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.

TMS320F280025: Timer2 ISR delayed.

Part Number: TMS320F280025


Tool/software:

Hello,

I’m working on a project with the TMS320F280025 microcontroller, C2000 v5.0.00.00, and the Safety Diagnostic Library v4.01.00.
The system is based on two interrupts:

  • Timer2 (with 500ms period): Inside the ISR, the CPUTIMER_TCR_TIF is cleared as required in the thread:
    TMS320F280025: Spurious interrupts after HWBIST test 
  • ADC (with 55µs period): On every occurrence of the ISR, an STL_HWBIST_runMicro is executed until the HWBIST test is completed. After that, the FLASH ECC test is executed for a certain number of cycles in order to run correctable and uncorrectable tests… Then the cycle restarts from the HWBIST test.
  • There are no other interrupts interfering with normal operation, and the system schedules correctly.


I have noticed that sometimes the execution of timer2_ISR is delayed by a time equal to the number of ADC_ISR cycles during which the flash tests are executed. After that, it seems that the execution of STL_HWBIST_runMicro restores normal operation.
The problem does not seem to occur in two different cases, namely when:

  • CPUTIMER_TCR_TIF is not cleared by timer2_ISR (and therefore without the HWBIST test, since that would imply spurious timer2 interrupts).
  • The instructions related to IER, PIEIER12, and EINT/DINT are not executed inside the else statement of the ADC_ISR.

Thank you in advance for your support.

Here the code:

__interrupt void timer2_ISR(void)
{
    // Some code...

    // Clear the overflow flag — this is mandatory to avoid spurious interrupts
    // after HWBIST micro-run execution.
    CPUTimer_clearOverflowFlag(CPUTIMER2_BASE);
}

