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.

TMS570 WFI trouble in LBIST

Other Parts Discussed in Thread: TMS570LS1227, HALCOGEN

Hi,

I'm using TMS570LS1227 and I have a strange trouble on the LBIST/STC.

Sometimes, after WFI instruction, the MCU reset doesn't occour and the program flow continue run.

It is strange that sometimes the MCU goes to idle stale and after that the MCU reset occours and sometimes no.

I haven't the debugger connect to MCU.

Best regards,

Enrico

  • Hi Enrico,

    My understanding is that WFI is a hint - nothing guarantees that the CPU will enter the low power state because between executing the WFI and the low power state entry ... there are some cycles needed for housekeeping and an interrupt may come in during these cycles preventing the WFI from actually causing a low power state. I believe if you don't actually enter the low power state the STC LBIST will not begin. Trying to confirm this but please try putting the WFI instruction that you are using to kick off LBIST into a loop.
    Something like:
    SLP WFI
    NOP
    NOP
    B SLP

    If the WFI succeeds you enter LBIST and exit LBIST with a reset so you'll get out of this loop.
    But if the WFI does not succeed, you'll be in the loop and try again so that eventually the LBIST will kick in.

    You can't actually disable all interrupts on this device because the FIQ is an NMI interrupt - so I think this loop is needed.

    Like I said I'll confirm this but please give it a shot and let me know if it resolves the issue for you.

    Best Regards,
    Anthony
  • Hi Anthony,

    I tried to put the WFI instruction into a loop but the issue doesn't fixed.

    The HCLK (system clock) is 20Mhz, is it too slow? And STCCLK is 20Mhz, also.

    Best Regards,

    Enrico

  • Hi Enrico,

    it should not be an issue to run at 20MHz.

    Maybe you can send me your code - this is a pretty difficult problem to diagnose I think without the code.
  • Hi Anthony,

    Here my code:
    -------------------------------------------------
    taskENTER_CRITICAL();

    /* execute the test */
    stcSelfTestConfig.stcClockDiv = 0u; /* STC Clock divider = 1 */
    stcSelfTestConfig.intervalCount = 24u; /* No. of interval = 24 */
    stcSelfTestConfig.restartInterval0 = TRUE; /* Start from interval 0 */
    stcSelfTestConfig.timeoutCounter = 0xfffffffful; /* Timeout counter */

    /* do lock step test and mark it*/
    myFaultInjected = 0x12345678u;

    /* store the MPU configuration */
    SS_SLS_StoreMPUConfiguration();

    /* save the core register set */
    _CoreRegisterSetSave_( &myCoreRegisterSet[0] );

    /* save the stacks of the banked registers */
    _CoreBankRegisterSetSave_( &myCoreRegisterSet[16] );

    SL_SelfTest_STC( STC_RUN, TRUE, &stcSelfTestConfig );

    /* here, after reset */

    /* restore mode and IRQ */
    SS_SLS_RestoreMPUConfiguration();

    myFaultInjected = 0x00000000u;

    /* restore stack pointers */
    _CoreBankRegisterSetRestore_( &myCoreRegisterSet[16] );

    /* switch back to System Mode */
    __asm( " cps #0x1F" );

    /* enable the interrupts again, because they have been disabled by the test */
    taskEXIT_CRITICAL();
    ---------------------------------------------------
    boolean SL_SelfTest_STC(register SL_SelfTestType testType, register boolean bMode, register SL_STC_Config * config)
    {
    register uint32 tempVal;
    boolean retval = FALSE;

    tempVal = 0U;

    /* Configure the clock divider */
    sl_systemREG2->STCCLKDIV = ((config->stcClockDiv & 0x07u) << 24);

    /* Configure the interval count & restart/continue */
    tempVal = 0U;
    tempVal |= ((uint32)config->intervalCount << STC_STCGCR0_INTCOUNT_START);
    if (TRUE == config->restartInterval0) {
    tempVal |= STC_STCGCR0_RS_CNT;
    }

    sl_stcREG->STCGCR0 = tempVal;

    /* If in compare selfcheck (fault injection) mode then setup STCSCSCR */
    if (STC_COMPARE_SELFCHECK == testType) {
    sl_stcREG->STCSCSCR = (uint32)(STC_STCSCSCR_FAULT_INS|STC_STCSCSCR_SELF_CHECK_KEY);
    }

    /* Setup the timeout value */
    sl_stcREG->STCTPR = config->timeoutCounter;

    /* Enable STC run */
    sl_stcREG->STCGCR1 = STC_STCGCR1_STC_ENA;

    for (tempVal=0u; tempVal<32u; tempVal++) {
    }

    #if 0
    /* Kick off the STC execution */
    _SL_Kickoff_STC_execution();
    #endif

    for(;;)
    {
    asm(" WFI");

    asm(" nop");
    asm(" nop");
    asm(" nop");
    asm(" nop");
    }
    }
    ---------------------------------------------------
    #pragma CODE_STATE(_c_int00, 32)
    #pragma INTERRUPT(_c_int00, RESET)
    #pragma WEAK(_c_int00)
    void _c_int00(void)
    {
    SL_Init_R4Registers();
    SL_Init_StackPointers();

    tFaultToInject = ( *( volatile uint32_t * )ADDR_APPLICATION_FINJECT );

    if ( systemREG1->SYSESR & 0x20U )
    {
    /* Clear CPU RST bit in Exception Status Register in Sys module */
    systemREG1->SYSESR = 0x20U;

    /* Check if an STC test has been executed by the application.
    * If that is the case then restore the core register set and continue the application
    * behind the STC run time test call. */
    if( 0x12345678u == tFaultToInject )
    {
    /* the restore ensures that the FW can continue after the STC test */
    _CoreRegisterSetRestore_( &myCoreRegisterSet[ 0 ] );

    /* !!! the code never ends here because the application is continued */
    for ( ;; )
    {
    ;
    }
    }
    }

    Best Regards,

    Enrico
  • Hi Enrico,

    It is possible for you to send .out file for the project as well - so we can take a look on hardware.

    Thanks and Best Regards,
    Anthony
  • Also - to confirm - you are not seeing the code execute *past* the WFI with this change - correct? It at least always stays in the for(;;) loop?
  • Hi Anthony,

    Yes, I confirm that the code stays in the for loop. I have attached the out file.

    Best reagrds,

    Enrico

    0550.S81-F7011_APPLICATION.zip

  • Hi Enrico,

    First thing I wanted to check was the disassembly - just to make sure the machine code is as expected.

    I disassembled S81-FF011_APPLICATION.out by using the command armdis --all S81-F7011_APPLICATION.out > disass.txt

    When I search disass.txt though, the only WFI instruction that I see is in a function that is:
    0449cc: _gotoCPUIdle_:
    0449cc: E320F003 WFI
    0449d0: E1A00000 MOV R0, R0
    0449d4: E1A00000 MOV R0, R0
    0449d8: E1A00000 MOV R0, R0
    0449dc: E1A00000 MOV R0, R0
    0449e0: E12FFF1E BX R14

    And it's only called from 4 places, none of them seem to be in a loop.

    I thought I would look for your function above to see what code was generated, but searching for 'SL_SelfTest_STC' in the disassembly file comes up empty.

    Wondering if you could take a look at this - and let me know what address range that the function should be in.

    It almost looks like this may be different code - especially if you've seen the CPU get stuck in the WFI loop..
  • Hi Anthony,

    please, can you verify with this file attached?

    I think that I have found the issue. The interrupts are disabled before of STC test, but some interrupt events can occour and their flags will be set, so the CPU exit from standby state.

    I captured the 'Pending Interrupt Read Location Register 0, 1, 2 and 3' registers values, in two places, first place is after the disable interrupt instruction and the second place is before the WFI instruction. I noticed that the test isn't executed if the interrupt flag is set before the WFI instruction. For example:

    The test is executed with values of register 0,1,2 and 3 (addr: FFFF FE20h, FFFF FE24h, FFFF FE28h, FFFF FE2Ch)

    place1-> 0x00000000 0x00000000 0x00200000 0x00000000
    place2-> 0x00000000 0x00000000 0x00200000 0x00000000

    and the test isn't executed with the following values:

    place1-> 0x00000000 0x00000000 0x00200000 0x00000000
    place2-> 0x00000004 0x00000000 0x00200000 0x00000000

    Can you confirm this interpretation?

    Best regards,

    Enrico

    6445.S81-F7011_APPLICATION.zip

  • Hi Enrico,

    What format is the attached file? I tried to disassemble it again but I don't think it's an EABI ELF file.
  • Hi Anthony,

    the file attached was in binary format. Now, I have attached the file in EABI ELF format.

    I apologize for the confusion.

    Best regards,

    Enrico

    2845.S81-F7011_APPLICATION.zip

  • Hi Anthony,

    the previous file attached was in binary format, now I have attached the 6646.S81-F7011_APPLICATION.zipfile in EABI ELF format.

    I apologize for the confusion.

    Best Regards,

    Enrico

  • Hi Anthony,
    I have tried to attached the file in the EABI ELF format but the post is not posted.

    Best Regards,
    Enrico
  • Hi Enrico,

    Ok, I can see the disassembly of the loop with WFI in the SL_SelfTest_STC routine now.

    0126a0: $C$L121:
    0126a0: E320F003 WFI
    0126a4: E1A00000 MOV R0, R0
    0126a8: E1A00000 MOV R0, R0
    0126ac: E1A00000 MOV R0, R0
    0126b0: E1A00000 MOV R0, R0
    0126b4: EAFFFFF9 B $C$L121 [0x126a0]
    0126b8: 01A00000 MOVEQ R0, R0
    0126bc: 01A00000 MOVEQ R0, R0

    ...

    did not see it in the previous eabi dissassembly.

    will see if I can get to this on hardware now.

    Best Regards
    Anthony
  • Hi Enrico,

    Ok I tried just downloading your code into an LS1227 CNCD and running it, with breakpoints on both of the WFI instructions (one at 0x030360 from the STC library function, and one at 0x0126a0 from the snip above). I don't see the code hitting either. Is there something that I should do to trigger the self test to run? [like drive a pin or poke a value into RAM]?
  • Hi Anthony,

    the software executes some hardware checks and, if a test fails, the software enter in safe state. In this state the software executes a infinite loop.

    I have removed the entry into the safe state and I I have attached the new output file.

    Best regards

    Enrico

    8233.S81-F7011_APPLICATION.zip

  • Hi Enrico,

    Two Questions with this latest image:

    Q1. I keep getting stuck inside the ecmpInit() function. I think I am probably still missing some stimulus. After the second call to ecmpIfGetRegister with parameter 0xB, it looks to see if the return value is '7' and this always fails. I'm not sure what the source code is intending here. If you could explain that would be a big help.
    I am running this code on a TMS570LS1227 which I think you are but we should confirm that.

    Q2. I only see 2 WFI instructions in this code, one from the safety library:
    030390: _SL_Kickoff_STC_execution:
    030390: .arm
    030390: E320F003 WFI
    030394: E12FFF1E BX

    and one from halcogen for idle purposes.

    I assume you are going to use the WFI above inside _SL_Kicioff_STC_execution for entry into the LBIST but want to confirm. This WFI doesn't appear to be in any sort of loop.

    EDIT:  I should add that this board is using a 16MHz crystal for the clock input.  If you have a custom board with a different crystal - i wonder if anything that is senstive to the crystal freq is causing a problem.  So it would be good to know your crystal freq. too.


    Thanks and Best Regards,
    Anthony

  • Hi Anthony,

    Firstly I confirm that the MCU is TMS570LS1227 and my board uses a 16MHz crystal for the clock input.

    Q1. The MCU is connected to  TPS65381 by SPI and the software, at boot time, verify the TPS state ('7' correspond to diagnostic state).

    I think that will be difficult to run the software on the other board becuase there will be another points that the software will match to the hardware.

    Q2. I delete the for(;;) loop because it doesn't resolve the "wfi" issue

    I will try to re-insert the for(;;) loop and to delete evert hardware dipendance, if this will be useful. Can you tell me?

    Can you confirm the interpretation posted here ?

    Best Regards,

    Enrico

  • Hi Enrico,

    Ok I understand Q1 - just wondering if this is something you can also comment out.  But after a point commenting things out may remove the problem we are trying to figure out anyway...

    I am using the TI 1227 CNCD which also has the TPS65381 on it.  I don't know if you are using a TI board or a different one.

    Earlier I think you mentioned that you had interrupts enabled and this was preventing you from the WFI.     How did you disable interrupts (through CPSR or through VIM?)

    There is something interesting in the Arm architecture manual that may be a clue:

    When a processor issues a WFI instruction it can suspend execution and enter a low-power state. It can remain
    in that state until the processor detects a reset or one of the following WFI wake-up events:
    • an IRQ interrupt, regardless of the value of the CPSR.I bit
    • an FIQ interrupt, regardless of the value of the CPSR.F bit

    So you would need to actually use the VIM to disable the interrupt requests I think to avoid perpetually skipping the WFI.  If you just disable interrupts through the CPU according to the above you may not get the interrupt but you will get the WFI wakeup.

    EDIT:  I should say that the above makes sense if you are using WFI in the generic way - which is to reduce power in an IDLE loop until there is something to do...   But in this case the WFI is being used to trigger LBIST which is very different.    So you may need to disable interrupts in VIM in the '_SL_Kickoff_STC_execution' funciton - but you would not want to do the same in the '_gotoCPUIdle_'  function which is intended to enter a low power state.

  • Enrico,

    You may also want to check e2e.ti.com/.../1719099

    This is because two of the VIM channels are hard-wired to always be enabled, and if there is an ESM error then you actually have to clear the ESM error flag in order to enter the Standby state.

    You are using a different chip - which doesn't have the errata DEVICE #56 - so it's not likely that it is the same ESM error but any ESM group 1 or 2 error would be suspect.
  • Hi Enrico,

    Just wanted to follow up and see if there is an issue here or if you got your issue resolved.