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

Best method for writing to UICR during production

Please note that I am a new developer.

I am currently testing on a nRF52 DK on Windows.

I want to flash my application (which has a SoftDevice) and also write manufacturing information such as serial number to the UICR (customer reserved) registers.

I have tried using the method described in the UICR Config Example where Keil uVision is modified to write to UICR. This method works, but is not desirable. I want to use a Flasher ATE (JLink flash programmer) to flash each of my devices during production.

I have seen in some threads that it is possible to write to the UICR using nrfjprog as such:

nrfjprog --memwr 0x10001304 --val 0x00000000

Is the best method to use nrfjprog and write to each individual UICR address and then to flash the application and SoftDevice? Or perhaps it is more efficient to produce a single .hex file (using mergehex) where UICR registers are already written.

My question is: what is the most efficient way to write to the UICR registers during production?

Thanks for any help!

  • Based on new knowledge I`ll try to answer my own question. I will keep this thread here as future reference.

    Writing to UICR via Flasher ATE (during manufacturing):

    When using Flasher ATE during product manufacturing, it is possible to use a command called "#AUTO PATCH". As described in the Flasher ATE User Guide. The Flasher ATE will be connected to a PC using either RS232 or telnet interface. It is then possible to issue commands using J-Link software.

    From the Flasher ATE User Guide: A file called "Patches.txt" can be placed on the ATE module. Each line in the Patches.txt file can hold up to four patches, each being maximum 32 bytes in length. The number in "Serial.txt" refer to which line number in Patches.txt which will be used for the current cycle. Each cycle can refer to a single device which currently is being programmed. Alternatively it is possible to do single patching (no cycling) if there is only one device. The single patch command looks like this:

    #AUTO <module> PATCH <NumPatches>,<Addr>,<NumBytes>:<Data>

    For example:

    #AUTO 0 PATCH 1,10001080,4:12345678

    Here 10001080 refer to the CUSTOMER[0] UICR register address. 4 is the number of bytes in the data, and 12345678 is the data (e.g. the serial number of the device).

    Edit:

    As stated by greenlava below, in order to write to UICR using the ATE Flasher, these memory addresses should be filled with empty dummy data in the .hex file. The ATE Flasher fails to write to addresses which exceeds addresses included in the .hex file. Therefor, the .hex file should be padded with dummy data.

  • Creating separate .hex file containing UICR data:

    I initially also wanted to find out how to create .hex files which contain UICR data. This .hex file can then be merged with the application .hex file (using Nordic`s mergehex executable) before flashing. As Terje has stated (in a comment below), this is not the most efficient method for writing to the UICR registers.

    To make a separate HEX file containing the UICR data, we can use a HEX editor such as FlexHEX. Then simply write the desired data (such as serial number) into the editor. Note that when we read from the chip, the order of bytes will be reversed. The example below will for example be displayed as 0xEFBEADDE (and not 0xDEADBEEF).

    When saving the file, FlexHEX will export it as a binary file. Then we can use a program like SRecord to convert the binary file to a HEX file. Here we determine the offset of the data. The offset of the CUSTOMER[0] register is 0x1080 (hex) which is 4224 in decimal.

    srec_cat uicr.bin -binary -offset=4224 -o uicr.hex -intel -obs=16

    After this, Nordic`s mergehex executable can be used to merge the uicr.hex file with the application .hex file. The mergehex executable is part og the nRF Command Line Tools.

    mergehex -m application.hex uicr.hex -o output.hex

    It is (as stated in other threads) important to erase the flash stored on the device before flashing UICR:

    nrfjprog --family nRF52 --eraseall
    nrfjprog --program output.hex -f NRF52

    After flashing we can verify that there is data in the CUSTOMER[0] register using nrfjprog:

    nrfjprog -f NRF52 --memrd 0x10001080 --n 4

  • Hi,

    I see that you have already answered most of your question yourself. I do not have experience with what you describe in your answer, but I do have some input regarding your original question.

    I would rather use nrfjprog (or, if applicable, the approach that you describe,) than to generate a separate hexfile for each device.

    I would also make sure that the serial number gets written last. The reason is that some of the UICR fields may be used by an application (such as a DFU bootloader), and it is not unusual that the first step of programming a hex file onto the device is to erase all affected flash pages. In other words, existing UICR contents may get erased as part of the hex file programming.

    Regards,
    Terje

  • Thanks a lot for your input, Terje. That is very useful information.

  • Hi there:

        I'm trying to do exactly what you're referring to here, but I'm having trouble pulling it all together and verifying the contents of CUSTOMER[0] after I apply the AUTO PATCH.  I'm having trouble verifying the correct data  is written with a

    #READ <module> 10001080,4

    Did you end up having success with this?

Related