Hello,
For our product, we wish to store a custom post-production name (essentially a serial number) in the UICR registers of the nRF52840. We understand that this can only be done once (without erasing the Flash), and have put in the necessary precautions to ensure that this is only done once.
But our issue stems from what happens after initially writing to it. We write to the registers, and then attempt a NVIC_SoftReset(). This does successfully write to the UICR registers, however the NVIC_SoftReset hangs our system. The only way to make it functional again is to either power-cycle the whole board, or to initiate a POR by having another co-processor on the board triggering the reset line. After doing so, the UICR registers can be read just fine and our post-production serial number can be found just as expected. We'd like to keep this functionality, but remove the need for a hard POR reset (a simple NVIC_SoftReset() or similar would be ideal).
We are running a slightly modified version of theble_peripheral ble_app_uart project, within SDK 16.0.0 and SoftDevice S140 7.0.1. We also have the secure_bootloader running, however we see this exact same behaviour whether the bootloader is present or not, so we believe that this is irrelevant. None of the flash addresses or similar have been modified.
Below is the code snippet that we use to write to the UICR registers.
nrf_sdh_disable_request();
const uint32_t *nameAsInts = (uint32_t*)name;
const uint32_t numInts = (strlen(name) + 4) / 4;
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
for (int i=0; i<numInts; i++)
NRF_UICR->CUSTOMER[i] = nameAsInts[i];
strncpy(NRF_UICR->CUSTOMER, name, sizeof(device_name));
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
NVIC_SystemReset();
while(1) {};
When ran in Debug mode, we see that the app crashes on call address 0x0000.0A60, which is a simple ldr r3, [pc, #4] instruction. This call happens sometime after strncpy() is called, but before the final while (NRF_NVMC->READY == NVMC_READY_READY_Busy) line .
Cheers,
Tyrel K