TPM period (double time)

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

TPM period (double time)

Jump to solution
3,748 Views
mr_max
Contributor IV

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 :

  • I loaded 1000 to MOD register.
  • MCGIRCLK is routed to TPM modul and run @4MHz (fast IRC).
  • Prescale /4.  -> input module counter  = 1MHz

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 ?)


Capture d’écran 2014-07-22 à 18.43.46.png

What going on with TPM0 ?! 

note :

  • I'm using Keil v5 (no PE).
  • GPIO_pin(); is custom method

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

  }

}

Labels (1)
Tags (3)
0 Kudos
1 Solution
1,766 Views
Kan_Li
NXP TechSupport
NXP TechSupport

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.

1.png

1-1.png

2.png


Hope that helps,
B.R
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
7 Replies
1,766 Views
Kan_Li
NXP TechSupport
NXP TechSupport

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

0 Kudos
1,766 Views
mr_max
Contributor IV

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

0 Kudos
1,767 Views
Kan_Li
NXP TechSupport
NXP TechSupport

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.

1.png

1-1.png

2.png


Hope that helps,
B.R
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,766 Views
mr_max
Contributor IV

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:

0 Kudos
1,766 Views
mjbcswitzerland
Specialist V

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

0 Kudos
1,766 Views
mjbcswitzerland
Specialist V

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

1,766 Views
mr_max
Contributor IV

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 ?

0 Kudos