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