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.

MSPM0C1104: Timer code does not work when using TIMG8 but works on TIMG14 and TIMA0.

Part Number: MSPM0C1104
Other Parts Discussed in Thread: MSPM0L1306, MSPM0G3507, , SYSCONFIG,

Tool/software:

Hi, I have an issue where code for a timer queue implementation only functions on TIMG14 and TIMA0. For MSPM0C1104, TIMG8 does not work. I have also noticed that my code only functions using TIMA0 on the MSPM0G3507 and MSPM0L1306 launchpad boards.

I have reproduced a minimal example using the C SDK (the actual code is written in Rust) and it appears that TIMG8 never starts counting when replicating what the Rust code I've written does line by line. Changing the defines in the "empty_non_sysconfig.c" file to use TIMG14 or TIMA0 will cause the code to work. The code should result in the LED on the launchpad board being toggled once a second.

Although not shown here in full detail, I will explain what I am trying to do. The timer queue uses one of the timers and puts it into a free-running mode that counts up forever. The timer queue works uses the CCU0 and LOAD interrupts to increment a value indicating how many 32768 timer "ticks" have passed. The number of periods and the current counter value are used to compute a global "tick" counter corresponding to the amount of time passed since boot. CC1 is loaded with a value corresponding to how many ticks within the current period there are until the timer alarm happens. The CCU1 interrupt is enabled when the alarm will happen within the next period. The CCU1 interrupt then occurs when the alarm has happened.

I do recall the TIMER_ERR_01 errata present in the MSPM0G3507 hardware. However given that this code works on 2 out of 3 timers (and one of the timers for G3507), I am unsure if the issue is related.

I have attached a project reproducing this issue for the LP-MSPM0C1104 board. This only contains the code relating to CCU0 and LOAD since the TIMG8 never starts.

empty_non_sysconfig_LP_MSPM0C1104_nortos_gcc.tar

  • Sorry we are really busy today, please let me test it tomorrow.

  • Short answer: Add this line:

    >  DL_Timer_setCounterControl(TIMER,DL_TIMER_CZC_CCCTL0_ZCOND,DL_TIMER_CAC_CCCTL0_ACOND,DL_TIMER_CLC_CCCTL0_LCOND);

    Longer answer: CTRCTL:CAC needs to be set to =0 (CCCTL0_ACOND) in order to count (presumably CCCTL_01[0].ACOND=0 to get TIMCLK). But CAC resets to =7 (Reserved), so it needs to be set to something.

    The RMW of CTRCTL in DL_Timer_setCounterMode rewrites as CAC=7 for TIMG8, but rewrites as CAC=3 for TIMG14 [this is odd in itself]. CAC=3 refers to CCCTL3_ACOND, and by coincidence TIMG14 (and TIMA0) have 4x CC registers, and CCCTL_23[1].ACOND=0, so this works by accident. [I suspect that CAC bit 2 doesn't exist if the timer is incapable of QEI.]

    It is rather odd that a RMW of CTRCTL:<something else> would alter CAC at all, and do it differently depending on what features it has. [I still think it's odd that CAC resets to a Reserved value (=7) in the first place.]

    But in the end you need to set CAC to something, so you need that call.

  • Hi Bruce,

    Setting CAC, CZC and CLC to zero does indeed fix the issue. Thank you for helping me figure this out.

  • In my (non-DL) timer module this looks like:

    > TIMT->COUNTERREGS.CTRCTL = GPTIMER_CTRCTL_CAC_CCCTL0_ACOND|GPTIMER_CTRCTL_CVAE_ZEROVAL|
    GPTIMER_CTRCTL_REPEAT_REPEAT_1|GPTIMER_CTRCTL_CM_UP;

    followed by:

    > TIMT->COUNTERREGS.CCCTL_01[0] = GPTIMER_CCCTL_01_ACOND_TIMCLK|GPTIMER_CCCTL_01_COC_COMPARE;

    I think I concluded that I didn't need to care about CZC and CLC. DL requires that you set all 3.