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: EPWM4 interrupt stop after add TI diagnostic library

Part Number: TMS320F280025
Other Parts Discussed in Thread: AFE031, C2000WARE

Hi

My project using TI AFE031 FSK boostxl_afe031_f28004x_rx as template. I just change the interrupt source to EPWM4 as below

#pragma CODE_SECTION(epwm2_isr,".TI.ramfunc");
__interrupt void epwm4_isr(void)
{
    EALLOW;

    //
    // Enable ADC ISR Nesting
    //
    uint16_t TempPIEIER;
    TempPIEIER = PieCtrlRegs.PIEIER2.all;
    IER |= M_INT1;
    IER &= MINT1;                         // Set "global" priority
    PieCtrlRegs.PIEIER2.all &= MG1_1;     // Set "group" priority
    PieCtrlRegs.PIEACK.all = 0xFFFF;      // Enable PIE interrupts
    asm("       NOP");                    // Wait one cycle
    EINT;                                 // Clear INTM to enable interrupts

    //
    // Run the FSK Correlation Detector Function
    //
    FSK_CORR_DETECTOR_OverSampl_RUN(&FSK_struct1);

    //
    // See if a mark or space bit is detected
    //
    if(FSK_struct1.bit_detected != 0)
    {
        rxMessage[message_index++] = FSK_struct1.bit_detected; // Save the detected bit in the message buffer

        FSK_struct1.bit_detected = 0; // Clear the detected bit member

        //
        // Set flags when message buffer is full
        //
        if(RX_MESSAGE_SIZE <= message_index)
        {
            message_index = 0;
            msgFull = 1;
        }
    }

    //
    // Clear INT flag for EPwm2
    //
    //EPwm2Regs.ETCLR.bit.INT = 1;

   EPwm2Regs.ETCLR.bit.INT = 1;

    //
    // Acknowledge this interrupt to receive more interrupts from group 3
    //
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

    //
    // Restore registers saved for ADC ISR Nesting
    //
    DINT;
    PieCtrlRegs.PIEIER2.all = TempPIEIER;

    //
    // Toggle gpio pin for measuring frequency, debug purposes
    //
    //GpioDataRegs.GPCTOGGLE.bit.GPIO65 = 1; // LP Pin 47
}

and

#define INTERRUPT_BIT_ISR &epwm4_isi

interrupt_register(INT_EPWM4, INTERRUPT_BIT_ISR)

Anything was working fine as long as I added TI diagnostic function code which is reference to diagnostic library example f28002x_test_application.c

            DINT;

            uint16_t returnVal =
                    STL_CPU_REG_checkCPURegisters(STA_Tests_injectError);
            if (returnVal == STL_CPU_REG_FAIL)
            {

                  mcuFault_Status = mcuFault_Status | CPU_REGISTER_FAULT;
            }
            EINT;

The ISR function don't be run after a while ~ 7minutes. The diagnostic function will be ran in main loop ~ every 14ms.

