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.

MSPM0G3519-Q1: Systick work abnormal and lost ISR SysTick_Handler

Part Number: MSPM0G3519-Q1
Other Parts Discussed in Thread: MSPM0G3519

Hello TI Support Team,

I am currently working with the MSPM0G3519 on an EVB board and facing an issue where the SysTick interrupt occasionally does not trigger as expected.

System Configuration

  • Device: MSPM0G3519
  • Clock Source: SYSOSC @ 32 MHz
  • SysTick Time Base: 500 µs
  • Monitoring Method: Toggling a GPIO pin PA9 inside the SysTick ISR to observe timing on an oscilloscope / logic analyzer

Issue Description

Occasionally, the SysTick ISR seems to be missed or delayed.
On the oscilloscope, the PA9 toggle shows that the expected stable 500µs period sometimes stretches, indicating the interrupt did not fire on time.

 Additional Evidence

To rule out issues in my own code, I also tested the blinky demo using FreeRTOS from TI’s SDK, which uses FreeRTOS tickless mode.
However, the same timing issue occurs — the SysTick/timer tick occasionally stretches beyond the expected interval.

This suggests the issue may be related to:

  • Clock configuration
  • Timer/SysTick behavior at 32 MHz SYSOSC
  • Interrupt controller timing
  • Flash wait states or prefetch behavior
  • Low-power entry/exit timing
  • Other hardware-level limitations or errata

Questions for TI

  1. Are there any known issues or errata related to SysTick or interrupt latency on the MSPM0G3519?
  2. Could there be configuration dependencies in the clock or interrupt controller that may cause lost SysTick interrupts?
  3. Is the SysTick affected by low‑power states, flash wait states, or long-running critical sections?
  4. Are there recommended test methods or settings to ensure stable SysTick timing at 32 MHz SYSOSC?

 

 Thank you in advance for your support!

  • Could you please help clarify the following:

    1. Why does IAR optimization impact the runtime behavior on MSPM0G3519?
    2. Are there any known optimization-related issues for MSPM0 or the TI driver libraries when using IAR?
    3. Do we need to apply any special compiler flags, volatile qualifiers, memory barriers, or pragmas when enabling optimization?
    4. Is there an official TI guideline or application note for IAR optimization on MSPM0 devices?
    5. Are there MSPM0-specific coding rules to prevent the optimizer from removing or reordering critical instructions (e.g., register access, ISR updates, flag polling, etc.)?

  • Hello Tuan,

    I have got your questions. Please give me some time to check and test your questions this week. Maybe there will be a little delay because tomorrow I will go for business travel. But I will reply to you as soon as possible.

    BR, 

    Janz Bai

  • Hello Janz Bai,

    After I am deep dive investigate the issue. And I found the root cause which does not related to ISR Systick, that is using the toggle pin during monitor ISR Systick.

    1. The 1st way, with optimization high in IAR and sometime lost signal

    /* Set PB26 */

      GPIOB->DOUTSET31_0 |= 0x04000000;

     /* Clear PB26 */

      GPIOB->DOUTCLR31_0 |= 0x04000000;
    2. The 2nd way, with optimizarion high and the toggle work well
    /* Toggle PA9 */
    GPIOA->DOUTTGL31_0 = (1u << 9);
    void SysTick_Handler(void)
    {
        /* Set PB26 output value to HIGH (bit 9 = 0x00000200) */
        GPIOB->DOUTSET31_0 |= 0x04000000;
        /* Clear PB26 output to LOW (bit 9 = 0x00000200) */
        GPIOB->DOUTCLR31_0 |= 0x04000000;

        /* toggle PA9 */
        GPIOA->DOUTTGL31_0 = 0x00000200;

        // Clear SysTick pending status in case it has already been triggered
        SCB->ICSR = SCB->ICSR | (1<<25); // Set PENDSTCLR bit to clear SysTick pending flag
    }

    My questions:

    1. What is the hardware-level difference between SET/CLEAR and TOGGLE?
    2. Are SET/CLEAR/TOGGLE atomic operations?
    3. Are there any read‑modify‑write issues when using these registers?
    4. Is there any timing or performance advantage when using DOUTTGL compared to SET+CLR sequence?
  •     GPIOB->DOUTSET31_0 |= 0x04000000;

    This is a very unusual usage; DOUTSET is normally used with a Write, not a Read-Modify-Write. (Similarly DOUTCLR/DOUTTGL). My observation is that this register always reads as 0, but the TRM doesn't say. In any case, the RMW would add extra instructions which could be affected by optimization.

    Try instead:

        GPIOB->DOUTSET31_0  = 0x04000000;

    ---------------
     SCB->ICSR = SCB->ICSR | (1<<25); // Set PENDSTCLR bit to clear SysTick pending flag
    Similarly, the ICSR would normally be used with a Write, not RMW. Try instead:
     
     SCB->ICSR = (1<<25); // Set PENDSTCLR bit to clear SysTick pending flag
    The fact that you even have this line of code suggests that your SysTick interval is very short, and thus susceptible to races -- in particular, one where you may or may not clear a pending SysTick interrupt that you actually want. You may not want this line of code at all.
     
  • Hi Tuan,
    1. The hardware difference is the functionality of the registers. Set -> Sets a GPIO high | Clear --> Sets a GPIO low | Toggle --> Inverts the current GPIO output

    2. Yes, they are atomic operations

    3. There are no specific problems with accessing the GPIO registers.

    4. Let's assume you have two LED's and you want to turn one off and the other one on. With TOGGLE you can do that without overlap. With SET/CLR you either have both LED for a couple of clock cycles, or both off for a couple of clock cycles.

    Best Regards,

    Diego Abad

  • Try instead:

        GPIOB->DOUTSET31_0  = 0x04000000;

    --> In case , If the both pinB has been set at the same time. I think it is impact to functionality orher pin

    Example: 

    GPIOB->DOUTSET31_0  = 0x04000000; --> set to pin PB26

    and the same time pin PB25 has been alreadly set to high.

    and then with statement GPIOB->DOUTSET31_0  = 0x04000000;  has been change PB25 to low level.

  • thanks for your information

  • I think mismatch for 3rd point, which reply by Diego Abad Sajamin.

  • That's not how DOUTSET (nor DOUTCLR) works. Since bit 25 is 0, it will not change PB25.TRM (SLAU846C) Table 9-42 describes DOUTSET31_0:bit 25: "Writing 1 to this bit sets the DIO25 bit in the DOUT31_0 register. Writing 0 has no effect."

    DOUTSET/DOUTCLR allow you to set/clear bits in DOUT atomically, with no read-modify-write hazard. (There's no mechanism for simultaneously setting and clearing an arbitrary set of bits [as seen in e.g. the Tiva series].)

  • I should also point out that your two scope traces are displaying very different waveforms. 

    The first is a periodic pulse. The pulse is very narrow -- possibly too short for your scope to reliably capture.

    The second is a square wave, with wide pulses which are easily captured.

    A more appropriate comparison would be to set DOUTTGL31_0 twice in a row, to create a narrow pulse. Alternatively, try turning up the resolution on your scope.

  • Thanks for your information.