NRF5340: Read FICR.DEVICEADDR and set BLE MAC random address

Hi all,

NRF5340
NRF Connect 2.6.0

We would like to perform the following operations on the NRF5340:
* Read FICR.DEVICEADDR (BLE random MAC is also fine).
* Set the BLE address with type random.

Seems the FICR.DEVICEADDR is only accessible by the network core, which AFAIK is not documented anywhere in the PS. So need to call bt_enable first to get the random MAC address either via bt_id_get or bt_read_static_addr.

However, using bt_id_create after BLE has been started does not apply the new MAC address for BLE comms. There seems to be a workaround for setting the public address at runtime, but this doesn't work for random. The HCI command returns SUCCESS though.
devzone.nordicsemi.com/.../setting-nrf5340-public-ble-address

Is there a solution for this specific use case?

Parents Reply Children
  • Figuring this out is taking a hit longer than expected, but I am still on  it

  • Already tried that as mentioned in the original post. Didn't work.

  • I tried the stuff in that post on our BLE UART Central sample.

    Here is what I changed:

    diff --git a/samples/bluetooth/central_uart/src/main.c b/samples/bluetooth/central_uart/src/main.c
    index 756b8d136..9a7ea5002 100644
    --- a/samples/bluetooth/central_uart/src/main.c
    +++ b/samples/bluetooth/central_uart/src/main.c
    @@ -17,6 +17,7 @@
     
     #include <zephyr/bluetooth/bluetooth.h>
     #include <zephyr/bluetooth/hci.h>
    +#include <zephyr/bluetooth/hci_vs.h>
     #include <zephyr/bluetooth/conn.h>
     #include <zephyr/bluetooth/uuid.h>
     #include <zephyr/bluetooth/gatt.h>
    @@ -548,6 +549,28 @@ static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
     	.pairing_failed = pairing_failed
     };
     
    +
    +
    +void ble_set_mac(bt_addr_t* addr)
    +{
    +	struct net_buf *buf;
    +	int rc;
    +
    +	buf = bt_hci_cmd_create(BT_HCI_OP_VS_WRITE_BD_ADDR, sizeof(*addr));
    +	if (!buf) {
    +		LOG_ERR("failed to create buffer [%d]", -ENOBUFS);
    +	}
    +
    +	net_buf_add_mem(buf, addr, sizeof(*addr));
    +
    +	rc = bt_hci_cmd_send_sync(BT_HCI_OP_VS_WRITE_BD_ADDR, buf, NULL);
    +	if (rc) {
    +		LOG_ERR("failed to set BT address [%d]", rc);
    +	}
    +}
    +
    +
    +
     int main(void)
     {
     	int err;
    @@ -570,6 +593,20 @@ int main(void)
     		return 0;
     	}
     	LOG_INF("Bluetooth initialized");
    +/* check for public address in UICR.OPT area */
    +
    +  LOG_INF("setting public address retrieved from UICR");
    +
    +  bt_addr_t addr;
    +
    +  addr.val[0] = 2;
    +  addr.val[1] = 2;
    +  addr.val[2] = 2;
    +  addr.val[3] = 2;
    +  addr.val[4] = 2;
    +  addr.val[5] = 2;
    +  ble_set_mac(&addr);
    +
     
     	if (IS_ENABLED(CONFIG_SETTINGS)) {
     		settings_load();
    

    And here is the logs from the peripheral UART sample from before and after connecting to the central

    Could you also test this with these samples on your side?

  • I've managed to change the MAC address with the code snippet you provided. It seems I was missing CONFIG_BT_SETTINGS earlier.

    However, when CONFIG_BT_SETTINGS is enabled, Calling bt_id_get after bt_enable and before ble_set_mac returns id count of 0. How would I get the actual random address?

Related