Please advise that did I do something wrong?

    1. Typo should be EPwm4Regs.ETCLR.bit.INT = 
  • I think it's because STL_CPU_REG_checkCPURegisters is testing the IFR register. It backs it up and restores it, but since setting INTM doesn't prevent the interrupt from propagating at the IFR flag. It's possible an interrupt comes in after the back up but then gets erased by the restore.

    I think you have a few options:

    1. Modify STL_CPU_REG_checkCPURegisters() to remove the IFR test. You could test IFR for stuck bits separately at start up before you enable any interrupts in the PIE, but don't use STL_CPU_REG_checkCPURegisters to check it periodically. I'm guessing you probably already have some other kind of interrupt monitoring in place that would catch any issues with the IFR register.
    2. In addition to doing DINT, disable interrupts in the PIEIER registers (following the procedure in the TRM for disabling interrupts) before running STL_CPU_REG_checkCPURegisters. After it runs, reenable the interrupts.

    Either way, this should be highlighted in the SDL documentation. I'll file a bug to add a note.

    Whitney

  • Whitney

    Could you provide an example code in option 2?

  • I think option 1 is cleanest, so that's what I would recommend.

    However, option 2 would look something like the pseudo-code below

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // Disable all interrupts in the PIE so they can't propagate to IFR
    PieCtrlRegs.PIEIER1.all = 0;
    PieCtrlRegs.PIEIER2.all = 0;
    PieCtrlRegs.PIEIER3.all = 0;
    . . .
    PieCtrlRegs.PIEIER16.all = 0;
    // CPU Timer 1 and 2 aren't PIE interrupts, so disable them separately
    CpuTimer1Regs.TCR.bit.TIE = 0;
    CpuTimer2Regs.TCR.bit.TIE = 0;
    // Wait five cycles for any final interrupts to propagate to IFR
    NOP;
    NOP;
    NOP;
    NOP;
    NOP;
    // The TRM says that when you're disabling interrupts, you should then clear
    // the CPU IFR and PIEACK, but since we're going to be reenabling interrupts
    // as soon as STL_CPU_REG_checkCPURegisters() finishes, we can probably just
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Whitney

  • Hi Whitney

    Firstly, I am not family with assembly. If you can show me how to modify it. I will do it

  • Whitney

    Is it mean that no need to DINT and EINT in the code?

  • Whitney

    I based on your pseudo code and write a function as below

    void cpuRegister_Check(void)
    {
        while (buck_isrCompleted_Flag[0] == false);
        uint16_t TempPIEIER1, TempPIEIER2,TempPIEIER3, TempPIEIER4,TempPIEIER5, TempPIEIER6,TempPIEIER7,TempPIEIER8;
        uint16_t TempPIEIER9, TempPIEIER10,TempPIEIER11, TempPIEIER12,TempPIEIER13, TempPIEIER14,TempPIEIER15,TempPIEIER16;
        uint16_t TempPIEIFR1, TempPIEIFR2,TempPIEIFR3, TempPIEIFR4,TempPIEIFR5, TempPIEIFR6,TempPIEIFR7,TempPIEIFR8;
        uint16_t TempPIEIFR9, TempPIEIFR10,TempPIEIFR11, TempPIEIFR12,TempPIEIFR13, TempPIEIFR14,TempPIEIFR15,TempPIEIFR16;
        TempPIEIER1 = PieCtrlRegs.PIEIER1.all;
        TempPIEIER2 = PieCtrlRegs.PIEIER2.all;
        TempPIEIER3 = PieCtrlRegs.PIEIER3.all;
        TempPIEIER4 = PieCtrlRegs.PIEIER4.all;
        TempPIEIER5 = PieCtrlRegs.PIEIER5.all;
        TempPIEIER6 = PieCtrlRegs.PIEIER6.all;
        TempPIEIER7 = PieCtrlRegs.PIEIER7.all;
        TempPIEIER8 = PieCtrlRegs.PIEIER8.all;
        TempPIEIER9 = PieCtrlRegs.PIEIER9.all;
        TempPIEIER10 = PieCtrlRegs.PIEIER10.all;
        TempPIEIER11 = PieCtrlRegs.PIEIER11.all;
        TempPIEIER12 = PieCtrlRegs.PIEIER12.all;
        TempPIEIFR1 = PieCtrlRegs.PIEIFR1.all;
        TempPIEIFR2 = PieCtrlRegs.PIEIFR2.all;
        TempPIEIFR3 = PieCtrlRegs.PIEIFR3.all;
        TempPIEIFR4 = PieCtrlRegs.PIEIFR4.all;
        TempPIEIFR5 = PieCtrlRegs.PIEIFR5.all;
        TempPIEIFR6 = PieCtrlRegs.PIEIFR6.all;
        TempPIEIFR7 = PieCtrlRegs.PIEIFR7.all;
        TempPIEIFR8 = PieCtrlRegs.PIEIFR8.all;
        TempPIEIFR9 = PieCtrlRegs.PIEIFR9.all;
        TempPIEIFR10 = PieCtrlRegs.PIEIFR10.all;
        TempPIEIFR11 = PieCtrlRegs.PIEIFR11.all;
        TempPIEIFR12 = PieCtrlRegs.PIEIFR12.all;


    //    //DINT;
    //    // Disable all interrupts in the PIE so they can't propagate to IFR
        PieCtrlRegs.PIEIER1.all = 0;
        PieCtrlRegs.PIEIER2.all = 0;
        PieCtrlRegs.PIEIER3.all = 0;
        PieCtrlRegs.PIEIER4.all = 0;
        PieCtrlRegs.PIEIER5.all = 0;
        PieCtrlRegs.PIEIER6.all = 0;
        PieCtrlRegs.PIEIER7.all = 0;
        PieCtrlRegs.PIEIER8.all = 0;
        PieCtrlRegs.PIEIER9.all = 0;
        PieCtrlRegs.PIEIER10.all = 0;
        PieCtrlRegs.PIEIER11.all = 0;
        PieCtrlRegs.PIEIER12.all = 0;
        PieCtrlRegs.PIEIFR1.all = 0;
        PieCtrlRegs.PIEIFR2.all = 0;
        PieCtrlRegs.PIEIFR3.all = 0;
        PieCtrlRegs.PIEIFR4.all = 0;
        PieCtrlRegs.PIEIFR5.all = 0;
        PieCtrlRegs.PIEIFR6.all = 0;
        PieCtrlRegs.PIEIFR7.all = 0;
        PieCtrlRegs.PIEIFR8.all = 0;
        PieCtrlRegs.PIEIFR9.all = 0;
        PieCtrlRegs.PIEIFR10.all = 0;
        PieCtrlRegs.PIEIFR11.all = 0;
        PieCtrlRegs.PIEIFR12.all = 0;
    //
    //    // CPU Timer 1 and 2 aren't PIE interrupts, so disable them separately
        CpuTimer0Regs.TCR.bit.TIE = 0;
        CpuTimer1Regs.TCR.bit.TIE = 0;
        CpuTimer2Regs.TCR.bit.TIE = 0;
    //    CpuTimer3Regs.TCR.bit.TIE = 0;
        // Wait five cycles for any final interrupts to propagate to IFR
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
        buck_isrCompleted_Flag[0] = false;

        cpuRegister_Fail_Counter++;
        uint16_t returnVal =
                STL_CPU_REG_checkCPURegisters(false);
        PieCtrlRegs.PIEIER1.all = TempPIEIER1;
        PieCtrlRegs.PIEIER2.all = TempPIEIER2;
        PieCtrlRegs.PIEIER3.all = TempPIEIER3;
        PieCtrlRegs.PIEIER4.all = TempPIEIER4;
        PieCtrlRegs.PIEIER5.all = TempPIEIER5;
        PieCtrlRegs.PIEIER6.all = TempPIEIER6;
        PieCtrlRegs.PIEIER7.all = TempPIEIER7;
        PieCtrlRegs.PIEIER8.all = TempPIEIER8;
        PieCtrlRegs.PIEIER9.all = TempPIEIER9;
        PieCtrlRegs.PIEIER10.all = TempPIEIER10;
        PieCtrlRegs.PIEIER11.all = TempPIEIER11;
        PieCtrlRegs.PIEIER12.all = TempPIEIER12;
        PieCtrlRegs.PIEIFR1.all = TempPIEIFR1;
        PieCtrlRegs.PIEIFR2.all = TempPIEIFR2;
        PieCtrlRegs.PIEIFR3.all = TempPIEIFR3;
        PieCtrlRegs.PIEIFR4.all = TempPIEIFR4;
        PieCtrlRegs.PIEIFR5.all = TempPIEIFR5;
        PieCtrlRegs.PIEIFR6.all = TempPIEIFR6;
        PieCtrlRegs.PIEIFR7.all = TempPIEIFR7;
        PieCtrlRegs.PIEIFR8.all = TempPIEIFR8;
        PieCtrlRegs.PIEIFR9.all = TempPIEIFR9;
        PieCtrlRegs.PIEIFR10.all = TempPIEIFR10;
        PieCtrlRegs.PIEIFR11.all = TempPIEIFR11;
        PieCtrlRegs.PIEIFR12.all = TempPIEIFR12;
    //    PieCtrlRegs.PIEIER13.all = TempPIEIER13;
    //    PieCtrlRegs.PIEIER14.all = TempPIEIER14;
    //    PieCtrlRegs.PIEIER15.all = TempPIEIER15;
    //    PieCtrlRegs.PIEIER16.all = TempPIEIER16;

        // Reenable CPU Timer 1 and 2 interrupts
        CpuTimer0Regs.TCR.bit.TIE = 1;
        CpuTimer1Regs.TCR.bit.TIE = 1;
        CpuTimer2Regs.TCR.bit.TIE = 1;
        NOP;
        NOP;
        NOP;
        NOP;
        NOP;
    //    CpuTimer3Regs.TCR.bit.TIE = 1;
        if (returnVal == STL_CPU_REG_FAIL)
        {

            mcuFault_Status = mcuFault_Status | CPU_REGISTER_FAULT;
        }


    }

    I am using F280025 which has 12 IER and IFR only. MCU is latched after 2 times running with below screenshot

    Please advise what is problem.

    Thanks

  • Hi Whitney

    I changed the code below

        volatile uint16_t tempPIEIER1 = HWREGH(PIECTRL_BASE + PIE_O_IER1);
        volatile uint16_t tempPIEIER2 = HWREGH(PIECTRL_BASE + PIE_O_IER2);
        volatile uint16_t tempPIEIER3 = HWREGH(PIECTRL_BASE + PIE_O_IER3);
        volatile uint16_t tempPIEIER4 = HWREGH(PIECTRL_BASE + PIE_O_IER4);
        volatile uint16_t tempPIEIER5 = HWREGH(PIECTRL_BASE + PIE_O_IER5);
        volatile uint16_t tempPIEIER6 = HWREGH(PIECTRL_BASE + PIE_O_IER6);
        volatile uint16_t tempPIEIER7 = HWREGH(PIECTRL_BASE + PIE_O_IER7);
        volatile uint16_t tempPIEIER8 = HWREGH(PIECTRL_BASE + PIE_O_IER8);
        volatile uint16_t tempPIEIER9 = HWREGH(PIECTRL_BASE + PIE_O_IER9);
        volatile uint16_t tempPIEIER10 = HWREGH(PIECTRL_BASE + PIE_O_IER10);
        volatile uint16_t tempPIEIER11 = HWREGH(PIECTRL_BASE + PIE_O_IER11);
        volatile uint16_t tempPIEIER12 = HWREGH(PIECTRL_BASE + PIE_O_IER12);
        volatile uint16_t tempPIEIFR1 = HWREGH(PIECTRL_BASE + PIE_O_IFR1);
        volatile uint16_t tempPIEIFR2 = HWREGH(PIECTRL_BASE + PIE_O_IFR2);
        volatile uint16_t tempPIEIFR3 = HWREGH(PIECTRL_BASE + PIE_O_IFR3);
        volatile uint16_t tempPIEIFR4 = HWREGH(PIECTRL_BASE + PIE_O_IFR4);
        volatile uint16_t tempPIEIFR5 = HWREGH(PIECTRL_BASE + PIE_O_IFR5);
        volatile uint16_t tempPIEIFR6 = HWREGH(PIECTRL_BASE + PIE_O_IFR6);
        volatile uint16_t tempPIEIFR7 = HWREGH(PIECTRL_BASE + PIE_O_IFR7);
        volatile uint16_t tempPIEIFR8 = HWREGH(PIECTRL_BASE + PIE_O_IFR8);
        volatile uint16_t tempPIEIFR9 = HWREGH(PIECTRL_BASE + PIE_O_IFR9);
        volatile uint16_t tempPIEIFR10 = HWREGH(PIECTRL_BASE + PIE_O_IFR10);
        volatile uint16_t tempPIEIFR11 = HWREGH(PIECTRL_BASE + PIE_O_IFR11);
        volatile uint16_t tempPIEIFR12 = HWREGH(PIECTRL_BASE + PIE_O_IFR12);
        DINT;
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER2) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER3) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER4) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER5) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER6) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER7) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER8) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER9) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER10) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER11) = 0x00;
        HWREGH(PIECTRL_BASE + PIE_O_IER12) = 0x00;
        CPUTimer_disableInterrupt(TASKA_CPUTIMER_BASE);
        CPUTimer_disableInterrupt(TASKB_CPUTIMER_BASE);
        CPUTimer_disableInterrupt(TASKC_CPUTIMER_BASE);
        uint16_t returnVal =
                STL_CPU_REG_checkCPURegisters(false);
        if (returnVal == STL_CPU_REG_FAIL)
        {

            mcuFault_Status = mcuFault_Status | CPU_REGISTER_FAULT;
        }
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER1;
        HWREGH(PIECTRL_BASE + PIE_O_IER2) = tempPIEIER2;
        HWREGH(PIECTRL_BASE + PIE_O_IER3) = tempPIEIER3;
        HWREGH(PIECTRL_BASE + PIE_O_IER4) = tempPIEIER4;
        HWREGH(PIECTRL_BASE + PIE_O_IER5) = tempPIEIER5;
        HWREGH(PIECTRL_BASE + PIE_O_IER6) = tempPIEIER6;
        HWREGH(PIECTRL_BASE + PIE_O_IER7) = tempPIEIER7;
        HWREGH(PIECTRL_BASE + PIE_O_IER8) = tempPIEIER8;
        HWREGH(PIECTRL_BASE + PIE_O_IER9) = tempPIEIER9;
        HWREGH(PIECTRL_BASE + PIE_O_IER10) = tempPIEIER10;
        HWREGH(PIECTRL_BASE + PIE_O_IER11) = tempPIEIER11;
        HWREGH(PIECTRL_BASE + PIE_O_IER12) = tempPIEIER12;
        HWREGH(PIECTRL_BASE + PIE_O_IFR1) = tempPIEIFR1;
        HWREGH(PIECTRL_BASE + PIE_O_IFR2) = tempPIEIFR2;
        HWREGH(PIECTRL_BASE + PIE_O_IFR3) = tempPIEIFR3;
        HWREGH(PIECTRL_BASE + PIE_O_IFR4) = tempPIEIFR4;
        HWREGH(PIECTRL_BASE + PIE_O_IFR5) = tempPIEIFR5;
        HWREGH(PIECTRL_BASE + PIE_O_IFR6) = tempPIEIFR6;
        HWREGH(PIECTRL_BASE + PIE_O_IFR7) = tempPIEIFR7;
        HWREGH(PIECTRL_BASE + PIE_O_IFR8) = tempPIEIFR8;
        HWREGH(PIECTRL_BASE + PIE_O_IFR9) = tempPIEIFR9;
        HWREGH(PIECTRL_BASE + PIE_O_IFR10) = tempPIEIFR10;
        HWREGH(PIECTRL_BASE + PIE_O_IFR11) = tempPIEIFR11;
        HWREGH(PIECTRL_BASE + PIE_O_IFR12) = tempPIEIFR12;

        CPUTimer_enableInterrupt(TASKA_CPUTIMER_BASE);
        CPUTimer_enableInterrupt(TASKB_CPUTIMER_BASE);
        CPUTimer_enableInterrupt(TASKC_CPUTIMER_BASE);
        EINT;

    MCU do not latch anymore. Start to run it to see any issue found.

  • I wouldn't have expected that you would need to save and restore PIEIFR--PIEIER should have been enough.

    Anyway, if you want to try option 1 instead you would remove these sections:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ; lines 234 and 235
    PUSH IFR
    POP @TH ; save IFR in TH
    ; lines 263-268
    PUSH @AL
    POP IFR ; write to IFR
    PUSH IFR
    POP AR4
    CMP AL, @AR4
    B fail16BitRegTest, NEQ
    ; lines 346 and 347
    PUSH @TH
    POP IFR ; restore IFR
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Whitney

  • Whitney

    I have written other code below to store and restore IER only. It works fine over 20 Hours

    volatile uint16_t tempPIEIER1 = HWREGH(PIECTRL_BASE + PIE_O_IER1);
    volatile uint16_t tempPIEIER2 = HWREGH(PIECTRL_BASE + PIE_O_IER2);
    volatile uint16_t tempPIEIER3 = HWREGH(PIECTRL_BASE + PIE_O_IER3);
    volatile uint16_t tempPIEIER4 = HWREGH(PIECTRL_BASE + PIE_O_IER4);
    volatile uint16_t tempPIEIER5 = HWREGH(PIECTRL_BASE + PIE_O_IER5);
    volatile uint16_t tempPIEIER6 = HWREGH(PIECTRL_BASE + PIE_O_IER6);
    volatile uint16_t tempPIEIER7 = HWREGH(PIECTRL_BASE + PIE_O_IER7);
    volatile uint16_t tempPIEIER8 = HWREGH(PIECTRL_BASE + PIE_O_IER8);
    volatile uint16_t tempPIEIER9 = HWREGH(PIECTRL_BASE + PIE_O_IER9);
    volatile uint16_t tempPIEIER10 = HWREGH(PIECTRL_BASE + PIE_O_IER10);
    volatile uint16_t tempPIEIER11 = HWREGH(PIECTRL_BASE + PIE_O_IER11);
    volatile uint16_t tempPIEIER12 = HWREGH(PIECTRL_BASE + PIE_O_IER12);
    volatile uint16_t tempPIEIFR1 = HWREGH(PIECTRL_BASE + PIE_O_IFR1);
    volatile uint16_t tempPIEIFR2 = HWREGH(PIECTRL_BASE + PIE_O_IFR2);
    volatile uint16_t tempPIEIFR3 = HWREGH(PIECTRL_BASE + PIE_O_IFR3);
    volatile uint16_t tempPIEIFR4 = HWREGH(PIECTRL_BASE + PIE_O_IFR4);
    volatile uint16_t tempPIEIFR5 = HWREGH(PIECTRL_BASE + PIE_O_IFR5);
    volatile uint16_t tempPIEIFR6 = HWREGH(PIECTRL_BASE + PIE_O_IFR6);
    volatile uint16_t tempPIEIFR7 = HWREGH(PIECTRL_BASE + PIE_O_IFR7);
    volatile uint16_t tempPIEIFR8 = HWREGH(PIECTRL_BASE + PIE_O_IFR8);
    volatile uint16_t tempPIEIFR9 = HWREGH(PIECTRL_BASE + PIE_O_IFR9);
    volatile uint16_t tempPIEIFR10 = HWREGH(PIECTRL_BASE + PIE_O_IFR10);
    volatile uint16_t tempPIEIFR11 = HWREGH(PIECTRL_BASE + PIE_O_IFR11);
    volatile uint16_t tempPIEIFR12 = HWREGH(PIECTRL_BASE + PIE_O_IFR12);
    DINT;
    HWREGH(PIECTRL_BASE + PIE_O_IER1) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER2) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER3) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER4) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER5) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER6) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER7) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER8) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER9) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER10) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER11) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER12) = 0x00;
    CPUTimer_disableInterrupt(TASKA_CPUTIMER_BASE);
    CPUTimer_disableInterrupt(TASKB_CPUTIMER_BASE);
    CPUTimer_disableInterrupt(TASKC_CPUTIMER_BASE);
    uint16_t returnVal =
    STL_CPU_REG_checkCPURegisters(false);
    if (returnVal == STL_CPU_REG_FAIL)
    {

    mcuFault_Status = mcuFault_Status | CPU_REGISTER_FAULT;
    }
    HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER1;
    HWREGH(PIECTRL_BASE + PIE_O_IER2) = tempPIEIER2;
    HWREGH(PIECTRL_BASE + PIE_O_IER3) = tempPIEIER3;
    HWREGH(PIECTRL_BASE + PIE_O_IER4) = tempPIEIER4;
    HWREGH(PIECTRL_BASE + PIE_O_IER5) = tempPIEIER5;
    HWREGH(PIECTRL_BASE + PIE_O_IER6) = tempPIEIER6;
    HWREGH(PIECTRL_BASE + PIE_O_IER7) = tempPIEIER7;
    HWREGH(PIECTRL_BASE + PIE_O_IER8) = tempPIEIER8;
    HWREGH(PIECTRL_BASE + PIE_O_IER9) = tempPIEIER9;
    HWREGH(PIECTRL_BASE + PIE_O_IER10) = tempPIEIER10;
    HWREGH(PIECTRL_BASE + PIE_O_IER11) = tempPIEIER11;
    HWREGH(PIECTRL_BASE + PIE_O_IER12) = tempPIEIER12;
    HWREGH(PIECTRL_BASE + PIE_O_IFR1) = tempPIEIFR1;
    HWREGH(PIECTRL_BASE + PIE_O_IFR2) = tempPIEIFR2;
    HWREGH(PIECTRL_BASE + PIE_O_IFR3) = tempPIEIFR3;
    HWREGH(PIECTRL_BASE + PIE_O_IFR4) = tempPIEIFR4;
    HWREGH(PIECTRL_BASE + PIE_O_IFR5) = tempPIEIFR5;
    HWREGH(PIECTRL_BASE + PIE_O_IFR6) = tempPIEIFR6;
    HWREGH(PIECTRL_BASE + PIE_O_IFR7) = tempPIEIFR7;
    HWREGH(PIECTRL_BASE + PIE_O_IFR8) = tempPIEIFR8;
    HWREGH(PIECTRL_BASE + PIE_O_IFR9) = tempPIEIFR9;
    HWREGH(PIECTRL_BASE + PIE_O_IFR10) = tempPIEIFR10;
    HWREGH(PIECTRL_BASE + PIE_O_IFR11) = tempPIEIFR11;
    HWREGH(PIECTRL_BASE + PIE_O_IFR12) = tempPIEIFR12;

    CPUTimer_enableInterrupt(TASKA_CPUTIMER_BASE);
    CPUTimer_enableInterrupt(TASKB_CPUTIMER_BASE);
    CPUTimer_enableInterrupt(TASKC_CPUTIMER_BASE);
    EINT;

    Any comment on above code.

    Regarding to your previous mail, Do you mean that "Store and Restore IER/IFR" is not good enough to fix the problem. It is necessary to change assembly?

    BR

    HK Woo

  • Do you mean that "Store and Restore IER/IFR" is not good enough to fix the problem. It is necessary to change assembly?

    No, I expect either method should work fine. I like the option of changing the assembly better, because it allows you to avoid the extra execution cycles required for saving and restoring all those PIE registers. If the test execution time isn't a concern for you, that's fine.

    Any comment on above code.

    Does it still work if you remove the lines to read/write to the PIEIFR registers? It doesn't seem necessary to me, and you may be inadvertently cancelling interrupts that you want to receive.

    Whitney

  • Whitney

    I copied a wrong code. Actually the code should be below one

    volatile uint16_t tempPIEIER1 = HWREGH(PIECTRL_BASE + PIE_O_IER1);
    volatile uint16_t tempPIEIER2 = HWREGH(PIECTRL_BASE + PIE_O_IER2);
    volatile uint16_t tempPIEIER3 = HWREGH(PIECTRL_BASE + PIE_O_IER3);
    volatile uint16_t tempPIEIER4 = HWREGH(PIECTRL_BASE + PIE_O_IER4);
    volatile uint16_t tempPIEIER5 = HWREGH(PIECTRL_BASE + PIE_O_IER5);
    volatile uint16_t tempPIEIER6 = HWREGH(PIECTRL_BASE + PIE_O_IER6);
    volatile uint16_t tempPIEIER7 = HWREGH(PIECTRL_BASE + PIE_O_IER7);
    volatile uint16_t tempPIEIER8 = HWREGH(PIECTRL_BASE + PIE_O_IER8);
    volatile uint16_t tempPIEIER9 = HWREGH(PIECTRL_BASE + PIE_O_IER9);
    volatile uint16_t tempPIEIER10 = HWREGH(PIECTRL_BASE + PIE_O_IER10);
    volatile uint16_t tempPIEIER11 = HWREGH(PIECTRL_BASE + PIE_O_IER11);
    volatile uint16_t tempPIEIER12 = HWREGH(PIECTRL_BASE + PIE_O_IER12);
    volatile uint16_t tempPIEIFR1 = HWREGH(PIECTRL_BASE + PIE_O_IFR1);
    volatile uint16_t tempPIEIFR2 = HWREGH(PIECTRL_BASE + PIE_O_IFR2);
    volatile uint16_t tempPIEIFR3 = HWREGH(PIECTRL_BASE + PIE_O_IFR3);
    volatile uint16_t tempPIEIFR4 = HWREGH(PIECTRL_BASE + PIE_O_IFR4);
    volatile uint16_t tempPIEIFR5 = HWREGH(PIECTRL_BASE + PIE_O_IFR5);
    volatile uint16_t tempPIEIFR6 = HWREGH(PIECTRL_BASE + PIE_O_IFR6);
    volatile uint16_t tempPIEIFR7 = HWREGH(PIECTRL_BASE + PIE_O_IFR7);
    volatile uint16_t tempPIEIFR8 = HWREGH(PIECTRL_BASE + PIE_O_IFR8);
    volatile uint16_t tempPIEIFR9 = HWREGH(PIECTRL_BASE + PIE_O_IFR9);
    volatile uint16_t tempPIEIFR10 = HWREGH(PIECTRL_BASE + PIE_O_IFR10);
    volatile uint16_t tempPIEIFR11 = HWREGH(PIECTRL_BASE + PIE_O_IFR11);
    volatile uint16_t tempPIEIFR12 = HWREGH(PIECTRL_BASE + PIE_O_IFR12);
    DINT;
    HWREGH(PIECTRL_BASE + PIE_O_IER1) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER2) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER3) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER4) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER5) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER6) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER7) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER8) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER9) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER10) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER11) = 0x00;
    HWREGH(PIECTRL_BASE + PIE_O_IER12) = 0x00;
    CPUTimer_disableInterrupt(TASKA_CPUTIMER_BASE);
    CPUTimer_disableInterrupt(TASKB_CPUTIMER_BASE);
    CPUTimer_disableInterrupt(TASKC_CPUTIMER_BASE);
    uint16_t returnVal =
    STL_CPU_REG_checkCPURegisters(false);
    if (returnVal == STL_CPU_REG_FAIL)
    {

    mcuFault_Status = mcuFault_Status | CPU_REGISTER_FAULT;
    }
    HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER1;
    HWREGH(PIECTRL_BASE + PIE_O_IER2) = tempPIEIER2;
    HWREGH(PIECTRL_BASE + PIE_O_IER3) = tempPIEIER3;
    HWREGH(PIECTRL_BASE + PIE_O_IER4) = tempPIEIER4;
    HWREGH(PIECTRL_BASE + PIE_O_IER5) = tempPIEIER5;
    HWREGH(PIECTRL_BASE + PIE_O_IER6) = tempPIEIER6;
    HWREGH(PIECTRL_BASE + PIE_O_IER7) = tempPIEIER7;
    HWREGH(PIECTRL_BASE + PIE_O_IER8) = tempPIEIER8;
    HWREGH(PIECTRL_BASE + PIE_O_IER9) = tempPIEIER9;
    HWREGH(PIECTRL_BASE + PIE_O_IER10) = tempPIEIER10;
    HWREGH(PIECTRL_BASE + PIE_O_IER11) = tempPIEIER11;
    HWREGH(PIECTRL_BASE + PIE_O_IER12) = tempPIEIER12;
    CPUTimer_enableInterrupt(TASKA_CPUTIMER_BASE);
    CPUTimer_enableInterrupt(TASKB_CPUTIMER_BASE);
    CPUTimer_enableInterrupt(TASKC_CPUTIMER_BASE);
    EINT;

    It is working fine, but I have a question, MCU will be latched if content of IFR restored from temp value. Why

    BR

    HK Woo

  • Hi Whitney

    I checked stl_cpu_reg.asm version 3.3. It is found that there is slightly different from your mail

    Line 234- 235 OK

    Line 263-268 : line 263 is space, should be 264-268. I think that it is ok

    Line 346 -347 : Line 346 is MOV                   IER, @AR0

                              Line 347 is PUSH                  @TH

                              Line 348 is POP                      IFR

    Please confirm

  • It is working fine, but I have a question, MCU will be latched if content of IFR restored from temp value.

    When you say the MCU is being latched, do you mean it's triggering the Interrupt_defaultISR to run like you showed in your earlier screenshot (when you were hitting the ESTOP0)? It seems you're somehow triggering an interrupt that you don't have a valid ISR registered for.

    You may want to double check to make sure you haven't mistakenly enabled any interrupts you aren't using. When you hit that ESTOP0, you can check the PIECTRL register to see which vector was fetched to figure out which interrupt caused the problem.

    I checked stl_cpu_reg.asm version 3.3. It is found that there is slightly different from your mail

    I think I was looking at the version in C2000Ware 4.01.00. The lines numbers aren't important as long as the actual lines of assembly are the same as what I shared. For the last section, there are just 2 lines to remove--"PUSH @TH" and "POP IFR".

    Whitney