This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G1519: DL_Timer_initTimerMode clobbers CVAE field

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