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.

RM57L843: Enabling the PBIST test for March13N Single-Port algorithm

Part Number: RM57L843
Other Parts Discussed in Thread: UNIFLASH

I am implementing a series of PBIST tests at startup for my application. I have a function that takes in an ALGO value, as well as the corresponding RINFOL/RINFOU values and runs a test largely based on the `sl_selftest.c` example code from the SafeTI library. I have pasted the code below for reference.

bool run_algorithm(const uint32_t algo,
                const uint32_t rinfol,
                const uint32_t rinfou)
{
        /**
         * Program the GCLK1 to PBIST ROM clock ratio to 1:4 in System Module.
         *      MSTGCR[9:8] = 2
         */
        BF_SET(systemREG1->MSTGCR, 0x2U, 8U, 2U);

        /**
         * Enable PBIST Controller in System Module.
         *      MSINENA[31:0] = 0x00000001
         */
        systemREG1->MSINENA = 0x1U;

        /**
         * Enable the PBIST self-test in System Module.
         *      MSTGCR[3:0] = 0xA
         */
        BF_SET(systemREG1->MSTGCR, 0xAU, 0U, 4U);

        /**
         * Wait for at least 64 VCLK cycles in a software loop.
         */
        const uint64_t wait_end = get_cycles() + 64U;
        while (get_cycles() < wait_end) {
                /* Wait */
        }

        /**
         * Enable the PBIST internal clocks.
         *      PACT = 0x1
         */
        pbistREG->PACT = 0x1U;

        /**
         * Select the Algorithms to be run (refer to Table 2-6).
         *      ALGO = 0x0000000C (select March13N for single-port and two-port RAMs)
         */
        pbistREG->ALGO = algo;
        pbistREG->RINFOL = rinfol;
        pbistREG->RINFOU = rinfou;
        kprintf(0, " > ALGO = 0x%08X\n", pbistREG->ALGO);
        kprintf(0, " > RINFOL = 0x%08X\n", pbistREG->RINFOL);
        kprintf(0, " > RINFOU = 0x%08X\n", pbistREG->RINFOU);

        /**
         * Disable RAM Override.
         *      OVER = 0x0
         */
        pbistREG->OVER = 0x0U;

        /**
         * Select both Algorithm and RAM information from on-chip PBIST ROM.
         *      ROM = 0x3
         */
        pbistREG->ROM = 0x3U;

        /**
         * Configure PBIST to run in ROM Mode and kickoff PBIST test.
         *      DLR = 0x14
         */
        pbistREG->DLR = 0x14U;

        kprintf(0, "DLR 0x%08X\n", pbistREG->DLR);

        /**
         * Wait for PBIST test to complete by polling MSTDONE bit in System Module.
         *      while (MSTDONE !=1)
         */
        while (0x1U != (systemREG1->MSTCGSTAT & 0x1U)) {
                /* Wait */
        }

        /**
         * Once self-test is completed, check the Fail Status register FSRF0.
         *      In case there is a failure (FSRF0 = 1):
         *              a. Read RAMT register that indicates the RGS and RDS values of the failure RAM.
         *              b. Read FSRC0 and FSRC1 registers that contain the failure count.
         *              c. Read FSRA0 and FSRA1 registers that contain the address of first failure.
         *              d. Read FSRDL0 and FSRDL1 registers that contain the failure data.
         *              e. Resume the Test if required using Program Control register (offset = 0x16C) STR = 2.
         *      In case there is no failure (FSRF0 = 0), the Memory self-test is completed.
         *              a. Disable the PBIST internal clocks.
         *                      PACT = 0
         *              b. Disable the PBIST self-test.
         *                      MSTGCR[3:0] = 0x5
         */
        bool test_passed = false;

        kprintf(0,
                        " > [ALGO 0x%X | RINFOL 0x%08X | RINFOU 0x%08X] | ",
                        algo,
                        rinfol,
                        rinfou);
        if (1U == pbistREG->FSRF0) {
                kprintf(0, "FAIL\n");
                kprintf(0, " > RAMT | 0x%08X\n", pbistREG->RAMT);
                uint8_t RGS = (uint8_t)(pbistREG->RAMT >> 24U);
                uint8_t RDS = (uint8_t)(pbistREG->RAMT >> 16U);
                kprintf(0, "   > RGS %d | RDS %d\n", RGS, RDS);
                kprintf(0, " > FSRC0 | 0x%08X\n", pbistREG->FSRC0);
                kprintf(0, " > FSRC1 | 0x%08X\n", pbistREG->FSRC1);
                kprintf(0, " > FSRA0 | 0x%08X\n", pbistREG->FSRA0);
                kprintf(0, " > FSRA1 | 0x%08X\n", pbistREG->FSRA1);
                kprintf(0, " > FSRDL0 | 0x%08X\n", pbistREG->FSRDL0);
                kprintf(0, " > FSRDL1 | 0x%08X\n", pbistREG->FSRDL1);
        } else {
                test_passed = true;
                kprintf(0, "PASS\n");

                /* Cleanup */
                pbistREG->PACT = 0U;
                BF_SET(systemREG1->MSTGCR, 0x5U, 0U, 4U);
        }
        return test_passed;
}                             

For reference, I am calling

