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.

TMS570LS1114: , ECAP IRQ cannot enter again.

Part Number: TMS570LS1114
Other Parts Discussed in Thread: HALCOGEN

Hi:

    The mcu is TMS570LS1114, the current design 

vimREG->FIRQPR0 = 0x00000003;vimREG->FIRQPR1 = 0x00000000;vimREG->FIRQPR2 = 0x00000000;vimREG->FIRQPR3 = 0x00000000;

vimREG->REQMASKSET0 = 0x03;vimREG->REQMASKSET1 = 0x00;vimREG->REQMASKSET2 = 0x00;

vimREG->REQMASKSET3 = (1u<<11u);    /*ECAP4 interrupt*/

In fact system, ECAP4 has real pulse input, then ECAP4 interrupt is ok. At the same time ,the mcu_self_test is working .   After a few hours running, the system report VIM_PRTY , VIM_CRC64 error,

after the error, the system cannot go into ECAP4 interrupt. Then I check core register CPSR I=0(IRQ is allowed) F=0(FIQ is allowed), and i check eCAP4 register , ECFLG=0x0003(Interrupt flag is ok), ECEINT=0x0002(Interrupt enable is ok), TSCTR is running, CAP1 is running.

but the system cannot enter ecap4 interrupt again. Why? How can i debug? How can i avoid this happen?  I think the condition is interrupt conflict.

  • Hello,

    What is the value of VIM ADDERR register? The ADDERR register stores the address of the first parity error location, and it's value will never be reset by the power reset and other reset sources.

    but the system cannot enter ecap4 interrupt again. Why? How can i debug? How can i avoid this happen? 

    If Parity error occurs, the Interrupt Vector Table will be bypassed. The resulting vector of any IRQ/FRQ interrupt is then the value contained in the FBPARERR register until this bit has been cleared.

    Did you program the VIM FBPARERR register? You can use this ISR to clear the PARFLG to restore the integrity of the VIM INT vector table. 

  • Thank your reply!

    I will study this part. 

  • sys_vim.c

    func void viminit(void)

    {

        VIM_PARCTL = 0xAU;

        VIM_FBPARERR = (uint32)&vimParityErrorHandler;

        。。。

    }

    #pragma CODE_STATE(vimParityErrorHandler, 32)
    #pragma INTERRUPT(vimParityErrorHandler, IRQ)
    #pragma WEAK(vimParityErrorHandler)

    /* SourceId : VIM_SourceId_006 */
    /* DesignId : VIM_DesignId_006 */
    /* Requirements : HL_SR105 */

    func void vimParityErrorHandler(void)

    {

        。。。。

    }

    I have seen this func. But i don't know which channel vector i can assign for it.

    static const t_isrFuncPTR s_vim_init[128U]=

    {

        &phantomInterrupt,

        &esm_high_intr_handler,            /* Channel 0 */

        .......&vimParityErrorHandler,     /* channel ? */

        &ecap4Interrupt,            /* Channel 107 */

    }

    you know ecap4interrupt will cause irq, then program will jump to 

    #pragma CODE_STATE(ecap4Interrupt, 32)
    #pragma INTERRUPT(ecap4Interrupt, IRQ)

    /* SourceId : ECAP_SourceId_035 */
    /* DesignId : ECAP_DesignId_021 */
    /* Requirements : HL_ECAP_SR15 */
    void ecap4Interrupt(void)

  • But i don't know which channel vector i can assign for it.

    You don't need to map this fallback routine to a VIM channel. It is just a temporary substitute of the ISR which has a parity error.

    VIM parity error occurs when an interrupt occurs and CPU tries to fetch the corresponding ISR address and finds a parity error in the VIM RAM location. The ISR address register (IRQVECREG) in VIM is automatically updated with the fallback address and the PC branches to this address.

    The fallback routine handler needs to do the following:

    1. Clear the parity error in the VIM RAM. You can re-write the ISR address in the VIM RAM so that the parity error gets clear

    2. Update the IRQVECREG or FIQVECREG by reading those two registers or disabling/enabling interrupt. Once you come out of the fallback routine (parity handler), IRQVECREG and FIQVECREG will not get updated with the correct ISR address (Even though you rewrote the  address in the VIM RAM). The register will still hold the fallback address. 

  • hi,

    1、 In debug mode, i can see program has entered vimParityErrorHandler.

    2、In this interrupt,you can see the fuction call vimInit(), in vimInit, vimRAM->ISR[] have been re-writed.

    3、I want to update IRQVECREG or FIQVECREG by reading those two registers, so you can see

          u32lv_irqvecreg = vimREG->IRQVECREG;
          u32lv_fiqvecreg = vimREG->FIQVECREG;

        but IRQVECREG or FIQVECREG do not change.  then i check CPSR_I ,this bit has been set to 1, and return to 0. disabling/enabling interrupt

        IRQVECREG=FBPARERR=(uint32)&vimParityErrorHandler; still

        FIQVECREG=&phantomInterrupt

       So ecap interrupt can not be entered again.

    Thanks for your reply, i think i know a little. I want more help. Thanks!

    #pragma CODE_STATE(vimParityErrorHandler, 32)
    #pragma INTERRUPT(vimParityErrorHandler, IRQ)
    #pragma WEAK(vimParityErrorHandler)

    /* SourceId : VIM_SourceId_006 */
    /* DesignId : VIM_DesignId_006 */
    /* Requirements : HL_SR105 */
    void vimParityErrorHandler(void)
    {
    uint32 vec;
    uint32_t u32lv_irqvecreg;
    uint32_t u32lv_fiqvecreg;

    /* Identify the corrupted address */
    uint32 error_addr = VIM_ADDERR;

    /* Identify the channel number */
    uint32 error_channel = ((error_addr & 0x1FFU) >> 2U);

    /* Correct the corrupted location */
    vimRAM->ISR[error_channel] = s_vim_init[error_channel];

    /* Clear Parity Error Flag */
    VIM_PARFLG = 1U;

    /* Disable and enable the highest priority pending channel */
    if (vimREG->FIQINDEX != 0U)
    {
    vec = vimREG->FIQINDEX - 1U;
    }
    else
    {
    /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Read 32 bit volatile register" */
    vec = vimREG->IRQINDEX - 1U;
    }
    if(vec == 0U)
    {
    vimREG->INTREQ0 = 1U;
    vec = esmREG->IOFFHR - 1U;

    if (vec < 32U)
    {
    esmREG->SR1[0U] = (uint32)1U << vec;
    esmGroup1Notification(vec);
    }
    else if (vec < 64U)
    {
    esmREG->SR1[1U] = (uint32)1U << (vec-32U);
    esmGroup2Notification(vec-32U);
    }
    else if (vec < 96U)
    {
    esmREG->SR4[0U] = (uint32)1U << (vec-64U);
    esmGroup1Notification(vec-32U);
    }
    else
    {
    esmREG->SR4[1U] = (uint32)1U << (vec-96U);
    esmGroup2Notification(vec-64U);
    }
    }
    else if (vec < 32U)
    {
    vimREG->REQMASKCLR0 = (uint32)1U << vec;
    vimREG->REQMASKSET0 = (uint32)1U << vec;
    }
    else if (vec < 64U)
    {
    vimREG->REQMASKCLR1 = (uint32)1U << (vec-32U);
    vimREG->REQMASKSET1 = (uint32)1U << (vec-32U);
    }
    else if(vec < 96U)
    {
    vimREG->REQMASKCLR2 = (uint32)1U << (vec-64U);
    vimREG->REQMASKSET2 = (uint32)1U << (vec-64U);
    }
    else
    {
    vimREG->REQMASKCLR3 = (uint32)1U << (vec-96U);
    vimREG->REQMASKSET3 = (uint32)1U << (vec-96U);
    }

    u32lv_irqvecreg = vimREG->IRQVECREG;
    u32lv_fiqvecreg = vimREG->FIQVECREG;
    vimInit();
    }

  • Hi QJ,

    May I have your follow up update for this issue troubleshooting? Any further information need, please let me know. Thanks for the support.

    Best Regards,

    Tess Chen

  • hello, i still don't resolve this problem.

    But i know this vimParityError , which is cause by my program.

    When the program is doing check_vim(), then when ecap frequently interrupt, then cause this problem.

    I found "

    /* Disable esm interrupt generation */
    esmREG->IECR1 = GET_ESM_BIT_NUM(ESM_G1ERR_VIM_PARITY_CORRERR);
    u32lv_tmp = esmREG->IECR1 ;
    /* Disable esm error influence */
    esmREG->DEPAPR1 = GET_ESM_BIT_NUM(ESM_G1ERR_VIM_PARITY_CORRERR);"

    takes no effect.

    I want to how to disable esm vim_parity error.

    I want help, thank you!

    The below is program: FYI

    /* Backup PCR register */
    u32lv_vimparctl_bk = REG_VIM_PARCTL;
    /*Backup grp1 esm interrupt enable register */
    u32lv_bak_reg_IESR1 = esmREG->IESR1;
    u32lv_bak_reg_EEPAPR1 = esmREG->EEPAPR1;
    /* Disable esm interrupt generation */
    esmREG->IECR1 = GET_ESM_BIT_NUM(ESM_G1ERR_VIM_PARITY_CORRERR);
    u32lv_tmp = esmREG->IECR1 ;
    /* Disable esm error influence */
    esmREG->DEPAPR1 = GET_ESM_BIT_NUM(ESM_G1ERR_VIM_PARITY_CORRERR);
    /* Enable parity test mode */
    BIT_SET(REG_VIM_PARCTL, VIM_TEST_MODE);
    /* Flip a bit in VIM RAM parity location */
    BIT_FLIP(REG_VIMRAMPARLOC, 0x1U);
    /* Disable parity test mode */
    BIT_CLEAR(REG_VIM_PARCTL, VIM_TEST_MODE);
    /* Cause parity error */
    u32lv_vimramread = REG_VIMRAMLOC;

    /* Check if ESM group1 channel 15 is not flagged */
    u32lv_tmp = esmREG->SR1[0U] & GET_ESM_BIT_NUM(ESM_G1ERR_VIM_PARITY_CORRERR);
    if (((REG_VIM_PARFLG & VIM_PAR_ERR_FLG) == 0U) ||
    (u32lv_tmp == 0U))
    {
    /* VIM RAM parity error was not flagged to ESM. */
    b8lv_err_vim_prty_test = BTRUE;
    }
    else
    {
    /* verify erronous address */
    if(REG_VIM_ADDERR == VAL_VIMRAMLOC)
    {
    b8lv_err_vim_prty_test = BFALSE;
    }
    else
    {
    b8lv_err_vim_prty_test = BTRUE;
    }
    }

    /* clear VIM parity error flag in VIM */
    BIT_SET(REG_VIM_PARFLG, VIM_PAR_ERR_FLG);
    /* clear ESM group1 channel 15 flag */
    esmREG->SR1[0U] = GET_ESM_BIT_NUM(ESM_G1ERR_VIM_PARITY_CORRERR);
    /* Enable parity test mode */
    BIT_SET(REG_VIM_PARCTL, VIM_TEST_MODE);
    /* Revert back to correct parity */
    BIT_FLIP(REG_VIMRAMPARLOC, 0x1U);
    /* Restrore Parity Control register */
    REG_VIM_PARCTL = u32lv_vimparctl_bk;
    /* Restore ESM registers states */
    esmREG->IESR1 = u32lv_bak_reg_IESR1;
    esmREG->EEPAPR1 = u32lv_bak_reg_EEPAPR1;

  • Hi,

    Did you use the vimParityCheck() generated by HALCoGen? This function should clear the error flag.

  • My program is similar as vimParityCheck() generated by HALCoGen. 

    I discard my program , and use vimParityCheck( sys_selftest.c ) generated by HALCoGen. It also apear program will cause vimParityErrorHandler, then ecap4 interrupt cannot enter again.

    When there is no interrupt at ecap4 pin, the vimParityCheck program is ok , the program will not enter into vimParityErrorHandler. But when i cause interrupt at ecap4 pin, the program will enter in vimParityErrorHandler.

    I want to find a method which mask vimParityErrorHandler when i use vimParityCheck .

  • While performing vimParityCheck, the interrupt should not be enabled. After the vimParityCheck, the flipped bit of VIM parity value (at 0xFFF82400) is corrected.

  • Hi,

        I think I have found the mechod. Thanks for your online help.

        A few days , I disabled the interrupt by 

        _disable_interrupt_();

       vimParityCheck();

       _enable_interrupt_();

       But this not enough, so the test failed.

        Today, follow your instruction, I also disable ecap4 interrupt

         _disable_interrupt_();
        ecapREG4->ECCTL2 &= (uint16)~(uint16)0x0010U; /* ecapStopCounter(ecapREG4);*/
        ecapREG4->ECEINT = 0x0000U; /* ecapDisableInterrupt(ecapREG4,ecapInt_CEVT1);*/
        ecapREG4->TSCTR= 0u ;
        vimParityCheck();
        /** - Set interrupt enable */
        ecapREG4->ECCLR = 0xffu;
        ecapInit();
        _enable_interrupt_();

         Then result is exciting, the program will not enter vimParityErrorHandler  again.

          Yesterday night, I think i will change a method.  Why i do not vimParityCheck in ecap4 interrupt? So I try this morning. Yes , the test is success also.

           This method is better than disable interrupt. I will use this method , vimparitycheck in ISR. 

           If you have any sugestion , you can reply.

          Thanks and best regard!

           zsm/20220415