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
}
}
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
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
}
}