run_algorithm(0x1U, 0xFU, 0x0U))
run_algorithm(0x4U, 0x0CFFBFF0U, 0x0U))
run_algorithm(0x8U, 0xF0000000U, 0x18U))

In accordance with Table 2-6 of the TRM, the first two run correctly and pass (0x1U and 0x4U), however when I run the last test (0x8U), the program will either hang indefinitely, or cause a reset. In some cases it locks up the processor and I am no longer able to flash anything using either Uniflash or CCS.

Any help or example code would be much appreciated.

Best,

John King

  • Hello John,

    Your last test is to perform the PBIST to MCU SRAM and caches (Icache, Dcache).

    1. The content in SRAM (including data in stack) will be completely lost. 

    2. If cache memory is selected to be part of the PBIST test then the contents will become incoherent with respect to the level 2 memory after the PBIST test. The cache will need to be invalidated before cache can be enabled for use by the CPU. In addition, if you are using ECC error checking scheme in the cache, you must enable this by programming the CEC bits in the Auxiliary Control Register before invalidating the cache, to ensure that the correct error code bits are calculated when the cache is invalidated. 

  • Hi QJ,

    Thanks for your response.

    1) Does this mean that the MCU will need to reboot? If so what is the procedure for initializing and detecting this type of reboot (such that this test does not run ad infinitum). Before running this test I will have completed several tests using the STC module so the CPURST bit in the SYSESR will not be reliable for this purpose.

    2) To clarify, are these actions that need to happen after the PBIST test completes in order to resume normal execution? Do you have an example for invalidating the cache and programming the CEC bits?

    Best,

    John

  • Hi QJ,

    I attempted to run the following function directly after the while loop wait in line 72 of my original post:

    void invalidate_cache(void)
    {
            asm(" MRC p15, #0, R1, c1, c0, #1");
            asm(" BIC R1, R1, #0x1<<5");
            asm(" MCR p15, #0, R1, c1, c0, #1");
    
            asm(" MRC p15, #0, R1, c1, c0, #0");
            asm(" ORR R1, R1, #0x1<<12");
            asm(" ORR R1, R1, #0x1<<2");
            asm(" DSB");                                                                                                                                                                                                                                                                                                                                          
            asm(" MCR p15, #0, R0, c15, c5, #0");
            asm(" MCR P15, #0, R0, c7, c5, #0");
            asm(" MCR p15, #0, R1, c1, c0, #0");
            asm(" ISB");
    }
    

    This was taken directly from section 9.3.1 in the Tech RM but I am still experiencing the hanging issue where no code after this will run. Do you have any further suggestions?

    Best,

    John

  • Hi John,

    I run the similar PBIST selftest on TMS570LC43x launchpad (PBIST on TMS570LC43x is the same as on RM57Lx), everything works fine:

    1. Run test in startup.c

    2. rinfol= 0xF0000000; rinfou=0x18

  • /* PBIST test on RAMs */
    void PBIST_SelfTest(uint32 raminfoH, uint32 raminfoL, uint32 algomask)
    {
    volatile uint32 i = 0U;

    /* PBIST ROM clock frequency = HCLK frequency /2 */
    /* Disable memory self controller */
    systemREG1->MSTGCR = 0x00000105U;

    /* Disable Memory Initialization controller */
    systemREG1->MINITGCR = 0x5U;

    /* Enable PBIST controller */
    systemREG1->MSINENA = 0x1U;

    /* Enable memory self controller */
    systemREG1->MSTGCR = 0x0000010AU;

    /* wait for 64 VBUS clock cycles at least, based on GCLK to VCLK ratio */
    for (i=0U; i<(32U + (32U * 1U)); i++){ /* Wait */ }

    /* USER CODE BEGIN (18) */
    /* USER CODE END */

    /* Enable PBIST clocks and ROM clock */
    pbistREG->PACT = 0x1U;

    /* Select all algorithms to be tested */
    pbistREG->ALGO = algomask;

    /* Select RAM groups */
    pbistREG->RINFOL = raminfoL;

    /* Select all RAM groups */
    pbistREG->RINFOU = raminfoH;

    /* ROM contents will not override RINFOx settings */
    pbistREG->OVER = 0x0U;

    /* Algorithm code is loaded from ROM */
    pbistREG->ROM = 0x3U;

    /* Start PBIST */
    pbistREG->DLR = 0x14U;

    }

    void pbistStop(void)
    {
    /* USER CODE BEGIN (20) */
    /* USER CODE END */
    /* disable pbist clocks and ROM clock */
    pbistREG->PACT = 0x0U;
    systemREG1->MSTGCR &= 0xFFFFFFF0U;
    systemREG1->MSTGCR |= 0x5U;
    /* USER CODE BEGIN (21) */
    /* USER CODE END */
    }

    boolean pbistIsTestCompleted(void)
    {
    /* USER CODE BEGIN (22) */
    /* USER CODE END */

    return ((systemREG1->MSTCGSTAT & 0x1U) != 0U);
    /* USER CODE BEGIN (23) */
    /* USER CODE END */
    }


    boolean pbistIsTestPassed(void)
    {
    /* USER CODE BEGIN (24) */
    /* USER CODE END */
    boolean status;

    if ((pbistREG->FSRF0 == 0U) && (pbistREG->FSRF0 == 0U))
    {
    status = TRUE;
    }
    else
    {
    status = FALSE;
    }