SPRADP8 February   2025 F29H850TU , TMS320F2800132 , TMS320F2800133 , TMS320F2800135 , TMS320F2800137 , TMS320F2800153-Q1 , TMS320F2800154-Q1 , TMS320F2800155-Q1 , TMS320F2800156-Q1 , TMS320F2800157 , TMS320F2800157-Q1 , TMS320F280021 , TMS320F280021-Q1 , TMS320F280023 , TMS320F280023-Q1 , TMS320F280023C , TMS320F280025 , TMS320F280025-Q1 , TMS320F280025C , TMS320F280025C-Q1 , TMS320F280033 , TMS320F280034 , TMS320F280034-Q1 , TMS320F280036-Q1 , TMS320F280036C-Q1 , TMS320F280037 , TMS320F280037-Q1 , TMS320F280037C , TMS320F280037C-Q1 , TMS320F280038-Q1 , TMS320F280038C-Q1 , TMS320F280039 , TMS320F280039-Q1 , TMS320F280039C , TMS320F280039C-Q1 , TMS320F280040-Q1 , TMS320F280040C-Q1 , TMS320F280041 , TMS320F280041-Q1 , TMS320F280041C , TMS320F280041C-Q1 , TMS320F280045 , TMS320F280048-Q1 , TMS320F280048C-Q1 , TMS320F280049 , TMS320F280049-Q1 , TMS320F280049C , TMS320F280049C-Q1 , TMS320F28384D , TMS320F28384D-Q1 , TMS320F28384S , TMS320F28384S-Q1 , TMS320F28386D , TMS320F28386D-Q1 , TMS320F28386S , TMS320F28386S-Q1 , TMS320F28388D , TMS320F28388S , TMS320F28P550SG , TMS320F28P550SJ , TMS320F28P650DH , TMS320F28P650DK , TMS320F28P650SH , TMS320F28P650SK , TMS320F28P659DH-Q1 , TMS320F28P659DK-Q1 , TMS320F28P659SH-Q1

 

  1.   1
  2.   2
  3.   Trademarks

Introduction

Supporting real-time tasks on a CPU requires the use of interrupts. If an external sensor senses a fault, the CPU needs to be interrupted or halted to perform a subroutine that is able to handle the fault. In this example, timing of the interrupt of when the signal reaches the CPU matters. Interrupts are hardware or software-driven signals that cause the CPU to suspend the current program sequence and execute a subroutine. Interrupts often handle time critical loops and control algorithms that are critical to the application and need to execute in timely fashion. Most of the case interrupts can happen periodically with a known frequency. However, when designing the software architecture, have you ever seen an interrupt waveform oscillate incorrectly, as shown in Figure 1?

 Abnormal Interrupt Oscillation
                    (Ch4: Interrupt with GPIO toggle; Ch3: Interrupt trigger on ePWM ZRO event, Red
                    signal: Frequency trend measurement from oscilloscope) Figure 1 Abnormal Interrupt Oscillation (Ch4: Interrupt with GPIO toggle; Ch3: Interrupt trigger on ePWM ZRO event, Red signal: Frequency trend measurement from oscilloscope)

Interrupt Propagation Path and Interrupt Timing

First, there are two concepts to focus on with interrupt latency that are interrupt propagation path and interrupt timing. The interrupt propagation path is the time from an interrupt request triggering to the beginning of the interrupt service function. Second, confirm if there are any interference factors during an interrupt request triggering or with normal interrupt execution. Third, interrupt latency is maintained to be executed normally by setting interrupt priority reasonably (such as interrupt nesting and register stack restore/protect) and shielding others interrupt interference source.

Interrupt propagation path on C28x handles interrupts in four main phases:

  1. Receive the interrupt request. Suspension of the current program sequence must be requested by a software interrupt (from program code) or a hardware interrupt (from a pin or an on-chip device), as described in Figure 2.
  2. Approve the interrupt. The C28x must approve the interrupt request. If the interrupt is maskable, certain conditions must be met for the C28x to approve the interrupt request. For non-maskable hardware interrupts and for software interrupts, approval is immediate, as described in Figure 3.
  3. Prepare for the interrupt service routine and save register values, as described in Figure 4.
  4. Execute the interrupt service routine. This is interrupt loop processing entry, call ISR.

Most programmers only pay attention to first two phases, and know less about stack protection or recovery and interrupt response in the last two phases. This application brief dives deeper into phases three and four.

 Interrupt Triggering Source
                    (F28003x) Figure 2 Interrupt Triggering Source (F28003x)

Figure 3 shows how peripheral interrupts propagate to the CPU.

 Interrupt Propagation
                    Path Figure 3 Interrupt Propagation Path

Figure 4 shows how C28x generates and responds to interrupt service functions.

 Interrupt PIE Initialization
                    Code Flow Figure 4 Interrupt PIE Initialization Code Flow

