In this blog, I would describe the UICR region and how to use it in details.

It covers the following topic:

  • Memory Layout (Address) of the UICR
  • Registers in UICR (and each functionality)
  • How to write / read / erase on the UICR by using the nrfjprog
  • Dump flash / ram / registers

Memory Layout

The user information configuration registers (UICRs) are non-volatile memory (NVM) registers for configuring
user specific settings.

Memory Layout on nRF52832 QFAA
Memory layout of NRF52840

Registers in UICR (and each functionality)

Region of UICRRegisterDescription
0x00 – 0x14Reserved
0x14 – 0x80NRFFW[0] – NRFHW[14]Reserved for Nordic Firmware Design
0x50 – 0x80NRFHW[0] – NRFHW[11]Reserved for Nordic Firmware Design
0x80 – 0x100CUSTOMER[0] – CUSTOMER[31]Reserved for customer
0x200 PSELRESET[0] Mapping of the nRESET function
0x204PSELRESET[1] Mapping of the nRESET function
0x208APPROTECT Access Port protection
0x20CNFCPINS Setting of pins dedicated to NFC functionality: NFC antenna or GPIO
0x210DEBUGCTRL (nRF52840 only)Processor debug control
0x304REGOUT0 (nRF52840 only) GPIO reference voltage / external output supply voltage in high voltage mode

Reference Schematic of nRF52832 QFAA

P.021 is used for the HW Reset Pin or GPIO.

It is configured by the UICR Register (PSELRESET[0] and PSELRESET[1]).

In the SDK, compile switch (CONFIG_GPIO_AS_PINRESET) is used for this.

Access Port protection

If the UICR register APPPROTECT is set to 0xFF (default disable), the AHB-AP is connected to the debugger bus. Otherwise, it is disconnected (APPPROTECT = 0x00).

If you would like to recover (after enabling the APPPROTECT), there are 3 different approaches.

  1. Use nrfjprog.exe -f NRF52 –recover
  2. Use nrfjprog.dll function recover() or use the pynrfjprog recover()
  3. Manually, a) write 1 to register 0x4 of debug access port 1, b) read register 0x8 of debug access port until its value is 0, c) write 0 to register 0x4 of debug access port 1, d) write 1 to register 0x0 of debug access port 1, e) write 0 to register 0 of debug access port 1.

NFC on the NRF52832 / NRF52840

GPIO 9 / 10 can be used for the NFC tag.

By configuring the UICR Register NFCPINS as below.

Debug control (nRF52840 only), It is used for advanced PCU debug feature and flash patch.

  • ETM(Embedded Trace Macrocell)
  • ITM(Instrumentation Trace Macrocell)

ITM means you can create a debug channel for sending messages from your code to the debugger.

ETM means that the chip hardware can stream out step-by-step how it walks through the instruction stream. There is heavy data compression involved so it basically just informs the debugger with “y”, “n”, “n”, “y” if it takes jumps or not.
This means the debugger on the PC can recreate a virtual copy of the instruction sequence the processor performs.

So you can look back in time and evaluate the instruction sequence that led the program into a specific state.

This is a big advantage if you need to solve issues with magically hanging software, programs making unexpected jumps, getting stuck in interrupt service routines etc.

So ETM is very good when your program performs unexpected crash-and-burn magic.
And ITM is good for getting some trace output of the performance of your business logic “config saved”, “motor started”, “user intervention timeout”, …

You pay extra for a ULINKpro just because it gives an additional professional feature intending to cut down debug times when something is really off and you can’t just rely on single-stepping through the program. Single-stepping doesn’t work well in a real-time system where the external hardware doesn’t stop the time just because you want to stop the time in the debugger.

So ETM is in some ways a flight data recorder (black box) crash protected memory. Expensive but valuable.

Regulator OUT 0 (nRF52840 only)

How to write / read / erase on the UICR by using the nrfjprog

nRF5x Command Line Tools

