how to erase UICR on nrf52832 from the code (not from nrfjprog)

I want to update some data stored in UICR CUSTOMER area on an nrf52832.

Code to do this works fine, as long as the areas are already erased (0xFFFFFFFF).

However, if they have already had a value written, and I want to update it, I understand I need to erase the UICR area first as its flash.

My process is

- copy out the non-CUSTOMER registers, to save them

- enable erase in the NVMC CONFIG

- ask the NVMC to erase by writing 1 to ERASEUICR register

- enable writing

- write back the saved registers

- go back to read mode

(and then do my usual writing code)

However, as soon as I start the process the MCU hangs (no logs, no crash, just hung).

Here is my code : I never see any of the logs probably coz the UART doesn't manage to get the bytes out!

static void _erase_uicr() {
    // Preserve nordic registers. Note RESERVED fields can be ignored
    uint32_t nrffw[15];
    uint32_t nrfhw[12];
    uint32_t pselreset0;
    uint32_t pselreset1;
    uint32_t approtect;
    uint32_t nfcpins;
    log_info("ERASE UICR");

    for (int i=0;i<15;i++) {
        nrffw[i] = NRF_UICR->NRFFW[i];
    }
    for (int i=0;i<12;i++) {
        nrfhw[i] = NRF_UICR->NRFHW[i];
    }
    approtect = NRF_UICR->APPROTECT;
    pselreset0 = NRF_UICR->PSELRESET[0];
    pselreset1 = NRF_UICR->PSELRESET[1];
    nfcpins = NRF_UICR->NFCPINS;
    log_info("SAVED UICR info");
    // Enable erasing
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;      // erase enabled
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    log_info("ENABLED ERASE UICR");
    // Must erase UICR first
    NRF_NVMC->ERASEUICR = 0x00000001;
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    log_info("ERASED UICR");
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;      // write enabled
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    log_info("ENABLED WRITE UICR");
    // Write back the copies
    for (int i=0;i<15;i++) {
        NRF_UICR->NRFFW[i] = nrffw[i];
    }
    for (int i=0;i<12;i++) {
        NRF_UICR->NRFHW[i] = nrfhw[i];
    }
    NRF_UICR->APPROTECT = approtect;
    NRF_UICR->PSELRESET[0] = pselreset0;
    NRF_UICR->PSELRESET[1] = pselreset1;
    NRF_UICR->NFCPINS = nfcpins;

    log_info("REWROTE NON-CUSTOMER UICR");

    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;      // RO
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    log_info("BACK TO RO UICR");

}

Any ideas what I'm doing wrong?

Thanks

Parents Reply Children
Related