The interrupt timing from interrupt request triggering to interrupt service function ISR:

  1. Minimum latency (to when real work occurs in the ISR), 14 or 16 cycles: take F280039C 120Mhz CPU for example, Minimum latency- add All Registers Save or Restored automatically On Real-Time interrupt prepared can be 40 cycles, it can be around 50 cycles/415ns latency.
  2. Maximum latency: Depends on C28x handles cycles for stack protection and restoration, wait states, INTM, and not interruptible RPT Instruction, as described in Figure 5.
 Interrupt Latency Flow Figure 5 Interrupt Latency Flow

In addition to correct usage of interrupt request and interrupt approval operation bits (Such as INTM, IER bit), consider the following interference factors and interrupt nesting that can affect interrupts.

Interrupt Nesting and Interference Factors

  • When C28x is executing an interrupt or responding to a high-priority interrupt, by default the interrupt cannot continue to respond to other low-priority interrupts. However, there are steps that can be followed to enable servicing of other interrupts within the current interrupt. This is called interrupt nesting.
  • When uninterruptible instructions such as RPT instructions are being executed for too long or too frequently, the C28x CPU cannot respond to the interrupts in a timely manner.

These two points are sources that can affect how the interrupt timing can be affected.

Interrupt Nesting

When talking about interrupt nesting, interrupts are automatically prioritized by the C28x hardware. Prioritization for all interrupts can be found in the System Control guide specific to the particular device family. When the C28x CPU is responding to a low-priority interrupt, the CPU interferes with the normal response of a high-priority interrupt, as described in Figure 6.

 Interrupt PIE Channel
                    Mapping Figure 6 Interrupt PIE Channel Mapping

Therefore, application code needs to add simple software prioritization during low priority interrupts. This allows the CPU to respond to high-priority interrupt processing in a timely manner from the execution of low-priority interrupts. Here are the steps C28x performs interrupt nesting:

  1. Set the global priority:
    1. Modify the IER register to allow CPU interrupts with a higher user priority to be serviced. (Note: at this time IER has already been saved on the stack.)
  2. Set the group priority:
    1. Modify the appropriate PIEIERx register to allow group interrupts with a higher user set priority to be serviced. (Note: Do NOT clear PIEIER register bits from another group other than that being serviced by this ISR. Doing so can cause erroneous interrupts to occur.)
  3. Enable interrupts: There are three steps to do this:
    1. Clear the PIEACK bits.
    2. Wait at least one cycle.
    3. Clear the INTM bit. Use the assembly statement asm(” CLRC INTM”); or TI examples use #define EINT asm(” CLRC INTM”).
  4. Run the main part of the ISR.
  5. Set INTM to disable interrupts. Use asm(” SETC INTM”); or TI examples use #define DINT asm(” SETC INTM”).
  6. Restore PIEIERx (optional depending on step 2)
  7. Return from ISR:
    1. This restores INTM and IER automatically. Meanwhile, the example code as below:
      // // C28x ISR Code // // Enable nested interrupts // // ADCA1 interrupt for loop Interrput
      void INT_myCPUTIMER2_ISR(void)
      {
              uint16_t TempPIEIER;
              TempPIEIER = PieCtrlRegs.PIEIER1.all; // Save PIEIER register for later
              IER |= 0x001;                         // Set global priority by adjusting IER
              IER &= 0x001;
              PieCtrlRegs.PIEIER1.all &= 0x0001;    // Set group priority by adjusting PIEIER1 to //allow INT1.1 to interrupt current CPU time0 ISR
              PieCtrlRegs.PIEACK.all = 0xFFFF;      // Enable PIE interrupts
              asm("       NOP");                    // Wait one cycle
              EINT;                                 // Clear INTM to enable interrupts
              //
              // Insert ISR Code here.......
              // for now just insert a delay
              //
              //for(i = 1; i <= 10; i++) {}
              //
              // Restore registers saved:
              //
              DINT;
              PieCtrlRegs.PIEIER1.all = TempPIEIER;
      }
      

Our next-generation C29x architecture F29H85x supports Hardware Interrupt Prioritization requires no software overhead and allows interrupt nesting. For C29x architecture all registers are save/restored automatically by hardware on real-time interrupt in 10 cycles when compared C28x 40 cycles.

 C29x Interrupt Grouping
                    Overview Figure 7 C29x Interrupt Grouping Overview

Nesting for INTs within the PIPE module is enabled within an Interrupt Service Routine (ISR) by setting the CPU level DSTS.INTE bit active because this bit is disabled while entering the ISR., as described in Figure 7. Here are the steps C28x performs interrupt nesting:

// // C29x ISR Code // // Enable nested interrupts // // ADCA1 interrupt for loop Interrput
void INT_myCPUTIMER0_ISR(void)
{
       // Set INTE to 1 to enable interrupts here.
       ENINT; 
       // Insert ISR Code here.......                         

}

C28x Interrupt Nesting Test Results

The below test results are with two interrupts: EPWM interrupt at 150kHz (yellow signal) and Timer2 interrupt at 1kHz (blue signal). Timer2 interrupt has lower priority than the EPWM interrupt. Without C28x interrupt nesting enabled, the interrupt frequency of the EPWM is not be 150kHz, as shown in Figure 8. Keeping EPWM interrupt fixed at 150Khz is only possible by leveraging C28x CPU interrupt nesting, as shown in Figure 9. The test results are based on LAUNCHXL-F280039C. If interrupt nesting is not enabled by software method as described with the above code there is abnormal interrupt behavior.

