nRF5340 - setting public bt address

Hello,

Still on my custom nRF5340 board for a Bluetooth LE peripheral application (building environment: NCS 2.2.0, Zephyr 3.2.99).
The net core is populated with the Zephyr HCI RPMsg sample LE Controller as it is.
I don't want to change it if possible.

The problem is how to move from working random address to public address for advertising ?
I've found a couple of functions around, namely bt_ctlr_set_public_addr() and sdc_hci_cmd_vs_zephyr_write_bd_addr(). However, for a reason or another things mess up.

To start clean, and depending on my case of use, can anyone pass a recipe in terms of

1. API name
2. prj.conf configs
3. include file(s)

Thank you very much

  • I've solved as follows, strongly inspired to link

    #include <zephyr/bluetooth/hci_vs.h>
    
    static char bt_mac_buf[BT_ADDR_LE_STR_LEN];
    
    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 ble_init(void)
    {
    	bt_enable(NULL);
    
    	/* check for public address in UICR.OPT area */
    	if(NRF_UICR->OTP[0] != 0xffffffff && \
    			NRF_UICR->OTP[1] != 0xffffffff) {
    		LOG_INF("setting public address retrieved from UICR");
    		bt_addr_t addr;
    		uint8_t tmp[BT_ADDR_SIZE];
    		int i;
    		memcpy(&tmp[0], (uint8_t *)&NRF_UICR->OTP[0], BT_ADDR_SIZE);
    		for (i=0; i < BT_ADDR_SIZE; i++) {
    			addr.val[i] = tmp[BT_ADDR_SIZE - i -1];
    		}
    
    		ble_set_mac(&addr);
    
    	} else {
    		LOG_INF("going to set random static address");
    	}
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    }
    

Related