AnsweredAssumed Answered

Macro USEC_TO_COUNT not working correctly

Question asked by Jose Carlos Fuentes Angulo on Feb 5, 2019
Latest reply on Feb 7, 2019 by Jose Carlos Fuentes Angulo

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

/* Init pit module */
PIT_Init(PIT, &pitConfig);

uint32_t freq = CLOCK_GetFreq(kCLOCK_McgInternalRefClk);

/* Set timer period for channel 1 */
PIT_SetTimerPeriod(PIT, kPIT_Chnl_1, USEC_TO_COUNT(100000U, CLOCK_GetFreq(kCLOCK_BusClk)));

/* Enable timer interrupts for channel 1 */
PIT_EnableInterrupts(PIT, kPIT_Chnl_1, kPIT_TimerInterruptEnable);

/* Enable at the NVIC */
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);
  • Handler of TMP2
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.

Outcomes