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