Example code to write to UICR

I am trying to store data to the UICR using SDK16, mesh SDK 4.2.0 and the nRF52840 chip.

I want to write to the UICR once on runtime and never again. To avoid messing with the softdevice, I am trying to write to the UICR before calling ble_stack_init() and after __LOG_INIT to get logs working.

This is the code:

NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}

uint32_t * consumer0 = (uint32_t *) 0x10001080;
*consumer0 = 0x00000005;

NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "%d\n", *consumer0);

NVIC_SystemReset();

So we put the NVMC in Write enable, wait for it to be ready, write to consumer0, put it in Read enable, wait for it to be ready and reset the device. I can see 5 logged to Segger console.

Then I comment what I don't need:

//NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
//while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}

uint32_t * consumer0 = (uint32_t *) 0x10001080;
//*consumer0 = 0x00000005;

//NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
//while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "%d\n", *consumer0);

//NVIC_SystemReset();

And I see -1 logged to Segger console, meaning the flash still has the 0xFFFF on that position. I can confirm it on Segger Memory explorer that 10001080 is never filled with the data I wanted. Am I doing something wrong?

  • Hi Thorsrud,

    The code snippet you have seems to match QDAAB0, which has the improved access port mechanism (IN-149).

    Can I use the same code snippet with other Soc version e.g. QDAAA0?

    Also, when I use nRF Programmer v2.3.3 to flash the same debug version of the firmware merged.hex the UICR content gets erased. However, when I use SES Nordic Edition v5.60 to flash the same debug version merged.hex the content of the UICR is preserved.

    Note, when using nRF Programmer only the 'Erase & write' option is available. The 'Write' only option is disabled, see attached screen shot below.

    Thank you.

    Kind regards
    Mohamed
  • Regarding my statement:

    write to flash can only reset bits.
    It is necessary to erase flash to set it to FFFFFFF

    The second part is NOT correct!

    Unfortunately 

    NRFJPROG incorrectly requires it see:

    nrfjprog---memwr-0x10001080---val-0x01010101-shouldn-t-fail-second-time

    In fact you could use a "counter" (up to 31) by repeatedly clearing bits.
    counter =1: 7FFFFFF,  counter=2:3FFFFFFF, counter=3 :1FFFFFFF, =4:0FFFFFFF ... =30:00000003, 31:00000001 with no intervening erasures. 


    ++++++++++++++

    You can use nrfjprog 

    --sectorerase

     to only erase the area that is being programmed which can preserve UCIR.

  • Yes, that is correct. Writing to flash can only flip bits from '1' to '0'. This is an inherent property of flash technology and applies to all flash memory (not just on Nordic products).

    To change bits from '0' to '1' you need to erase the page.

  • Learner said:
    Can I use the same code snippet with other Soc version e.g. QDAAA0?

    If you refer to the code snippet to write to flash, then yes. Writing to flash (including the UICR) is the same for all revisions. (As mentioned deleting the UICR page is special though, as it can only be done with a full chip erase).

    Learner said:
    Also, when I use nRF Programmer v2.3.3 to flash the same debug version of the firmware merged.hex the UICR content gets erased. However, when I use SES Nordic Edition v5.60 to flash the same debug version merged.hex the content of the UICR is preserved.

    The nRF Connect Programmer version >= 2.0.0 unfortunately always does an erase on write, and this is a full chip erase and not a sector erase (erasing only sectors to be writtne to). This has been reported, but is unfortunately the case at the moment. So you must use another tool in order to program without erasing the whole chip (including the UICR). A simple tool for this is nrfjprog.

  • Hi Thorsrud,

    Thank you for your support.

    The nRF Connect Programmer version >= 2.0.0 unfortunately always does an erase on write, and this is a full chip erase and not a sector erase (erasing only sectors to be writtne to).

    Unfortunately, this is what we were planning to use. It looks like we will have to go to plan B.

    A simple tool for this is nrfjprog.

    nrfjprog is plan B. I have never used it before. I have now downloaded v10.15.

    nrfjprog version: 10.15.4 external
    JLinkARM.dll version: 7.58b

    I have read the documentation but I am still not sure how to use 'sectorerase'. I would like to use the following command line to flash our firmware using nrfjprog and avoiding to erase UICR,

    nrfjprog -f NRF52 --program merged.hex –-sectorerase <????>

    Thank you for your help.

    Kind regards
    Mohamed

Related