This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

write to NRF_UICR->CUSTOMER when SD is enabled

Hi there,

We're trying to write to the UICR CUSTOMER register to store some of the manufacturer info, such as BLE MAC address, for example.

When SD isn't running we have the following code working:

NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
uint32_t cust0 = data[0];
cust0 |= data[1] << 8;
cust0 |= data[2] << 16;
cust0 |= data[3] << 24;
uint32_t cust1 = data[4];
cust1 |= data[5] << 8;
NRF_UICR->CUSTOMER[0] = cust0;
NRF_UICR->CUSTOMER[1] = cust1;
NRF_NVMC->CONFIG      = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}

Now, when the SD is running this method would not work and throw  SOFTDEVICE: INVALID MEMORY ACCESS

We tried using following

uint32_t cust0 = data[3];
cust0 |= data[2] << 8;
cust0 |= data[1] << 16;
cust0 |= data[0] << 24;
uint32_t cust1 = 0xFFFFFFFF;
cust1 |= data[4] << 16;
cust1 |= data[5] << 24;

sd_protected_register_write(&NRF_UICR->CUSTOMER[0], cust0);
sd_protected_register_write(&NRF_UICR->CUSTOMER[1], cust1);

also, instead of sd_protected_register_write tried using  sd_flash_write

But it simply doesn't work, in both cases. When I try to read the data from the UICR I get nothing

$ nrfjprog -f nrf52 --memrd 0x10001080 --w 32 --n 8
0x10001080: FFFFFFFF FFFFFFFF                     |........|

How to write to UICR when the SD is running. I also want to be able to write multiple times if necessary.

Thanks you,
Oleg

Parents
  • Hi

    How to write to UICR when the SD is running. I also want to be able to write multiple times if necessary.

     The short answer is that it's not possible. You would have to disable the Softdevice to be able to write to the UICR. 

    regards

    Jared 

  • Do I need to use nrf_sdh_enable_request and nrf_sdh_disable_request to temporarily disable it?

    Also, regarding writing multiple times to the UICR. How would I erase the UICR->CUSTOMER region, or perhaps erasing the whole UICR region? I don't think UICR is page aligned, so calling sd_flash_page_erase probably won't be a good idea.

    (I tried using using NRF_NVMC->ERASEUICR = 1 and it didn't work. I've read that using ERASEALL =1 could help, but would it erase the application as well, or only the UICR?)

Reply
  • Do I need to use nrf_sdh_enable_request and nrf_sdh_disable_request to temporarily disable it?

    Also, regarding writing multiple times to the UICR. How would I erase the UICR->CUSTOMER region, or perhaps erasing the whole UICR region? I don't think UICR is page aligned, so calling sd_flash_page_erase probably won't be a good idea.

    (I tried using using NRF_NVMC->ERASEUICR = 1 and it didn't work. I've read that using ERASEALL =1 could help, but would it erase the application as well, or only the UICR?)

Children
  • Oleg Z said:
    Do I need to use nrf_sdh_enable_request and nrf_sdh_disable_request to temporarily disable it

     Yes that would be proper way to do it.

     

    Oleg Z said:

    Also, regarding writing multiple times to the UICR. How would I erase the UICR->CUSTOMER region, or perhaps erasing the whole UICR region? I don't think UICR is page aligned, so calling sd_flash_page_erase probably won't be a good idea.

    (I tried using using NRF_NVMC->ERASEUICR = 1 and it didn't work. I've read that using ERASEALL =1 could help, but would it erase the application as well, or only the UICR?)

    Your assumption regarding erase all is correct. Did you remember to set the NVMC in write mode first?  

        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    
        NRF_NVMC->ERASEUICR = 1 
        
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}

Related