Hello :smileyhappy:,
I'm looking to use TPM0 timer with FRDM-KL25Z in order to create simple delay method but there is something I don't understand.
TPM0 work well after initialization but its period isn't like what I expected. If I test a n second delay, the delay loop will be 2n seconds. Double of time !
Here is a quick configuration for 1ms delay :
If I read KL25Z reference manual. The period of TMP0 in up counting mode is = (MOD+1)* Period of timer module counter clock = 1001*(1/1MHz) = 1ms. (Am I right ?)
What going on with TPM0 ?!
note :
My code :
#include "MKL25Z4.h"
#include "GPIO.h"
#define PTB_18 0x40000
#define PTB_19 0x80000
#define PTD_01 0x02
int main (void)
{
static int i;
SystemInit();
MCG->C2 |= MCG_C2_IRCS_MASK;//Fast internal reference clock (4MHz)
SystemCoreClockUpdate();
SIM->SCGC5 = SIM_SCGC5_PORTB_MASK|SIM_SCGC5_PORTD_MASK;//Clock gate PORTB et D activé
PORTB->PCR[18] = PORT_PCR_MUX(0x01);//MUX Pin 18 PTB config en GPIO (Alt 1)
PORTB->PCR[19] = PORT_PCR_MUX(0x01);//MUX Pin 19 PTB config en GPIO (Alt 1)
PORTD->PCR[1] = PORT_PCR_MUX(0x01);//MUX Pin 1 PTD config en GPIO (Alt 1)
GPIO_config(_PTB,(PTB_18|PTB_19),OUT);//Config direction Port B pin 18,19 output
GPIO_config(_PTD,PTD_01,OUT);//Config direction Port D pin 1 output
GPIO_pin(_PTB,(PTB_18|PTB_19),_PDOR);//Init port B (LED R,V OFF)
GPIO_pin(_PTD,PTD_01,_PDOR);//init port D (LED B OFF)
//OSC INT = 4MHz
//TPM0 init
SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK;//TPM0 clock activé
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(0x03);//TPM clock source -> MCGIRCLK = 4MHz
TPM0->SC = TPM_SC_CMOD(0x00);//LPTPM desactivé
TPM0->SC |= TPM_SC_PS(0x01);//Prescaler /4 => 4MHz/4 = 1MHz => T = 1µs
//TPM0->SC &= !TPM_SC_CPWMS_MASK;//Compte de zéro à MOD reg
TPM0->MOD = TPM_MOD_MOD(10);//1000*1µs = 1ms
TPM0->SC |= TPM_SC_TOF_MASK;//Reset TOF bit
TPM0->SC |= TPM_SC_CMOD(0x01);//LPTPM activé compteur interne
while(1)
{
GPIO_pin(_PTD,1,_PCOR);//Set blue LED
while((TPM0->SC & TPM_SC_TOF_MASK)!=TPM_SC_TOF_MASK);//Poll TOF bit
TPM0->SC |= TPM_SC_TOF_MASK;//clear TOF
GPIO_pin(_PTD,1,_PSOR);//clear bleu LED
while((TPM0->SC & TPM_SC_TOF_MASK)!=TPM_SC_TOF_MASK);//Poll TOF bit
TPM0->SC |= TPM_SC_TOF_MASK;//clear TOF
}
}
Solved! Go to Solution.
Hi Max,
Thanks for the information! Actually there is no divider by 2 on MCGIRCLK, but there is a divider named as FCRDIV following the 4MHz IRC and right before it becomes MCGIRCLK, and the default value for FCRDIV is 1 meaning that Divide Factor is 2. so I am suspecting if you didn't change the value in MCG_SC[FCRDIV] in your application code so that MCGIRCLK is 2MHz for your case, and therefore you would meet such issue. Would you please help to confirm that? Please kindly refer to the following for details.
Hope that helps,
B.R
Kan
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Maxtime,
How did you measure the period? did you get it from the blue LED? Per your code, this LED was toggled in the TOF event of TPM, so the period of waveform on blue LED would be double time of TPM period, for example, this LED was turned on for 1ms, and then turned off for the next 1ms, and so on. so that you will observe a 2ms period waveform on the blue LED.
Hope that makes sense,
Have a great day,
B.R
Kan
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello Kan,
I mesure the period with the help of an oscilloscope. Blue LED is set during 2ms and clear 2ms too. So there is a 4ms of period.
Like Mark said above, a divider by 2 on MCGIRCLK could be the reason of this unexpected double times period.
Thanks for your response
Have a great day too :smileyhappy:
Max
Hi Max,
Thanks for the information! Actually there is no divider by 2 on MCGIRCLK, but there is a divider named as FCRDIV following the 4MHz IRC and right before it becomes MCGIRCLK, and the default value for FCRDIV is 1 meaning that Divide Factor is 2. so I am suspecting if you didn't change the value in MCG_SC[FCRDIV] in your application code so that MCGIRCLK is 2MHz for your case, and therefore you would meet such issue. Would you please help to confirm that? Please kindly refer to the following for details.
Hope that helps,
B.R
Kan
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Write ! I didn't notice it .
Thank you Kan. It's work very well now :smileyhappy: , I can go further now with UART, I2C and then I2S (on FRDM-KL26Z and Sparkfun Codec Shield). Can't wait to start it ! :smileygrin:
Hi All
I made a mistake by writing that divide by 2 was generally in the MCGIRCLK path because it is not in the slow IRC path but only in the fast IRC, whereby the default value of the FCRDIV explains the fact.
If the FCRDIV value is written to 0 the TPM clock is then 4MHz rather than 2MHz and the calculations are all as expected.
Regards
Mark
Maxime
I believe that selecting MCGIRCLK as TPM clock actually connects to MCGIRCLK/2. This is not just for the KL25 but for all KL devices.
If you select the slow internal clock (32kHz) as reference instead of the fast internal clock (4MHz) the effect is the same.
This means that you need to set half the value that you would set if the clock was (really) MCGIRCLK. (that is, perform the calculations for MCGIRCLK/2).
In the case of the OSCERCLK, MCGFLLCLK or MCGPPLCLK/2 sources the calculation is correct, which is what leads me to believe that there is an extra divide by 2 in the MCGIRCLK path that is not mentioned in the user manuals.
Regards
Mark
Yes, maybe there is a divider. If I set prescale by 2 instead of 4, my delay method is correct.
But why Freescale didn't show it in to the user manual ?