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.

TMS320F280025C: Priority interrupt (ADC and others)

Part Number: TMS320F280025C
Other Parts Discussed in Thread: C2000WARE

Hi,

I have a problem I would like to change the interrupt priorities, so I have included the corresponding header file in my project. You will find the details here. The interrupts work well independently (I commented them and then reactivated them one by one in the main) but when I activate at least two of them it does not work anymore. For example when I activate the ADC interrupt and slow tasks I don't go to the ADC interrupt anymore.

I have looked at the examples but I can't find the solution.

Here a part of my main code

/**
 * Interrupt for state machine sequencing and synchronization for slow background tasks all of 10ms.
 */
timer_cpu_config(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 10000);
Interrupt_register(INT_TIMER0, &isr_slow_tasks);
CPUTimer_enableInterrupt(CPUTIMER0_BASE);
Interrupt_enable(INT_TIMER0);

/**
 * Set up the ADC / ePWM SOC and initialize the end of conversion.
 * Enable interrupt.
 */
Interrupt_register(INT_ADCA1, &isr_adca);
adc_config(ADCA_BASE);
adc_config(ADCC_BASE);
adc_init_soc();
Interrupt_enable(INT_ADCA1);

/**
 * Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
 */
EINT;
ERTM;
__interrupt void isr_adca(void)
{
    GPIO_writePin(4, 1); // for test

    /// Save IER register on stack
    volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER1);

    /// See prioritized_isr_levels.h file for explanations and details. Set global priority with INTxPL values and others Gx_xPL
    /// Set the global and group priority to allow CPU interrupts with higher priority.
    /// The user must set the appropriate priority level for each of the CPU interrupts.
    /// This is termed as the "global" priority. The priority level must be a number between 1 (highest) to 16 (lowest).
    /// A value of 0 must be entered for reserved interrupts or interrupts that are not used.
    IER |= M_INT1;
    IER &= MINT1;
    HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG1_1;

    /// Enable Interrupts
    Interrupt_clearACKGroup(0xFFFFU);
    __asm("  NOP");
    EINT;

    /// To be sure all contactor's are open when offsets are read in order to obtain the correct value of the offset
    if((flag_read_offset_adca == 0) &&
       (flag_read_offset_adcc == 0) &&
       (engineer_return_contactor_k_line_fc == RETURN_CONTACTOR_OPEN) &&
       (engineer_return_contactor_k_pl_fc == RETURN_CONTACTOR_OPEN) &&
       (engineer_return_contactor_k_line_batt == RETURN_CONTACTOR_OPEN) &&
       (engineer_return_contactor_k_pl_batt == RETURN_CONTACTOR_OPEN))
    {
        read_offset_at_init_adca();
        flag_read_offset_adca = 1;
        read_offset_at_init_adcc();
        flag_read_offset_adcc = 1;
    }

    MU_TRAC_BATT_FLT_ACC_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER2) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER3);
    /// Divide by 4 to obtain average value.
    MU_TRAC_BATT_FLT_AVG_SAMPLE = (MU_TRAC_BATT_FLT_ACC_SAMPLE >> 2);

    MU_FUEL_CELL_FLT_ACC_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER0) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER1) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER2) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER3);
    /// Divide by 4 to obtain average value.
    MU_FUEL_CELL_FLT_AVG_SAMPLE = (MU_FUEL_CELL_FLT_ACC_SAMPLE >> 2);

    MI_L_U_FLT_ACC_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER4) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER5) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER6) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER7);
    /// Divide by 4 to obtain average value.
    MI_L_U_FLT_AVG_SAMPLE = (MI_L_U_FLT_ACC_SAMPLE >> 2);

    MI_L_V_FLT_ACC_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER4) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER5) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER6) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER7);
    /// Divide by 4 to obtain average value.
    MI_L_V_FLT_AVG_SAMPLE = (MI_L_V_FLT_ACC_SAMPLE >> 2);

    MI_L_W_FLT_ACC_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER8) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER9) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER10) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER11);
    /// Divide by 4 to obtain average value.
    MI_L_W_FLT_AVG_SAMPLE = (MI_L_W_FLT_ACC_SAMPLE >> 2);

    MI_TRAC_BATT_FLT_ACC_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER8) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER9) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER10) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER11);
    /// Divide by 4 to obtain average value.
    MI_TRAC_BATT_FLT_AVG_SAMPLE = (MI_TRAC_BATT_FLT_ACC_SAMPLE >> 2);

    MU_FUEL_CELL_PCH_FLT_ACC_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER12) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER13);
    /// Divide by 2 to obtain average value.
    MU_FUEL_CELL_PCH_FLT_AVG_SAMPLE = (MU_FUEL_CELL_PCH_FLT_ACC_SAMPLE >> 1);

    MU_TRAC_BATT_FLT_ACC_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER12) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER13);
    /// Divide by 2 to obtain average value.
    MU_TRAC_BATT_PCH_FLT_AVG_SAMPLE = (MU_TRAC_BATT_FLT_ACC_SAMPLE >> 1);

    REF_MI_H_2V5_ACC_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER14) + ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER15);
    /// Divide by 2 to obtain average value.
    REF_MI_H_2V5_AVG_SAMPLE = (REF_MI_H_2V5_ACC_SAMPLE >> 1);

    MT_COLD_PLATE_FLT_ACC_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER14) + ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER15);
    /// Divide by 2 to obtain average value.
    MT_COLD_PLATE_FLT_AVG_SAMPLE = (MT_COLD_PLATE_FLT_ACC_SAMPLE >> 1);

    /// Check if overflow has occurred
    if(ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1) == true)
    {
        ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1);
        ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
    }
    /// Clear the interrupt flag
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
    /// Acknowledge the interrupt, see PIE Interrupt Vectors table
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    /// Disable interrupts and restore registers saved:
    DINT;
    HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER;

    GPIO_writePin(4, 0); // for test
}
__interrupt void isr_slow_tasks()
{
    GPIO_writePin(39, 1); // for test

    /// Save IER register on stack
    volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER1);
    /// Set the global and group priority to allow CPU interrupts with higher priority
    IER |= M_INT1;
    IER &= MINT1;
    HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG1_7;

    /// Enable Interrupts
    Interrupt_clearACKGroup(0xFFFFU);
    __asm("  NOP");
    EINT;

    if(CPUTimer_getTimerOverflowStatus(CPUTIMER0_BASE) == true)
    {
        CPUTimer_clearOverflowFlag(CPUTIMER0_BASE);
    }

    /// Update data and send frames if CAN request is detected.
    can_request();
    /// Read engineer variables and if request by user's is detected.
    engineer_variable_and_request_forcing();
    /// CMPSS monitoring to detect if protection is set.
    cmpss_and_cold_plate_monitoring();
    /// Driver return monitoring to detect if protection is set.
    drv_monitoring();
    /// See requirement REQ_SYST0038
    //detection_coldplate(cold_plate_pin, &cold_plate_detect, &cold_plate_state_error, &cold_plate_state);
    /// See requirement REQ_SYST0039
    //detection_contactor(&k_line_batt, &k_line_batt_state_error, &trigger_state_kline_batt, &trigger_flag_kline_batt, &untrigger_flag_kline_batt);
    /// See requirement REQ_SYST0040
    //detection_contactor(&k_line_fuel_cell, &k_line_fc_state_error, &trigger_state_kline_fc, &trigger_flag_klinefc, &untrigger_flag_klinefc);
    /// See requirement REQ_SYST0041
    //detection_contactor(&k_pl_batt, &k_pl_batt_state_error, &trigger_state_kpl_batt, &trigger_flag_kpl_batt, &untrigger_flag_kpl_batt );
    /// See requirement REQ_SYST0042
    //detection_contactor(&k_pl_fuel_cell, &k_pl_fc_state_error, &trigger_state_kpl_fc, &trigger_flag_kpl_fc, &untrigger_flag_kpl_fc);
    /// Get authorization for open contactor's if converter's are off since delay.
    get_open_contactor_authorization(&open_contactor, &ack_inh_converter, &open_contactor_authorization);
    /// Get authorization for close contactor's if converter's are off since delay and no monitoring are activate.
    get_close_k_pl_contactor_authorization(&close_contactor, &step_global, &close_k_pl_authorization);
    /// Actions at the state machine due to detection at the contactor's.
    contactor_monitoring();
    /// State machine
    sm_main();
    /// Detect if a request to exit RUN state is detected (stop or no loop choice or vehicle crash is nok or consign < min).
    request_to_exit_run_state();

    /// Acknowledge the interrupt, see PIE Interrupt Vectors table
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    /// Disable interrupts and restore registers saved:
    DINT;
    HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER;

    GPIO_writePin(39, 0); // for test
}
#ifndef PRIORITIZED_ISR_LEVELS_H
#define PRIORITIZED_ISR_LEVELS_H

