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