Part Number: MSPM0G1519
Tool/software:
Hello,
I have a customer who noticed that setting the timer to use the DL_TIMER_TIMER_MODE_PERIODIC_UP mode wasn't working, and we think it's because the CVAE field gets reset in the DL_Timer_initTimerMode() function.
void DL_Timer_initTimerMode(
GPTIMER_Regs *gptimer, const DL_Timer_TimerConfig *config)
{
DL_Timer_setLoadValue(gptimer, config->period);
switch (config->timerMode) {
/* All four cases below should set counter value to ZERO when enabled */
case DL_TIMER_TIMER_MODE_ONE_SHOT_UP:
case DL_TIMER_TIMER_MODE_PERIODIC_UP:
case DL_TIMER_TIMER_MODE_ONE_SHOT_UP_DOWN:
case DL_TIMER_TIMER_MODE_PERIODIC_UP_DOWN:
DL_Timer_setCounterValueAfterEnable(
gptimer, DL_TIMER_COUNT_AFTER_EN_ZERO);
break;
/* The two cases below should set counter value to LOAD when enabled */
case DL_TIMER_TIMER_MODE_ONE_SHOT:
case DL_TIMER_TIMER_MODE_PERIODIC:
DL_Timer_setCounterValueAfterEnable(
gptimer, DL_TIMER_COUNT_AFTER_EN_LOAD_VAL);
break;
default:
/* Code should not reach this case */
break;
}
DL_Timer_setCaptureCompareValue(
gptimer, config->counterVal, DL_TIMER_CC_0_INDEX);
DL_Timer_setCaptureCompareCtl(gptimer, (uint32_t) config->genIntermInt,
DL_TIMER_CC_ACOND_TIMCLK, DL_TIMER_CC_0_INDEX);
gptimer->COUNTERREGS.CTRCTL =
((uint32_t) config->timerMode | (uint32_t) config->startTimer);
}
If you take a look, the switch statement calls DL_Timer_setCounterValueAfterEnable() which modifies gptimer->COUNTERREGS.CTRCTL:
__STATIC_INLINE void DL_Timer_setCounterValueAfterEnable(
GPTIMER_Regs *gptimer, DL_TIMER_COUNT_AFTER_EN cvae)
{
DL_Common_updateReg(&gptimer->COUNTERREGS.CTRCTL, (uint32_t) cvae,
GPTIMER_CTRCTL_CVAE_MASK);
}
But then the last line of DL_Timer_initTimerMode uses an = assignment to update the CTRCTL value. This causes the CVAE value to get overwritten. This assignment should be done as an |= or a true masked write to the register to avoid clobbering the existing register values.
Munan