#ifdef __cplusplus
extern "C" {
#endif

//
// Include the header file with software interrupt prioritization logic
//
#include "sw_interrupt_prioritization_logic.h"

//
// Mask for interrupt groups
//
#define M_INT1      0x0001  // INT1 Mask
#define M_INT2      0x0002  // INT2 Mask
#define M_INT3      0x0004  // INT3 Mask
#define M_INT4      0x0008  // INT4 Mask
#define M_INT5      0x0010  // INT5 Mask
#define M_INT6      0x0020  // INT6 Mask
#define M_INT7      0x0040  // INT7 Mask
#define M_INT8      0x0080  // INT8 Mask
#define M_INT9      0x0100  // INT9 Mask
#define M_INT10     0x0200  // INT10 Mask
#define M_INT11     0x0400  // INT11 Mask
#define M_INT12     0x0800  // INT12 Mask
#define M_INT13     0x1000  // INT13 Mask
#define M_INT14     0x2000  // INT14 Mask
#define M_DLOG      0x4000  // DLOGINT Mask
#define M_RTOS      0x8000  // RTOSINT Mask

//
// Interrupt Enable Register Allocation:
// Interrupts can be enabled/disabled using the CPU interrupt enable register
// (IER) and the PIE interrupt enable registers (PIEIER1 to PIEIER12).
//

//
// Set "Global" Interrupt Priority Level (IER register):
//
// The user must set the appropriate priority level for each of the CPU
// interrupts. This is termed as the "global" priority. The priority level
// must be a number between 1 (highest) to 16 (lowest). A value of 0 must
// be entered for reserved interrupts or interrupts that are not used.
//
// Note: The priority levels below are used to calculate the IER register
//       interrupt masks MINT1 to MINT16.
//
// Note: The priority levels shown here may not make sense in a
//       real application.  This is for demonstration purposes only!!!
//
//       The user should change these to values that make sense for
//       their application.
//
// 0  = not used
// 1  = highest priority
// ...
// 16 = lowest priority
//
#define INT1PL      3        // Global Priority for Group1 Interrupts
#define INT2PL      1        // Global Priority for Group2 Interrupts
#define INT3PL      2        // Global Priority for Group3 Interrupts
#define INT4PL      0        // Global Priority for Group4 Interrupts
#define INT5PL      0        // Global Priority for Group5 Interrupts
#define INT6PL      0        // Global Priority for Group6 Interrupts
#define INT7PL      0        // Global Priority for Group7 Interrupts
#define INT8PL      0        // Global Priority for Group8 Interrupts
#define INT9PL      0        // Global Priority for Group9 Interrupts
#define INT10PL     0        // Global Priority for Group10 Interrupts
#define INT11PL     0        // Global Priority for Group11 Interrupts
#define INT12PL     0        // Global Priority for Group12 Interrupts
#define INT13PL     0        // Global Priority for INT13 (TINT1)
#define INT14PL     0        // Global Priority for INT14 (TINT2)
#define INT15PL     0        // Global Priority for DATALOG
#define INT16PL     0        // Global Priority for RTOSINT

//
// Set "Group" Interrupt Priority Level (PIEIER1 to PIEIER12 registers):
//
// The user must set the appropriate priority level for each of the PIE
// interrupts. This is termed as the "group" priority. The priority level
// must be a number between 1 (highest) to 16 (lowest). A value of 0 must
// be entered for reserved interrupts or interrupts that are not used.
//
// Note: The priority levels below are used to calculate the following
//       PIEIER register interrupt masks:
//       MG1_1 to MG1_16
//       MG2_1 to MG2_16
//       MG3_1 to MG3_16
//       MG4_1 to MG4_16
//       MG5_1 to MG5_16
//       MG6_1 to MG6_16
//       MG7_1 to MG7_16
//       MG8_1 to MG8_16
//       MG9_1 to MG9_16
//       MG10_1 to MG10_16
//       MG11_1 to MG11_16
//       MG12_1 to MG12_16
//
// Note: The priority levels shown here may not make sense in a
//       real application.  This is for demonstration purposes only!!!
//
//       The user should change these to values that make sense for
//       their application.
//
// 0  = not used
// 1  = highest priority
// ...
// 16  = lowest priority
//
#define G1_1PL      1       // ADCA1_INT
#define G1_2PL      0       // Reserved
#define G1_3PL      0       // ADCC1_INT
#define G1_4PL      0       // XINT1_INT
#define G1_5PL      0       // XINT2_INT
#define G1_6PL      0       // Reserved
#define G1_7PL      2       // TIMER0_INT
#define G1_8PL      0       // WAKE_INT
#define G1_9PL      0       // Reserved
#define G1_10PL     0       // Reserved
#define G1_11PL     0       // Reserved
#define G1_12PL     0       // Reserved
#define G1_13PL     0       // Reserved
#define G1_14PL     0       // Reserved
#define G1_15PL     0       // Reserved
#define G1_16PL     0       // Reserved

#define G2_1PL      1       // EPWM1_TZ_INT
#define G2_2PL      2       // EPWM2_TZ_INT
#define G2_3PL      0       // EPWM3_TZ_INT
#define G2_4PL      3       // EPWM4_TZ_INT
#define G2_5PL      0       // EPWM5_TZ_INT
#define G2_6PL      0       // EPWM6_TZ_INT
#define G2_7PL      0       // EPWM7_TZ_INT
#define G2_8PL      0       // Reserved
#define G2_9PL      0       // Reserved
#define G2_10PL     0       // Reserved
#define G2_11PL     0       // Reserved
#define G2_12PL     0       // Reserved
#define G2_13PL     0       // Reserved
#define G2_14PL     0       // Reserved
#define G2_15PL     0       // Reserved
#define G2_16PL     0       // Reserved

#define G3_1PL      0       // EPWM1_INT
#define G3_2PL      0       // EPWM2_INT
#define G3_3PL      1       // EPWM3_INT
#define G3_4PL      0       // EPWM4_INT
#define G3_5PL      0       // EPWM5_INT
#define G3_6PL      0       // EPWM6_INT
#define G3_7PL      0       // EPWM7_INT
#define G3_8PL      0       // Reserved
#define G3_9PL      0       // Reserved
#define G3_10PL     0       // Reserved
#define G3_11PL     0       // Reserved
#define G3_12PL     0       // Reserved
#define G3_13PL     0       // Reserved
#define G3_14PL     0       // Reserved
#define G3_15PL     0       // Reserved
#define G3_16PL     0       // Reserved

#define G4_1PL      0       // ECAP1_INT
#define G4_2PL      0       // ECAP2_INT
#define G4_3PL      0       // ECAP3_INT
#define G4_4PL      0       // Reserved
#define G4_5PL      0       // Reserved
#define G4_6PL      0       // Reserved
#define G4_7PL      0       // Reserved
#define G4_8PL      0       // Reserved
#define G4_9PL      0       // Reserved
#define G4_10PL     0       // Reserved
#define G4_11PL     0       // ECAP3_2_INT
#define G4_12PL     0       // Reserved
#define G4_13PL     0       // Reserved
#define G4_14PL     0       // Reserved
#define G4_15PL     0       // Reserved
#define G4_16PL     0       // Reserved

#define G5_1PL      0       // EQEP1_INT
#define G5_2PL      0       // EQEP2_INT
#define G5_3PL      0       // Reserved
#define G5_4PL      0       // Reserved
#define G5_5PL      0       // CLB1_INT
#define G5_6PL      0       // CLB2_INT
#define G5_7PL      0       // Reserved
#define G5_8PL      0       // Reserved
#define G5_9PL      0       // Reserved
#define G5_10PL     0       // Reserved
#define G5_11PL     0       // Reserved
#define G5_12PL     0       // Reserved
#define G5_13PL     0       // Reserved
#define G5_14PL     0       // Reserved
#define G5_15PL     0       // Reserved
#define G5_16PL     0       // Reserved

#define G6_1PL      0       // SPIA_RX_INT
#define G6_2PL      0       // SPIA_TX_INT
#define G6_3PL      0       // SPIB_RX_INT
#define G6_4PL      0       // SPIB_TX_INT
#define G6_5PL      0       // Reserved
#define G6_6PL      0       // Reserved
#define G6_7PL      0       // Reserved
#define G6_8PL      0       // Reserved
#define G6_9PL      0       // Reserved
#define G6_10PL     0       // Reserved
#define G6_11PL     0       // Reserved
#define G6_12PL     0       // Reserved
#define G6_13PL     0       // Reserved
#define G6_14PL     0       // Reserved
#define G6_15PL     0       // Reserved
#define G6_16PL     0       // Reserved

#define G7_1PL      0       // DMA_CH1_INT
#define G7_2PL      0       // DMA_CH2_INT
#define G7_3PL      0       // DMA_CH3_INT
#define G7_4PL      0       // DMA_CH4_INT
#define G7_5PL      0       // DMA_CH5_INT
#define G7_6PL      0       // DMA_CH6_INT
#define G7_7PL      0       // Reserved
#define G7_8PL      0       // Reserved
#define G7_9PL      0       // Reserved
#define G7_10PL     0       // Reserved
#define G7_11PL     0       // FSITXA1_INT
#define G7_12PL     0       // FSITXA2_INT
#define G7_13PL     0       // FSIRXA1_INT
#define G7_14PL     0       // FSIRXA2_INT
#define G7_15PL     0       // Reserved
#define G7_16PL     0       // DCC0_INT

#define G8_1PL      0       // I2CA_INT
#define G8_2PL      0       // I2CA_FIFO_INT
#define G8_3PL      0       // I2CB_INT
#define G8_4PL      0       // I2CB_FIFO_INT
#define G8_5PL      0       // Reserved
#define G8_6PL      0       // Reserved
#define G8_7PL      0       // Reserved
#define G8_8PL      0       // Reserved
#define G8_9PL      0       // LINA0_INT
#define G8_10PL     0       // LINA1_INT
#define G8_11PL     0       // LINB0_INT
#define G8_12PL     0       // LINB1_INT
#define G8_13PL     0       // PMBUSA_INT
#define G8_14PL     0       // Reserved
#define G8_15PL     0       // Reserved
#define G8_16PL     0       // DCC1_INT

#define G9_1PL      0       // SCIA_RX_INT
#define G9_2PL      0       // SCIA_TX_INT
#define G9_3PL      0       // Reserved
#define G9_4PL      0       // Reserved
#define G9_5PL      0       // CANA0_INT
#define G9_6PL      0       // CANA1_INT
#define G9_7PL      0       // Reserved
#define G9_8PL      0       // Reserved
#define G9_9PL      0       // Reserved
#define G9_10PL     0       // Reserved
#define G9_11PL     0       // Reserved
#define G9_12PL     0       // Reserved
#define G9_13PL     0       // BGCRC_INT
#define G9_14PL     0       // Reserved
#define G9_15PL     0       // Reserved
#define G9_16PL     0       // HICA_INT

#define G10_1PL     0       // ADCA_EVT_INT
#define G10_2PL     0       // ADCA2_INT
#define G10_3PL     0       // ADCA3_INT
#define G10_4PL     0       // ADCA4_INT
#define G10_5PL     0       // Reserved
#define G10_6PL     0       // Reserved
#define G10_7PL     0       // Reserved
#define G10_8PL     0       // Reserved
#define G10_9PL     0       // ADCC_EVT_INT
#define G10_10PL    0       // ADCC2_INT
#define G10_11PL    0       // ADCC3_INT
#define G10_12PL    0       // ADCC4_INT
#define G10_13PL    0       // Reserved
#define G10_14PL    0       // Reserved
#define G10_15PL    0       // Reserved
#define G10_16PL    0       // Reserved

#define G11_1PL     0       // Reserved
#define G11_2PL     0       // Reserved
#define G11_3PL     0       // Reserved
#define G11_4PL     0       // Reserved
#define G11_5PL     0       // Reserved
#define G11_6PL     0       // Reserved
#define G11_7PL     0       // Reserved
#define G11_8PL     0       // Reserved
#define G11_9PL     0       // Reserved
#define G11_10PL    0       // Reserved
#define G11_11PL    0       // Reserved
#define G11_12PL    0       // Reserved
#define G11_13PL    0       // Reserved
#define G11_14PL    0       // Reserved
#define G11_15PL    0       // Reserved
#define G11_16PL    0       // Reserved

#define G12_1PL     0       // XINT3_INT
#define G12_2PL     0       // XINT4_INT
#define G12_3PL     0       // XINT5_INT
#define G12_4PL     0       // PBIST_INT
#define G12_5PL     0       // FMC_INT
#define G12_6PL     0       // Reserved
#define G12_7PL     0       // FPU_OVERFLOW_ISR
#define G12_8PL     0       // FPU_UNDERFLOW_ISR
#define G12_9PL     0       // Reserved
#define G12_10PL    0       // RAM_CORRECTABLE_ERROR_ISR
#define G12_11PL    0       // FLASH_CORRECTABLE_ERROR_ISR
#define G12_12PL    0       // RAM_ACCESS_VIOLATION_INT
#define G12_13PL    0       // SYS_PLL_SLIP_INT
#define G12_14PL    0       // Reserved
#define G12_15PL    0       // Reserved
#define G12_16PL    0       // Reserved

#ifdef __cplusplus
}
#endif /* extern "C" */

