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

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