Following up the post (Description of UICR on NRF52 series) https://jimmywongbluetooth.wordpress.com/2019/08/19/manufacturer-storage-data-on-uicr-region/, I would like to describe how to use the UICR to store the custom BLE address, Device Name and Device ID in this blog.
For example, as below table, there are list of the devices to have such configuration.
Device Number # | Device ID (8 bytes) 0x10001080 – 0x10001087 NRF_UICR->CUSTOMER[0] NRF_UICR->CUSTOMER[1] | Address (6 bytes) 0x10001088 – 0x1000108F NRF_UICR->CUSTOMER[2] NRF_UICR->CUSTOMER[3] | Device Name (11 bytes) 0x10001090 – 0x1000109B NRF_UICR->CUSTOMER[4] NRF_UICR->CUSTOMER[5] NRF_UICR->CUSTOMER[6] |
1 | FC000000 00000001 | FF00 00000001 | DEVICE_00001 |
2 | FC000000 00000002 | FF00 00000002 | DEVICE_00002 |
3 | FC000000 00000003 | FF00 00000003 | DEVICE_00003 |

@REM Erase the UICR region
nrfjprog –family NRF52 –eraseuicr
@REM DEVICE ID
nrfjprog –family NRF52 –memwr 0x10001080 –val 0x00000001
nrfjprog –family NRF52 –memwr 0x10001084 –val 0xFC000000
@REM DEVICE MAC ADDRESS
nrfjprog –family NRF52 –memwr 0x10001088 –val 0x00000001
nrfjprog –family NRF52 –memwr 0x1000108C –val 0x0000FF00
@REM DEVICE NAME
nrfjprog –family NRF52 –memwr 0x10001090 –val 0x30303031
nrfjprog –family NRF52 –memwr 0x10001094 –val 0x43455630
nrfjprog –family NRF52 –memwr 0x10001098 –val 0x44454549
#define MAX_LEN_DEVICE_ID 8
#define MAX_LEN_DEVICE_NAME 12
static void load_device_setting(void)
{
ret_code_t ret_code;
// Check if not written
uint8_t empty_addr[MAX_LEN_DEVICE_NAME];
memset(empty_addr, 0xff, MAX_LEN_DEVICE_NAME);
ble_gap_addr_t gap_addr;
gap_addr.addr_id_peer = 0;
gap_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
/* Read the Device ID (8 bytes) from UICR Memory */
uint8_t* ptr_device_id = (uint8_t*)&NRF_UICR->CUSTOMER[0];
if(memcmp(ptr_device_id, empty_addr, MAX_LEN_DEVICE_ID))
{
memcpy(m_manufacturer_specific_target_device_id, ptr_device_id, MAX_LEN_DEVICE_ID);
NRF_LOG_INFO("Device ID");
NRF_LOG_HEXDUMP_INFO(m_manufacturer_specific_target_device_id, MAX_LEN_DEVICE_ID);
}
/* Read the Bluetooth Address from UICR Memory */
// Get BD address from UICR memory
uint8_t* ptr = (uint8_t*)&NRF_UICR->CUSTOMER[2];
if(!memcmp(ptr, empty_addr, BLE_GAP_ADDR_LEN))
{
NRF_LOG_WARNING("No BD address in flash, using chip default");
ret_code = sd_ble_gap_addr_get(&gap_addr);
APP_ERROR_CHECK(ret_code);
NRF_LOG_HEXDUMP_INFO(&gap_addr.addr, 6);
}
else
{
memcpy(&gap_addr.addr, ptr, BLE_GAP_ADDR_LEN);
NRF_LOG_INFO("GAP Address");
NRF_LOG_HEXDUMP_INFO(&gap_addr.addr, 6);
}
/* Read the Device Name 12 bytes) from UICR Memory */
uint8_t* ptr_device_name = (uint8_t*)&NRF_UICR->CUSTOMER[4];
if(memcmp(ptr_device_name, empty_addr, MAX_LEN_DEVICE_NAME))
{
memcpy(m_device_name, ptr_device_name, MAX_LEN_DEVICE_NAME);
NRF_LOG_INFO("Device Name");
NRF_LOG_HEXDUMP_INFO(m_device_name, MAX_LEN_DEVICE_NAME);
}
NRF_LOG_INFO("Setting bd address to: %02X:%02X:%02X:%02X:%02X:%02X",
gap_addr.addr[5],
gap_addr.addr[4],
gap_addr.addr[3],
gap_addr.addr[2],
gap_addr.addr[1],
gap_addr.addr[0]);
ret_code = sd_ble_gap_addr_set(&gap_addr);
APP_ERROR_CHECK(ret_code);
}
I’m not that much of a online reader to be honest but your blogs really nice, keep it up! I’ll go ahead and bookmark your site to come back down the road. Cheers
LikeLike
Hi jimmy
How can I read what I just recorded, that is, how do I check that the address, name and ID were recorded correctly?
LikeLike
You can use the nrfjprog – – memrd 0x10001000 – – w 8 – – n 256 to read them from UICR address
LikeLike