The nRF5x Command Line Tools are used for developing, programming, and debugging of Nordic Semiconductor’s nRF5x SoCs (System on Chip).

The nRF5x Command Line Tools consist of the following components:

  • nrfjprog executable: The nrfjprog executable is a command line tool for programming nRF5x Series SoCs through SEGGER J-Link programmers and debuggers.
  • mergehex executable: The mergehex executable is a command line utility that enables you to combine up to three HEX files into a single file.
  • nrfjprog DLL: The nrfjprog DLL is a Dynamic-Link Library that exports functions for programming and controlling Nordic Semiconductor nRF5x Series SoCs. It lets developers create their own development tools for Nordic Semiconductor nRF5x SoCs using the DLLs API.
  • SEGGER J-Link software and documentation pack (included only in the Windows installer).

Nordic provides the command line (nRF Command line tool) to configure the nRF5 / nRF91 Series. The user manual is located at .

Dump the hex from the device

  • Dump entire flash such as 512KB flash from nRF52832
  • Dump the UICR region from nRF52

The hex file can be viewed by J-Flash tool as below,

Bootloader Starting address (difference from OLD SDK). It is not stored at the UICR 0x10001014.

Starting address of bootloader at nRF52840 (SDK15.3) is 0xF1000

Read the specify address through nrfjprog tool

read the address 0x10001080 (with 32 bytes data) , show in word (32 bits) format

Write data on the address through nrfjprog

Read the registers

Erase the UICR region

Change the MAC address on nRF52 and store it inside the UICR region

Example code to get / set the MAC address (remember to set the address type also)

void get_MAC_address_with_HEX(char * str_MAC)
    ble_gap_addr_t		addr;
    uint32_t err_code = sd_ble_gap_addr_get( &addr);
    sprintf(str_MAC,"%02X%02X%02X%02X%02X%02X", \
    NRF_LOG_INFO("MAC ADDRESS: %02X,%02X,%02X,%02X,%02X,%02X!", \

void change_MAC_address( ble_gap_addr_t	addr)
    addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
    uint32_t err_code = sd_ble_gap_addr_set( &addr );

for example,

Register Location

The 6-byte BLE Radio MAC address is stored in the nRF51822 UICR at NRF_UICR_BASE+0x80 LSB first.

NRF_UICR + 0x80 (0x10001080): MAC_Addr [0] (0xC0)
NRF_UICR + 0x81 (0x10001081): MAC_Addr [1] (0xYY)
NRF_UICR + 0x82 (0x10001082): MAC_Addr [2] (0xXX)
NRF_UICR + 0x83 (0x10001083): MAC_Addr [3] (0x93)
NRF_UICR + 0x84 (0x10001084): MAC_Addr [4] (0x54)
NRF_UICR + 0x85 (0x10001085): MAC_Addr [5] (0xDD)

Using the MAC address

To have the radio use this stored MAC address you need to read it from the UICR and pass the address to


If you do not call sd_ble_gap_addr_set(), the radio will use a random public MAC address, stored in the FICR. Please refer to Nordic’s SoftDevice documentation and SDK regarding the use of the sd_ble_gap_addr_set() function.

Reprogramming the MAC address

Use a J-Link interface with the savebin and loadbin commands.  These can be included in a script.

  • //save the MAC from UICR + 0x80
    savebin mac_addr.bin 0x10001080 8 // memory reads must be in 4-byte increments
  • //restore the MAC from the file and program to UICR + 0x80
    loadbin mac_addr.bin 0x10001080

Here are the code as example

If you like this blog, would you give me a “like” for appreciation?

Thanks for your interests on my blog. Since 2019, I have created this blog and shared the idea how to do some funny stuffs. I am very pleasure that I get quite a lot of positive feedback. I really hope that this blog helps your own embedded solution development. May I get support from you to keep it in order to maintain the wordpress host service? Your appreciation would be very helpful.