Hi everyone,
I'm having problems with TPM timers and USEC_TO_COUNT macro.
Context:
I'm using a KL17 as MCU an I'm working in an application in which I need a systick every 100ms and different timers to control specific processes. One of them is to control the opening of an electrovalve when an ultrasonic sensor detect an object, if a delay time is configured, the electrovalve should open at object detection and delay time have finished. So, now I'm using 1 TPM as PWM and 1 TPM as Timer and also I'm using PIT as follow:
- TPM0 is use to control a buzzer. Configuration is shown below
tpm_config_t tpmConfig;
tpm_chnl_pwm_signal_param_t pwmChannelParam;
TPM_GetDefaultConfig(&tpmConfig);
TPM_Init(TPM0, &tpmConfig);
pwmChannelParam.chnlNumber = kTPM_Chnl_2;
pwmChannelParam.level = kTPM_HighTrue;
pwmChannelParam.dutyCyclePercent = 0;
TPM_SetupPwm(TPM0, &pwmChannelParam, 1U, kTPM_EdgeAlignedPwm, 2000U,
CLOCK_GetFreq(kCLOCK_McgIrc48MClk)/4);
TPM_StartTimer(TPM0, kTPM_SystemClock);
- PIT is configured as systick, every 100ms. Configuration is shown below
pit_config_t pitConfig;
PIT_GetDefaultConfig(&pitConfig);
PIT_Init(PIT, &pitConfig);
uint32_t freq = CLOCK_GetFreq(kCLOCK_McgInternalRefClk);
PIT_SetTimerPeriod(PIT, kPIT_Chnl_1, USEC_TO_COUNT(100000U, CLOCK_GetFreq(kCLOCK_BusClk)));
PIT_EnableInterrupts(PIT, kPIT_Chnl_1, kPIT_TimerInterruptEnable);
EnableIRQ(PIT_IRQn);
- TPM2 is configure as Timer, it should interrupt every 100ms.
tpm_config_t timerConfig;
TPM_GetDefaultConfig(&timerConfig);
TPM_Init(TPM2, &timerConfig);
uint32_t freq = CLOCK_GetFreq(kCLOCK_McgInternalRefClk);
TPM_SetTimerPeriod(TPM2, USEC_TO_COUNT(100000U, freq));
TPM_EnableInterrupts(TPM2, kTPM_TimeOverflowInterruptEnable);
EnableIRQ(TPM2_IRQn);
void TPM2_IRQHandler(void){
if (remMiliseconds == 0){
if (leftSonarLastState == CLOSE)
openElectrovalve(LEFT_ELECTROVALVE);
if (rightSonarLastState == CLOSE){
openElectrovalve(RIGHT_ELECTROVALVE);
}
remMiliseconds = (global_var.input_delay * 1000);
TPM_StopTimer(TPM2);
}else{
remMiliseconds -= 100;
}
TPM_ClearStatusFlags(TPM2, kTPM_TimeOverflowFlag);
}
- remMiliseconds is a uint16_t and seted in runtime with buttons that increment and decrement the value of the variable
- input_delay is a float that hold the value of an specific delay. So, if I set a 1.2s input_delay, remMiliseconds is equal to 1200 miliseconds.
- Clocks are config as follow:

Expected behaviour:
When use the buttons to increment or decrement the value of the delay, I'm setting the value of remMiliseconds. So, if I configured the TPM2 Timer to interrupt every 100ms and the value of remMiliseconds is 2000, the electrovalve should opens 2 seconds after the Timer had started.
Spected behaviour:
I set the value of input_delay to 2s, so the value of remMiliseconds is 2000 so the electrovalve should opens 2 seconds after the Timer had started but it opens at the time I start the timer. The timer start when I detect and object. So is like the timer is not interrupting as expected or maybe I didn't configured it correctly. I think also that the macro USEC_TO_COUNT is may not working fine.
Could someone here explain me, if the timer is configured correctly or what is wrong with my program logic?
Thank you and kind regards.