How do I pass GPIOx_PTOR and TPMx_SC registers as arguments to a function

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How do I pass GPIOx_PTOR and TPMx_SC registers as arguments to a function

936 Views
Mamaro
Contributor II

kl25z‌  function parameter #registers

Hi, I want to have one timer() function that I can call and to control each led with instead of having these three almost identical ones. I figure that I have to pass PTOR and SC to the function but I don't know how to declare registers as arguments... 

while(1){
 timerRed (rItrPtr, rDtyCycMrkrPtr, rFlgPtr, 3.0, 0.8);
 timerGreen(gItrPtr, gDtyCycMrkrPtr, gFlgPtr, 0.5, 0.2);
 timerBlue (bItrPtr, bDtyCycMrkrPtr, bFlgPtr, 4.0, 0.3);
 }
}

void timerRed(volatile uint32_t port, int* iterator, int* dtyCycMrkr, int* flag, float seconds, float dutyCycle){
 if(*flag){
 *iterator *= seconds; *flag = 0; //Timer overflows 650 times a second(Hz)
 *dtyCycMrkr = dutyCycle * *iterator;
 }
 if(TPM0->SC & 0x80){ //Timer must overflow 6 times before changing LED state
 if(*iterator == 0 || *iterator == *dtyCycMrkr){ //Time overflows for the 6th time
 PTB->PTOR |= 0x40000; //LED state changes
 if(*iterator == 0)*iterator = seconds * 650; //Overflow tracker set to 6
 }
 TPM0->SC |= 0x80; //TOF cleared
 *iterator -= 1; //Tracks how number of overflows and decrements by 1
 }
}

void timerGreen(volatile int* iterator, int* dtyCycMrkr, int* flag, float seconds, float dutyCycle){
 if(*flag){
 *iterator *= seconds; *flag = 0; //Timer overflows 650 times a second(Hz)
 *dtyCycMrkr = dutyCycle * *iterator;
 }
 if(TPM1->SC & 0x80){ //Timer must overflow 6 times before changing LED state
 if(*iterator == 0 || *iterator == *dtyCycMrkr){ //Time overflows for the 6th
 PTB->PTOR |= 0x80000; //LED state changes
 if(*iterator == 0)*iterator = seconds * 650; //Overflow tracker set to 6
 }
 TPM1->SC |= 0x80; //TOF cleared
 *iterator -= 1; //Tracks how number of overflows and decrements by1
 }
}

void timerBlue(volatile int* iterator, int* dtyCycMrkr, int* flag, float seconds, float dutyCycle){
 if(*flag){
 *iterator *= seconds; *flag = 0; //Timer overflows 650 times a second(Hz)
 *dtyCycMrkr = dutyCycle * *iterator;
 }
 if(TPM2->SC & 0x80){ //Timer must overflow 6 times before changing LED state
 if(*iterator == 0 || *iterator == *dtyCycMrkr){ //Time overflows for the 6th
 PTD->PTOR |= 0x2; //LED state changes
 if(*iterator == 0)*iterator = seconds * 650; //Overflow tracker set to 6
 }
 TPM2->SC |= 0x80; //TOF cleared
 *iterator -= 1; //Tracks how number of overflows and decrements by1
 }
}

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

registerFunction001.png

registerFunction002.png

registerFunction.png

Labels (1)
0 Kudos
2 Replies

790 Views
mjbcswitzerland
Specialist V

Hi

In your case I would pass pointers to the TPM and port instances, plus the port B bit value.

void timerGeneral(TPM *ptrTPM, PT *ptrPT, unsigned long ulLED, volatile int* iterator, int* dtyCycMrkr, int* flag, float seconds, float dutyCycle){
 if(*flag){
 *iterator *= seconds; *flag = 0; //Timer overflows 650 times a second(Hz)
 *dtyCycMrkr = dutyCycle * *iterator;
 }
 if(ptrTPM->SC & 0x80){ //Timer must overflow 6 times before changing LED state
 if(*iterator == 0 || *iterator == *dtyCycMrkr){ //Time overflows for the 6th
 ptrPT->PTOR |= ulLED; //LED state changes
 if(*iterator == 0)*iterator = seconds * 650; //Overflow tracker set to 6
 }
 ptrTPM->SC |= 0x80; //TOF cleared
 *iterator -= 1; //Tracks how number of overflows and decrements by1
 }
}

which gives your main loop of:

#define RED_LED   0x40000
#define BLUE_LED  0x02
define GREEN_LED  0x80000
while(1){
 timerRed (TPM0, PTB, RED_LED, rItrPtr, rDtyCycMrkrPtr, rFlgPtr, 3.0, 0.8);
 timerGreen(TPM1, PTB, GREEN_LED, gItrPtr, gDtyCycMrkrPtr, gFlgPtr, 0.5, 0.2);
 timerBlue (TPM2, PTD, BLUE_LED, bItrPtr, bDtyCycMrkrPtr, bFlgPtr, 4.0, 0.3);
 }


You just need to find out what the name of TPM and PD structs actually are in your environment.

Regards

Mark


Complete Kinetis solutions for professional needs, training and support: http://www.utasker.com/kinetis.html

uTasker: supporting >1'000 registered Kinetis users get products faster and cheaper to market

Request Free emergency remote desk-top consulting at http://www.utasker.com/services.html

Open Source version at https://github.com/uTasker/uTasker-Kinetis

https://community.nxp.com/thread/512558

790 Views
Mamaro
Contributor II

Thanks, Mark! I right clicked "PTB" in Keil and clicked  "Go To Definition Of PTB" and it took me to the macro where "PTB" was defined as GPIOB. I went to GPIOB's definition and it took me to this:

//from MKL25Z.h 
/** Peripheral GPIOB base address */
#define GPIOB_BASE (0x400FF040u)
/** Peripheral GPIOB base pointer */
#define GPIOB ((GPIO_Type *)GPIOB_BASE)
#define GPIOB_BASE_PTR (GPIOB)

 

So the Port's struct was typedefed to GPIO_Type *  so, I used that as that as my parameter type.

I followed the same steps for TPM.

This is how my timer function looks like now:

prototype:

void timerGeneral(led*, GPIO_Type *, uint32_t, TPM_Type *, uint32_t, float, float);

definition:

void timerGeneral(led* myLed, GPIO_Type *port, uint32_t toggleMask, TPM_Type *timer, uint32_t statCtrlMask, float seconds, float dutyCycle){
 //LED timer setup
 if(myLed->flag){               //Only runs on first function call
   myLed->counter *= seconds; //Caluculates frequency LED is toggled base on given seconds
   myLed->dutyCycleMarker = dutyCycle * myLed->counter; //Marks the second point that the LED gets toggled
   myLed->flag = 0; 
 }
  if(timer->SC & statCtrlMask){     //Runs everytime timer overflow flag is thrown 
    if(myLed->counter == myLed->dutyCycleMarker || myLed->counter == 0){ //Toggles led on duty cycle marker or if counter equals 0 
          port->PTOR |= toggleMask; //LED state changes
          if(myLed->counter  == 0) myLed->counter = 650; //Overflow set to 650 
    }
  myLed->counter -= 1;                 //Tracks how many times timer overflows and decrements by 1
  timer->SC |= statCtrlMask; //Clears Timer Overflow flag 
 }  
}
0 Kudos