Setting a Custom BT Address - Production Approach#

Introduction#

The Bluetooth LE stack usually derives the BT address (sometimes referred to as MAC address) of a device from its Unique Identifier, a 64-bit value located in the Device Information Page. This value is factory-programmed and not modifiable. Since the BT address is only 48-bit long, part of the Unique Identifier is removed while deriving the address. See your device's reference manual for more details on the Device Information page.

To extract the Unique Identifier from a radio board (e.g., BRD4182A - EFR32MG22), you can issue the following command using Simplicity Commander in a Windows command prompt.

  • $ commander device info

You should get an output similar to this, notice the Unique ID value:

Part Number    : EFR32MG22C224F512IM40
Die Revision   : A2
Production Ver : 2
Flash Size     : 512 kB
SRAM Size      : 32 kB
Unique ID      : 680ae2fffe2886c5
DONE

You can see the derived BT address after flashing the Bluetooth - SoC Empty example to the same device and scanning nearby advertisers using the Simplicity Connect mobile application. The following figure shows the expected output:

BT address in Simplicity Connect applicationBT address in Simplicity Connect application

Notice how the address is the same as the Unique ID except for the middle 16 bits (0xFFFE), hence why the BT address is a derived value. As mentioned before, this is the usual way for the BLE stack to acquire the BT address. Nonetheless, if a valid BT address entry is in the non-volatile region of the device (NVM3 for series 2 devices and PS Store or NVM3 for series 1), this value is used instead. For more details regarding non-volatile regions in the BLE stack, see the following documentation:

  1. Custom Application method: The running application reads a token located in the User Data page, derives the BT address from it, and stores it in the non-volatile region. This token is easily programmable through Simplicity Commander.

  2. Simplicity Commander method: Create a custom non-volatile region (NVM3) with the desired BT address with Simplicity Commander. Flash the output binary to the device. This option is viable only if you're using NVM3 as the persistent storage solution.

Note: The solutions underneath were tested on a BRD4182A (EFR32MG22) using the Bluetooth - SoC Empty example as a baseline.

Methods#

Custom Application#

This approach uses a custom function that leverages the sl_bt_system_set_identity_address() and sl_bt_system_get_identity_address() APIs. The steps are as follows:

First, create a new Bluetooth - SoC Empty example for your board. Open the app.c file of the project and copy the following code snippet. This is the custom function responsible for updating the BT address.

#define MFG_CUSTOM_EUI_64_OFFSET 0x0002

static void sli_set_custom_bt_address(void)
{
  uint8_t *mfg_token = (uint8_t*)USERDATA_BASE + MFG_CUSTOM_EUI_64_OFFSET;
  bd_addr myaddr, cur_addr;
  uint8_t address_type;

  sl_status_t status;

  //Adjust token byte Endianness
  for(uint8_t i = 0; i < 6; i++) {
    myaddr.addr[i] = mfg_token[7-i];
  }

  //Get current BT address:
  //  Current address is derived from EUI64 in DEVINFO unless there's an NVM3
  //  valid entry
  status = sl_bt_system_get_identity_address(&cur_addr, &address_type);

  if (status != SL_STATUS_OK) {
      while(1); //Issue retrieving the status
  }

  //Compare current and desired BT address, IF NOT EQUAL update and reset
  //  reset needed to apply BT address changes in stack
  if((memcmp