TMS320F280039: HWBIST and interrupt

Part Number: TMS320F280039

Background Introduction:
1)The system uses interrupt sources including DMA_CH1/DCANA_0/DCANA_1/TIMER2.
2)DMA_CH1 is a 50µs control interrupt; TIMER2 is a 1ms OS interrupt; DCANA_0 is a CAN error and status interrupt; DCANA_1 is a CAN mailbox communication interrupt.
3)The underlying layer is configured and generated using SysCfg, employing an interrupt nesting scheme. The interrupt nesting priority follows the default TI priority settings without any modifications.
4)The product must comply with IEC60730 Class B requirements, therefore HWBIST-related code must be added.

Issues:
1)STL_HWBIST_runMicro() is called within the control interrupt (50µs).
2)When performing HWBIST detection, a spurious interrupt for TIMER2 is triggered. Referring to the forum issue: tms320f280025-spurious-interrupts-after-hwbist-test. The TIMER2 ISR was modified as follows: clear the TIMER2 TIF bit immediately upon entering the TIMER2 interrupt handler. After this change, TIMER2 enters normally every 1ms.
3)After running for some time, it was observed that the control interrupt (DMA_CH1) and OS interrupt (TIMER2) can both enter normally, but the CAN1 interrupt cannot enter. If STL_HWBIST_runMicro() is disabled in the control interrupt, the issue of CAN1 interrupt not entering does not occur.

  • Can you tell if it's specifically happening when the CAN interrupt is triggered during the HWBIST? Can you see the CAN interrupt flags getting set in the registers (both in the CAN and in the PIE)?

    Whitney

  • During HWBIST micro testing, it is not convenient to connect a debugger. Therefore, observing related registers/variables during testing is not very convenient for me.

    1) Below is 50us DMA control ISR code for test.

    __interrupt void INT_BswDma_DMA1_ADCACH0_6_ISR(void)
    {
        //
        // Save IER register on stack
        //
        volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER7);
    
        //
        // Set the global and group priority to allow CPU interrupts
        // with higher priority
        //
        IER |= M_INT7;
        IER &= MINT7;
        HWREGH(PIECTRL_BASE + PIE_O_IER7) &= MG7_1;
    
        //
        // Enable Interrupts
        //
        Interrupt_clearACKGroup(0xFFFFU);
        __asm("  NOP");
        EINT;
    
        //
        // Insert ISR Code here ..
        //
        GvUtility_TestData_U[0].u32data++;
        STL_HWBIST_runMicro();
    
        //
        // Disable interrupts and restore registers saved:
        //
        DINT;
        HWREGH(PIECTRL_BASE + PIE_O_IER7) = tempPIEIER;
    }

    2)Below is the CAN receive interrupt ISR Code.

    __interrupt void INT_BswCan_CANA_1_ISR(void)
    {
        //
        // Save IER register on stack
        //
        volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER9);
    
        //
        // Set the global and group priority to allow CPU interrupts
        // with higher priority
        //
        IER |= M_INT9;
        IER &= MINT9;
        HWREGH(PIECTRL_BASE + PIE_O_IER9) &= MG9_6;
    
        //
        // Enable Interrupts
        //
        Interrupt_clearACKGroup(0xFFFFU);
        __asm("  NOP");
        EINT;
    
        //
        // Insert ISR Code here ..
        //
    
        BswCan_MsgCallback();
    
        //
        // Disable interrupts and restore registers saved:
        //
        DINT;
        HWREGH(PIECTRL_BASE + PIE_O_IER9) = tempPIEIER;
    
        #ifdef TRACE_ISR_ENABLE
            //
            //  Add ISR to Trace
            //
            traceISR[traceISRIndex % TRACE_SIZE] = 0x0906;
            traceISRIndex++;
        #endif
    }

    3)I have done some tests as follows:

    When a CAN communication exception occurs, PIE_IER9 is normal, but PIE_IFR9 is continuously set. I suspect this may be related to the CPU-level IER register.

  • Thanks for your patience. Have you been able to do any additional debugging? I know HWBIST can make debugging challenging. Do you have some IOs that you could toggle in your ISRs or before and after running HWBIST to try to figure out the behavior seems to be related to interrupt nesting or if it specifically happens when an interrupt occurs during the HWBIST micro run? That could give us some hints about what may be happening.

    I don't see anything concerning in your ISRs. I'm thinking about your comment--"PIE_IER9 is normal, but PIE_IFR9 is continuously set." PIEIFR9 being set but the interrupt not being triggered could either be caused by an issue of the PIEACK not being reset after the last group 9 interrupt or either the CPU IER or INTM not be enabled. PIEIFR is supposed to get cleared when the CPU fetches the ISR vector from the PIE.

    Whitney

  • I apologize for the delayed response due to the Chinese Spring Festival holiday.

    The following are the further tests I have conducted so far:
    1)When calling the function STL_HWBIST_runMicro within a 1ms task, the issue of being unable to enter the CAN interrupt was not reproduced.
    2)When calling the function STL_HWBIST_runMicro within a 20kHz control interrupt, the issue of being unable to enter the CAN interrupt occurs.
    3)Based on test 2, I attempted to clear the ACK flag using Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9). This allowed re-entry into the CAN interrupt, but after running for a while, the issue reappeared.
    4)Based on test 2, I attempted to enable the IER using Interrupt_enable(INT_CANA1), but it had no effect, and the issue of being unable to enter the CAN interrupt could not be resolved.

    Additional questions:
    1)Our product application is a bidirectional DC converter that needs to meet IEC60730 Class B requirements. Would you recommend calling the function STL_HWBIST_runMicro within a 20kHz control interrupt, or within a background slow task (1ms/10ms)?
    2)Does the function STL_HWBIST_runMicro need to be called continuously, or can it be stopped once the coverage test is complete and it returns STL_HWBIST_BIST_DONE?

  • Could you tell me if there is any new information on this issue?

  • . Would you recommend calling the function STL_HWBIST_runMicro within a 20kHz control interrupt, or within a background slow task (1ms/10ms)?

    I'm not sure if the standard has a particular requirement for this or if you need to decide for your own system. Do you have a requirement of how frequently your full set of tests need to be repeated? Recall the STl_HWBIST_runMicro is doing a single micro run and that it needs to be run 750 times to reach its maximum amount of diagnostic coverage.

    2)Does the function STL_HWBIST_runMicro need to be called continuously, or can it be stopped once the coverage test is complete and it returns STL_HWBIST_BIST_DONE?

    I think you'd want to run it continuously normally--meaning run it until it returns STL_HWBIST_BIST_DONE, reinitialize it, and repeat. However, class B requirements for CPU testing don't necessarily need HWBIST. We have devices without HWBIST that meet the class B requirements by performing a software test of the CPU registers using the SDL's STL_CPU_REG module and an additional PC counter test, so you could consider doing that as a periodic test instead of HWBIST.

    Whitney

  • 1.We are using a closed-loop control system, and I believe it would be better to perform the call during the high-speed control interrupt for the following reasons:
    1.1)It enables faster fault diagnosis.
    1.2)Since HWBIST requires suspending interrupt execution, performing it within the control interrupt ensures a stable control frequency, whereas running it in the background might cause control frequency jitter.
    2.I am aware of the relevant references, but STL_CPU_REG requires testing the CPU/FPU/VCRC, etc. I could execute one of these diagnostics each time an interrupt is triggered. However, the time required to run STL_CPU_REG_checkCPURegisters is longer than that for STL_HWBIST_runMicro. Choosing STL_HWBIST_runMicro is more advantageous given the limited execution time within my interrupt.

    3.Regarding this issue, I suspect it may be related to the clearing of PIE flags during interrupt nesting. I will find time to conduct further tests on this later. By analogy with the handling of timer interrupts 1/2 mentioned in my initial question on this topic, is there a specific code-based solution that allows calling STL_HWBIST_runMicro within the control interrupt without affecting the clearing of flags for other interrupts?