interrupt void ADC_ISR(void)
{
    // Some code...

    // Acknowledge interrupt group 1 to allow further interrupts from this group
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);

    if (condition == 1)
    {
        // Some code...

        // Execute HWBIST micro-run
        STL_HWBIST_runMicro();

        // Some code...
    }
    else
    {
        uint16_t pieier_prev = HWREGH(PIECTRL_BASE + PIE_O_IER12);

        // IER: disable all interrupt except for the group 12 and ERAD.
        IER &= INTERRUPT_CPU_INT12 | INTERRUPT_CPU_RTOSINT;

        // PIEIER12: disable all interrupt of group 12
        // except the flash correctable error interrupt.
        HWREGH(PIECTRL_BASE + PIE_O_IER12) &= PIE_IER12_INTX11;

        // Enable interrupts.
        EINT;

        // Perform a flash selftest.
        flash_selftest();

        // Disable interrupts.
        DINT;

        // Restore interrupts registers.
        HWREGH(PIECTRL_BASE + PIE_O_IER12) = pieier_prev;
    }
}

  • Hi Andrea,

    Thank you for your question, I will look into it and get back to you.

    Best Regards,

    Delaney

  • Hi Delaney, any updates?

  • Hi Andrea,

    Apologies, I am running behind on answering E2E threads. Please allow me until the end of this week to look into this.

    Best Regards,

    Delaney

  • Hi Delaney,

    any news?

    Best Regards,
    Andrea

  • Hi Andrea,

    My apologies, I still haven't been able to review your code. These types of questions usually take me longer to get to. If you have any specific conceptual questions about interrupts or the CPU timer module, I could probably answer those faster if you wanted to take that approach.

    Best Regards,

    Delaney

  • Hi Andrea,

    Sorry for the delay. I have looked through your setup and wanted to confirm, is your intended behavior for the CPU timer 2 ISR to nest inside of the ADC interrupt (if it is flagged during this time)? Please outline your intended behavior vs. what you are seeing. 

    As a note, you never want to write the PIEIER of a different group inside an ISR. This can cause unexpected behavior. For this reason, you do not want to write to PIEIER12 inside of your ADC ISR (from group 1). See warning below:

    Based on your current code, it would be expected that the CPU timer 2 interrupt doesn't nest inside the ADC ISR since TIMER2 is in group 14 and nesting has not been enabled for this group. Let me know what kind of nesting you are trying to do, and which interrupts are enabled, and I can provide some recommendations. 

    Best Regards,

    Delaney

  • Hi Delaney,

    This is the expected behavior:
    - During ADC ISR execution, if it's time to run the flash ECC test, only PIE_IER12_INTX11 and INTERRUPT_CPU_RTOSINT shoud be nested.
    - If Timer2 is flagged during the ADC ISR (or a nested ISR from the previous point), the execution of the Timer2 ISR must be postponed until the ADC ISR (and any nested ISR) has completed.

    Sometimes, I see that Timer2 ISR is flagged, but not executed for any of the subsequent ADC event in which flash ECC test is performed, until a HWBIST micro-run execution unlocks the Timer2 ISR.

    Best Regards,

    Andrea

  • Hi Andrea,

    I see, so you don’t expect the timer 2 ISR to nest but just to occur after the ADC ISR and any nested ISRs have completed. I will look into your code more and get back to you.

    Best Regards,

    Delaney

  • Hi Andrea,

    To make sure I am understanding correctly, is this an example of the desired behavior:

    1. ADC ISR x - HWBIST code (condition == 1)
    2. ADC ISR x+1 - Flash ECC code (condition != 1)
      1. Nested INTERRUPT_CPU_RTOSINT 
      2. TIMER2 is flagged during this time
    3. TIMER2 ISR
    4. ADC ISR x+2 - Flash ECC code (condition != 1)
    5. ADC ISR x+3 - Flash ECC code (condition != 1)

    Vs. what you are seeing:

    1. ADC ISR x - HWBIST code (condition == 1)
    2. ADC ISR x+1 - Flash ECC code (condition != 1)
      1. Nested INTERRUPT_CPU_RTOSINT 
      2. TIMER2 is flagged during this time
    3. ADC ISR x+2 - Flash ECC code (condition != 1)
    4. ADC ISR x+3 - Flash ECC code (condition != 1)
    5. TIMER2 ISR 

    If this is correct, then my question would be: how long (how many cycles) is the ADC ISR in the maximum case - where both other interrupts nest inside? Does this exceed 55us (=5500 cycles for a 100MHz SYSCLK)? If another ADC ISR interrupt comes in before the end of the original ADC ISR, the second ADC ISR will take precedence since it is in group 1 of the PIE and TIMER2 is group 14 and will be serviced by the CPU first. The PIE does not keep track of the order in which interrupts come in, whenever an interrupt is propagated to the CPU, the PIE will check which interrupt is of the highest priority that is both enabled and flagged and tell the CPU to branch to that ISR.

    Best Regards,

    Delaney

  • Hi Delaney,

    The desired behavior is correct, what I am seeing:

    1. ADC ISR x - HWBIST code (condition == 1)
    2. ADC ISR x+1 - Flash ECC code (condition != 1)
      1. Nested INTERRUPT_CPU_RTOSINT 
      2. TIMER2 is flagged during this time
    3. A TIMER2 ISR should occur here, but it does not.
    4. ADC ISR x+2 - Flash ECC code (condition != 1)
    5. ADC ISR x+3 - Flash ECC code (condition != 1)
    6. ... around 500 ADC ISR are executed...
    7. ADC ISR x+n - HWBIST code (condition == 1) this must be executed in order to "unlock" TIMER2 ISR
    8. TIMER2 ISR  (this should not happen here)


    In the worst-case scenario ADC ISR plus all nested interrupts does not exceed 43us, we have already verified that there are no timing issues and no unespected interrupts.

  • Hi Andrea,

    I see, thank you for clarifying. 

    As a note, you never want to write the PIEIER of a different group inside an ISR. This can cause unexpected behavior. For this reason, you do not want to write to PIEIER12 inside of your ADC ISR (from group 1)

    Have you tried removing the below lines of code and seeing if the problem persists? 

            // PIEIER12: disable all interrupt of group 12
            // except the flash correctable error interrupt.
            HWREGH(PIECTRL_BASE + PIE_O_IER12) &= PIE_IER12_INTX11;

    ...

            // Restore interrupts registers.
            HWREGH(PIECTRL_BASE + PIE_O_IER12) = pieier_prev;

    Best Regards,

    Delaney

  • Hi Delaney,

    Yes, I have tried removing those lines, but the problem still persists.

    Best Regards,

    Andrea

  • Hi Andrea,

    Can you try adding a check at the end of ADC ISR x+1 - Flash ECC code (condition != 1) that reads the CPU timer register to verify that the flag is actually set at that point as well as checks the status of the IER bit for group 14 to make sure it is enabled? Is there any code in the flash_selftest() function that could be disabling this IER bit?

    Best Regards,

    Delaney