#endif

Probably a bad setting ? Can you help me please ?

Thanks 

Damien

  • Hi Damien,

    Thanks for your question. For such a scenario, I would highly recommend stepping through the code and finding where the code is getting stuck. My best guess is that one of the interrupts that is enabled is "starving" the other interrupt from running. Basically, it keeps interrupting with a higher priority and preventing the other one from firing.

    Another possibility is that one interrupt is interrupting itself repeatedly: enters into the ISR, begins processing, but then receives another interrupt for itself and starts over, and repeats over and over again.

    Both can easily be diagnosed by stepping through the code.

    In order to continue assisting, can you please step through the code and provide code snippets of the part of the code that is "stuck"?

    Regards,

    Vince

  • Hi Vince,

    Thanks for your reply.

    After performing various tests, I have two interrupts configured ADCA1 and TIMER0, I want the TIMER0 interrupt to have a higher priority than the ADC so I modified the header file accordingly. I also attached to the oscilloscope my two interrupts, bad operation at the beginning because the TIMER0 interrupt must take place every 10ms what we observe well once the ADC interrupt is not active anymore.

    It seems that my problem comes from the ADC interrupt at the priority level ?

    why is the PIEIFR3.INTx3 bit active when I commented this interruption in my code ?

    //Interrupt_register(INT_EPWM3, &isr_regulation);
     //Interrupt_enable(INT_EPWM3); 

    And my TIMER0 interrupt :
    
    __interrupt void isr_slow_tasks()
    {
        GPIO_writePin(39, 1); // for test
    
        /// See the C28x interrupt nesting document for more details.
        /// Save IER register on stack
        volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER1);
        /// Set the global and group priority to allow CPU interrupts with higher priority.
        /// Modify the IER register to allow CPU interrupts with a higher user priority to be serviced.
        /// At this time IER has already been saved on the stack.
        IER |= M_INT1;
        IER &= MINT1;
        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG1_7;
    
        /// Enable Interrupts
        /// Clear the PIEACK bits.
        Interrupt_clearACKGroup(0xFFFFU);
        /// Wait at least one cycle.
        __asm("  NOP");
        /// Clear the INTM bit. Use this define or the assembly statement asm(" CLRC INTM).
        EINT;
    
        if(CPUTimer_getTimerOverflowStatus(CPUTIMER0_BASE) == true)
        {
            CPUTimer_clearOverflowFlag(CPUTIMER0_BASE);
        }
    
        .......
    
        /// Set the INTM to disable interrupts, use this define or the assembly statement asm("SETC INTM").
        DINT;
        /// Acknowledge the interrupt, see PIE Interrupt Vectors table
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
        /// Restore PIEIER
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER;
    
        GPIO_writePin(39, 0); // for test
    }

    Here my ADC interrupt :
    
    __interrupt void isr_adca(void)
    {
        GPIO_writePin(4, 1); // for test
    
        /// See the C28x interrupt nesting document for more details.
        /// Save IER register on stack
        volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER1);
    
        /// Set the global and group priority to allow CPU interrupts with higher priority.
        /// Modify the IER register to allow CPU interrupts with a higher user priority to be serviced.
        /// At this time IER has already been saved on the stack.
        IER |= M_INT1;
        IER &= MINT1;
        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG1_1;
    
        /// Enable Interrupts
        /// Clear the PIEACK bits
        Interrupt_clearACKGroup(0xFFFFU);
        /// Wait at least one cycle.
        __asm("  NOP");
        /// Clear the INTM bit. Use this define or the assembly statement asm(" CLRC INTM).
        EINT;
    
        .......
    
        /// Check if overflow has occurred
        if(ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1) == true)
        {
            ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1);
            ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
        }
        /// Clear the interrupt flag
        ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
    
        /// Set the INTM to disable interrupts, use this define or the assembly statement asm("SETC INTM").
        DINT;
        /// Acknowledge the interrupt, see PIE Interrupt Vectors table
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
        /// Restore PIEIER
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER;
    
        GPIO_writePin(4, 0); // for test
    }

    I went through the C28 nesting interrupt documentation with the different steps but I don't see any discrepancies with my code, can you please help me ?

    Thanks 

    Damien

  • And here a screenshot of my debugger for the PIEIFR register and the oscilloscope

    Pink signal : ADC interrupt

    Yellow signal : TIMER0 interrupt

    Sorry for the reflections.

  • Hi Damien,

      

    Thanks for testing and providing the screenshots. The scope capture hints at the issue, which is reflected in the TIMER0 interrupt. Let me place the offending code here:

    TIMER0 ISR:

        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG1_7;

    This is inside the TIMER0 ISR. Basically, what this is saying is "allow interrupts from channel 7 inside this interrupt". The problem is this means only Group1,Channel7 can interrupt inside Group1,Channel7. So basically, this only lets the TIMER0 interrupt itself. That's not what you want probably. You probably don't want ANYTHING to interrupt TIMER0. If that's true, then you can actually remove all the nesting from this ISR.

    Now onto the ADC interrupt:

      

    ADCA1 ISR:

    This has the same issue as the above, but for itself. Here's the offending code:

        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG1_1;

    This is saying "allow interrupts from channel 1 inside this interrupt". Again, this means that the only thing that can interrupt ADCA1 is itself. But from what you were saying, it sounds like you want ADCA1 to only allow CPUTIMER0 to interrupt inside ADCA1. If so, then you can change the line above to:

        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG1_7;

    What this now says is "allow interrupts from channel 7 inside this interrupt". Or said another way: "allow interrupts from TIMER0 inside ADCA1 interrupt".

      

    Regards,

    Vince

  • Hi Vince,

    Thank you very much for these clarifications, I explain a little better what I want to do:
    I set up a regulation I wish so:
    - that the isr_regulation interrupt is processed right after the end of the ADC interrupt.
    - that if a TIMER0 interrupt occurs, it is processed after the two previous ones (isr_adc and isr_regulation)
    - and finally, if a tz interrupt occurs, it should have priority over all the others.
    I get lost a little in all this with the oscilloscope I also observe the same phenomena as before. I can't configure my priorities and HW_REG() functions correctly.
    Can you help me please? Thanks a lot

    I join my code and a screenshot :

    ISR adc :
    __interrupt void isr_adca(void)
    {
        GPIO_writePin(4, 1); // for test
    
        /// See the C28x interrupt nesting document for more details.
        /// Save IER register on stack
        volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER1);
    
        /// Set the global and group priority to allow CPU interrupts with higher priority.
        /// Modify the IER register to allow CPU interrupts with a higher user priority to be serviced.
        /// At this time IER has already been saved on the stack.
        IER |= M_INT1;
        IER &= MINT1;
    
        /// We don't want anything to interrupt ADC interrupt.
        /// ...
    
        /// Enable Interrupts
        /// Clear the PIEACK bits
        Interrupt_clearACKGroup(0xFFFFU);
        /// Wait at least one cycle.
        __asm("  NOP");
        /// Clear the INTM bit. Use this define or the assembly statement asm(" CLRC INTM).
        EINT;
    
        ...
    
        /// Check if overflow has occurred
        if(ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1) == true)
        {
            ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1);
            ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
        }
        /// Clear the interrupt flag
        ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
    
        /// Set the INTM to disable interrupts, use this define or the assembly statement asm("SETC INTM").
        DINT;
        /// Acknowledge the interrupt, see PIE Interrupt Vectors table
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
        /// Restore PIEIER
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER;
    
        GPIO_writePin(4, 0); // for test
    }

    __interrupt void isr_slow_tasks()
    {
        GPIO_writePin(39, 1); // for test
    
        /// See the C28x interrupt nesting document for more details.
        /// Save IER register on stack
        volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER1);
        /// Set the global and group priority to allow CPU interrupts with higher priority.
        /// Modify the IER register to allow CPU interrupts with a higher user priority to be serviced.
        /// At this time IER has already been saved on the stack.
        IER |= M_INT1;
        IER &= MINT1;
    
        /// Allow interrupts from ADCA1 and regulation (INTEPWM3) inside slow tasks interrupt".
        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG1_1;
        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG3_3;
    
        /// Enable Interrupts
        /// Clear the PIEACK bits.
        Interrupt_clearACKGroup(0xFFFFU);
        /// Wait at least one cycle.
        __asm("  NOP");
        /// Clear the INTM bit. Use this define or the assembly statement asm(" CLRC INTM).
        EINT;
    
        if(CPUTimer_getTimerOverflowStatus(CPUTIMER0_BASE) == true)
        {
            CPUTimer_clearOverflowFlag(CPUTIMER0_BASE);
        }
    
        ...
    
        /// Set the INTM to disable interrupts, use this define or the assembly statement asm("SETC INTM").
        DINT;
        /// Acknowledge the interrupt, see PIE Interrupt Vectors table
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
        /// Restore PIEIER
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER;
    
        GPIO_writePin(39, 0); // for test
    }
    __interrupt void isr_regulation()
    {
        GPIO_writePin(44, 1);
    
        /// Clear INT flag for this interrupt
        EPWM_clearEventTriggerInterruptFlag(SPWM_REGU);
        /// Save IER register on stack
        volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER3);
    
        /// Set the global and group priority to allow CPU interrupts with higher priority
        IER |= M_INT3;
        IER &= MINT3;
    
        /// Enable Interrupts
        Interrupt_clearACKGroup(0xFFFFU);
        __asm("  NOP");
        EINT;
    
        ...
    
        /// Acknowledge interrupt group
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
        /// Disable interrupts and restore registers saved:
        DINT;
        HWREGH(PIECTRL_BASE + PIE_O_IER3) = tempPIEIER;
    
        GPIO_writePin(44, 0);
    }

    Yellow signal : TIMER0 interrupt (slow monitoring)

    PINK signal : ADC interrupt

    BLUE signal : regulation interrupt (INTEPWM3)

    If I can summarize this with a time base I would like ADC interrupt treatment AFTER regulation interrupt treatment (INTePWM3) AND AFTER TIMER0 interrupt treatment (slow monitoring). Is it possible ? How to do this please ?

    Thanks a lot

    Damien

  • And here prioritization header file configuration :

    #ifndef PRIORITIZED_ISR_LEVELS_H
    #define PRIORITIZED_ISR_LEVELS_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define INT1PL      2        // Global Priority for Group1 Interrupts
    #define INT2PL      1        // Global Priority for Group2 Interrupts
    #define INT3PL      3        // Global Priority for Group3 Interrupts
    #define INT4PL      0        // Global Priority for Group4 Interrupts
    #define INT5PL      0        // Global Priority for Group5 Interrupts
    #define INT6PL      0        // Global Priority for Group6 Interrupts
    #define INT7PL      0        // Global Priority for Group7 Interrupts
    #define INT8PL      0        // Global Priority for Group8 Interrupts
    #define INT9PL      0        // Global Priority for Group9 Interrupts
    #define INT10PL     0        // Global Priority for Group10 Interrupts
    #define INT11PL     0        // Global Priority for Group11 Interrupts
    #define INT12PL     0        // Global Priority for Group12 Interrupts
    #define INT13PL     0        // Global Priority for INT13 (TINT1)
    #define INT14PL     0        // Global Priority for INT14 (TINT2)
    #define INT15PL     0        // Global Priority for DATALOG
    #define INT16PL     0        // Global Priority for RTOSINT
    
    
    #define G1_1PL      1       // ADCA1_INT
    #define G1_2PL      0       // Reserved
    #define G1_3PL      0       // ADCC1_INT
    #define G1_4PL      0       // XINT1_INT
    #define G1_5PL      0       // XINT2_INT
    #define G1_6PL      0       // Reserved
    #define G1_7PL      2       // TIMER0_INT
    #define G1_8PL      0       // WAKE_INT
    #define G1_9PL      0       // Reserved
    #define G1_10PL     0       // Reserved
    #define G1_11PL     0       // Reserved
    #define G1_12PL     0       // Reserved
    #define G1_13PL     0       // Reserved
    #define G1_14PL     0       // Reserved
    #define G1_15PL     0       // Reserved
    #define G1_16PL     0       // Reserved
    
    #define G2_1PL      1       // EPWM1_TZ_INT
    #define G2_2PL      2       // EPWM2_TZ_INT
    #define G2_3PL      0       // EPWM3_TZ_INT
    #define G2_4PL      3       // EPWM4_TZ_INT
    #define G2_5PL      0       // EPWM5_TZ_INT
    #define G2_6PL      0       // EPWM6_TZ_INT
    #define G2_7PL      0       // EPWM7_TZ_INT
    #define G2_8PL      0       // Reserved
    #define G2_9PL      0       // Reserved
    #define G2_10PL     0       // Reserved
    #define G2_11PL     0       // Reserved
    #define G2_12PL     0       // Reserved
    #define G2_13PL     0       // Reserved
    #define G2_14PL     0       // Reserved
    #define G2_15PL     0       // Reserved
    #define G2_16PL     0       // Reserved
    
    #define G3_1PL      0       // EPWM1_INT
    #define G3_2PL      0       // EPWM2_INT
    #define G3_3PL      1       // EPWM3_INT
    #define G3_4PL      0       // EPWM4_INT
    #define G3_5PL      0       // EPWM5_INT
    #define G3_6PL      0       // EPWM6_INT
    #define G3_7PL      0       // EPWM7_INT
    #define G3_8PL      0       // Reserved
    #define G3_9PL      0       // Reserved
    #define G3_10PL     0       // Reserved
    #define G3_11PL     0       // Reserved
    #define G3_12PL     0       // Reserved
    #define G3_13PL     0       // Reserved
    #define G3_14PL     0       // Reserved
    #define G3_15PL     0       // Reserved
    #define G3_16PL     0       // Reserved
    
    
    #ifdef __cplusplus
    }
    #endif /* extern "C" */
    
    #endif
    

  • Hi Damien,

    Thanks for your follow up.

    - that the isr_regulation interrupt is processed right after the end of the ADC interrupt.
    - that if a TIMER0 interrupt occurs, it is processed after the two previous ones (isr_adc and isr_regulation)
    - and finally, if a tz interrupt occurs, it should have priority over all the others.

    Based on these items, it looks like nesting is not the desire for anything except for the TZ interrupt. The others you mentioned are all related to sequential actions. Meaning, you have a certain order for things to happen in.

    I would recommend removing nesting from all of the other interrupts except the one you are trying to have occur INSIDE other interrupts. Every other item mentioned seems to have the words "after X interrupt". This implies no nesting, but instead re-prioritization.

    For the code, we typically do not debug code dumps in the E2E forums, due to support difficulty of doing so. I can however provide pointers:

    1. Start by removing nesting and prioritization from all interrupts except 1 critical interrupt. Start with that and try to get that working properly.

    2. Once one single nesting interrupt is working properly, add on an additional interrupt (nesting or re-ordering, either is fine) and get that working.

    3. Repeat until all are working properly.

    Regards,

    Vince

  • Hi Vince,

    Thanks for all these precisions vince, I had proceeded by isolating the various interruptions then reactivating them one by one in order to better isolate the problems.
    Small question: what do you mean by nesting interrupts? Because priority management is not enough in some cases? Why do you have to declare a nesting of the trip zone interrupt in the other interrupts? It is the highest priority.

    Thanks

    Damien

  • Hi Damien,

    My apologies, I believe I misunderstood the previous response. For simple prioritization, I do recommend the provided interrupts prioritization example in C2000Ware, as this provides direct ability to prioritize.

    Please let me know if this answers your question.

    Regards,

    Vince