With interrupt nesting enabled, the higher priority interrupts can still be entered and executed even when a lower priority interrupt has occurred. This makes sure higher priority interrupt frequencies are constant..

 C28x Interrupt Nesting
                    Disabled Test Results (CH1: EPWM interrupt, CH2: TIMER2 interrupt) Figure 8 C28x Interrupt Nesting Disabled Test Results (CH1: EPWM interrupt, CH2: TIMER2 interrupt)
 C28x Interrupt Nesting Enabled
                    Test Results (CH1: EPWM interrupt, CH2: TIMER2 interrupt) Figure 9 C28x Interrupt Nesting Enabled Test Results (CH1: EPWM interrupt, CH2: TIMER2 interrupt)

C29x Interrupt Nesting Test Results

The below test results are with two interrupts: EPWM interrupt at 150kHz (pink signal) and Timer2 interrupt at 1kHz (green signal). Timer2 interrupt has lower priority than the EPWM interrupt. Without C29x interrupt nesting enabled, the interrupt frequency of the EPWM is not be 150kHz, as shown in Figure 10. Keeping EPWM interrupt fixed at 150Khz is only possible by leveraging C29x CPU interrupt nesting, as shown in Figure 11. This is tested based on the F29x devices. If interrupt nesting is not enabled by software method as described the above code there is abnormal interrupt behavior.

With interrupt nesting enabled, the higher priority interrupts can still be entered and executed even when a lower priority interrupt has occurred. This makes sure higher priority interrupt frequencies are constant.

 C29x Interrupt Nesting
                    Disabled Test Results (CH1: EPWM interrupt, CH2: TIMER2 interrupt) Figure 10 C29x Interrupt Nesting Disabled Test Results (CH1: EPWM interrupt, CH2: TIMER2 interrupt)
 C29x Interrupt Nesting Enabled
                    Test Results (CH1: EPWM interrupt, CH2: TIMER2 interrupt) Figure 11 C29x Interrupt Nesting Enabled Test Results (CH1: EPWM interrupt, CH2: TIMER2 interrupt)

Uninterruptible Instructions Affects Interrupt Timing

When talking about uninterruptible instructions RPT, a large number of repeated global initialization variables are used in the main program or state machine such as Memcopy, for loop assigns the same array, or repeated operations are performed, the C2000 compiler automatically generates RPT instructions. The repeat (RPT) instruction allows the execution of a single instruction (N + 1) times, where N is specified as an operand of the RPT instruction. The instruction is executed once and then repeated N times. When RPT is executed, the repeat counter (RPTC) is loaded with N. RPTC is then decremented every time the repeated instruction is executed, until RPTC equals 0. For a description of RPT and a list of repeatable instructions, see the RPT *8bit/loc16 section in the C28x Assembly Language Instructions chapter of the TMS320C28x CPU and Instruction Set Reference Guide.

Due to this RPT instruction being uninterruptible, it does not have the context saving stack protection or restore function. So, the PC pointer stays in RPT at this time and it may not be able to respond to the interrupt request in time, as described in Figure 12.

 RPT Instructions
                    Introduction Figure 12 RPT Instructions Introduction

Therefore, you can go into the C2000 compilers using the correct settings or you can avoid generated C usage notes. Regarding the C2000 compilers, you can change the Project Properties -> C2000 Compiler -> Advanced Options -> Runtime Model Options -> Enable “Don’t generate RPT instructions, as described in Figure 13.

 C2000 Compiler Setting About
                    RPT Instructions Figure 13 C2000 Compiler Setting About RPT Instructions
 RPT Instructions Generated By
                    Above Functions Figure 14 RPT Instructions Generated By Above Functions
 Source Code Figure 15 Source Code

Finally, follow the above C2000 compilers settings and the EPWM ISR works normally, as described in Figure 16.

 Abnormal Interrupt Oscillation
                    Fixed (Ch4: Interrupt with GPIO toggle; Ch3: Interrupt trigger on ePWM ZRO
                    event, Red signal: Frequency trend measurement from oscilloscope) Figure 16 Abnormal Interrupt Oscillation Fixed (Ch4: Interrupt with GPIO toggle; Ch3: Interrupt trigger on ePWM ZRO event, Red signal: Frequency trend measurement from oscilloscope)

Summary

The interrupt is executed normally by observing the minimum interrupt delay. However, the factors that affect the normal execution of the interrupt are:

  • Whether the interrupt request is triggered normally
  • Whether the INTM or IER enable bit is enabled, and whether the IFG flag is set normally
  • Whether the interrupt propagation path is likely to be blocked
  • Whether the interrupt response is likely to be disturbed when saving the register, such as the non-interruptible instruction RPT
  • Whether the interrupt is nested, when the low-priority interrupt is responding, the high-priority interrupt is blocked, affecting the timeliness of the interrupt response

This technical article tells you how to locate and troubleshoot the factors affecting the interrupts.