Re: STM32WB55 BLE address

Marcio Montenegro

Hello Erwan,

My code didn't work:
( hard coded ble address not the final version )
I checked STM32 ble app and on p2rsrv app  they send ACI_HAL_WRITE_CONFIG_DATA  just after hci reset.
Best regards,

Bluetooth init failed (err -5)
[00:00:00.163,000] <err> hci_ipm: Err send sync
[00:00:00.163,000] <err> bt_hci_core: HCI driver open failed (-5)

struct aci_set_ble_addr {
u8_t cmd;
u8_t config_offset;
u8_t length;
u8_t value[6];


static int wr_bd_addr (void)
struct aci_set_ble_addr *param;
struct net_buf *buf, *rsp;
int err;

buf = bt_hci_cmd_create(ACI_HAL_WRITE_CONFIG_DATA, sizeof(*param));
if (!buf) {
BT_ERR("Err buf");
return -ENOBUFS;
param = net_buf_add(buf, sizeof(*param));
param->cmd = 0x0C;
param->config_offset = CONFIG_DATA_PUBADDR_OFFSET;
param->length = 6;
param->value[0] = 0x57;
param->value[1] = 0x67;
param->value[2] = 0x00;
param->value[3] = 0x26;
param->value[4] = 0xe1;
param->value[5] = 0x80;

err = bt_hci_cmd_send_sync(ACI_HAL_WRITE_CONFIG_DATA, buf, &rsp);

if (err) {
BT_ERR("Err send sync");
return err;
return 0;
static int bt_ipm_ble_init(void)
struct aci_set_tx_power *param;
struct net_buf *buf, *rsp;
int err;

/* Send HCI_RESET */
err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, &rsp);
if (err) {
return err;
/* TDB: Something to do on reset complete? */

    err = wr_bd_addr();
if (err) {
return err;

buf = bt_hci_cmd_create(ACI_WRITE_SET_TX_POWER_LEVEL, 3);
if (!buf) {
return -ENOBUFS;
param = net_buf_add(buf, sizeof(*param));
param->cmd = 0x0F;
param->value[0] = 0x18;
param->value[1] = 0x01;

err = bt_hci_cmd_send_sync(ACI_WRITE_SET_TX_POWER_LEVEL, buf, &rsp);
if (err) {
return err;

return 0;

STM32 BLE application code:
static void Ble_Hci_Gap_Gatt_Init(void){

  uint8_t role;
  uint8_t index;
  uint16_t gap_service_handle, gap_dev_name_char_handle, gap_appearance_char_handle;
  const uint8_t *bd_addr;
  uint32_t srd_bd_addr[2];
  uint16_t appearance[1] = { BLE_CFG_GAP_APPEARANCE };

   * Initialize HCI layer
  /*HCI Reset to synchronise BLE Stack*/

   * Write the BD Address

  bd_addr = BleGetBdAddress();
                            (uint8_t*) bd_addr);

  /* BLE MAC in ADV Packet */
  manuf_data[ sizeof(manuf_data)-6] = bd_addr[5];
  manuf_data[ sizeof(manuf_data)-5] = bd_addr[4];
  manuf_data[ sizeof(manuf_data)-4] = bd_addr[3];
  manuf_data[ sizeof(manuf_data)-3] = bd_addr[2];
  manuf_data[ sizeof(manuf_data)-2] = bd_addr[1];
  manuf_data[ sizeof(manuf_data)-1] = bd_addr[0];
   * Static random Address
   * The two upper bits shall be set to 1
   * The lowest 32bits is read from the UDN to differentiate between devices
   * The RNG may be used to provide a random number on each power on
  srd_bd_addr[1] =  0x0000ED6E;
  srd_bd_addr[0] =  LL_FLASH_GetUDN( );
  aci_hal_write_config_data( CONFIG_DATA_RANDOM_ADDRESS_OFFSET, CONFIG_DATA_RANDOM_ADDRESS_LEN, (uint8_t*)srd_bd_addr );

   * Write Identity root key used to derive LTK and CSRK
    aci_hal_write_config_data( CONFIG_DATA_IR_OFFSET, CONFIG_DATA_IR_LEN, (uint8_t*)BLE_CFG_IR_VALUE );
   * Write Encryption root key used to derive LTK and CSRK
    aci_hal_write_config_data( CONFIG_DATA_ER_OFFSET, CONFIG_DATA_ER_LEN, (uint8_t*)BLE_CFG_ER_VALUE );

   * Set TX Power to 0dBm.
  aci_hal_set_tx_power_level(1, CFG_TX_POWER);

   * Initialize GATT interface

On Tue, Aug 13, 2019 at 9:17 AM Marcio Montenegro via Lists.Zephyrproject.Org <> wrote:
Awesome, thanks!

On Tue, Aug 13, 2019 at 9:13 AM Erwan Gouriou <erwan.gouriou@...> wrote:
Hi Marcio,

Setting of public address based on flash registers should be done as part of controller init in hci driver.
In function bt_ipm_ble_init in drivers/bluetooth/hci/ipm_stm32wb.c

It should be done by sending a custom command to the controller (ACI_HAL_WRITE_CONFIG_DATA), which will provide the address that you can get by the piece of code you mentionned.
This proprietary command is described in following application note:

Hope it helps

On Thu, 8 Aug 2019 at 20:29, Marcio Montenegro <mtuxpe@...> wrote:
Hello Rob,
I got the error below:
undefined reference to `bt_ctlr_set_public_addr'

Yes I included <bluetooth/controller.h>
I don't know if any config is missing and how public BLE address is assigned for this board.

My prj.conf:


Anyway I can connect to nrf connect and ST BLE sensor android app.
The battery service is working.
Now I am finishing a custom service.
Best regards,

On Wed, Aug 7, 2019 at 2:21 PM Marcio Montenegro via Lists.Zephyrproject.Org <> wrote:
Thanks, I'll check it out. 

On Wed, Aug 7, 2019, 13:57 Rob Weber <rob@...> wrote:

On Tue, Aug 06, 2019 at 11:26:59AM -0300, Marcio Montenegro wrote:
> I am evaluating STM32WB55  board HCI driver.
> During my test I found that BLE  public address is  02:80:e1:00:00:00
> But this microcontroller has an internal flash register to store BLE
> address and device id.
> I would like to know the best way to change the address BLE in this case.
> Best regards,
> Marcio
> BLE Stack initialization:
> [00:00:00.015,000] <dbg> bt_settings.bt_settings_init:
> Bluetooth initialized
> Configuration mode: waiting connections...
> [00:00:00.187,000] <inf> bt_hci_core: Identity: 02:80:e1:00:00:00 (public)
> [00:00:00.187,000] <inf> bt_hci_core: HCI: version 5.0 (0x09) revision
> 0x0026, manufacturer 0x0030
> [00:00:00.187,000] <inf> bt_hci_core: LMP: version 5.0 (0x09) subver 0x2126
> Get correct BLE address:
> udn = LL_FLASH_GetUDN();
> if(udn != 0xFFFFFFFF)
> {
>     company_id = LL_FLASH_GetSTCompanyID();
>     device_id = LL_FLASH_GetDeviceID();
>     bd_addr_udn[0] = (uint8_t)(udn & 0x000000FF);
>     bd_addr_udn[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 );
>     bd_addr_udn[2] = (uint8_t)( (udn & 0x00FF0000) >> 16 );
>     bd_addr_udn[3] = (uint8_t)device_id;
>     bd_addr_udn[4] = (uint8_t)(company_id & 0x000000FF);;
>     bd_addr_udn[5] = (uint8_t)( (company_id & 0x0000FF00) >> 8 );
>     bd_addr = (const uint8_t *)bd_addr_udn;
> }

I have not yet worked with any of the bluetooth APIs, but this thread
peaked my interest because I am also evaluating the STM32WB55 for an
upcoming project.

I did a quick search through the bluetooth API and found the function
bt_ctlr_set_public_addr [1]. I started digging into its implementation,
but I was not able to figure out how this function relates to the rest
of the bluetooth system, or how it relates to the STM32WB55 LL/HAL.

I would recommend trying this function to see if it meets your needs.
Please let me know if it works! I'm definitely curious to know how this
might work with the STM32WB55.

Rob Weber


Join to automatically receive all group messages.