Configuring the Bluetooth Stack and a Wireless Gecko Device#
To run the Bluetooth stack and an application on a Wireless Gecko, the MCU and its peripherals must be properly configured. The application project configuration consists of selecting the Platform and Bluetooth components that the application needs and setting the configurable values for each selected component. Application projects are generated using Silicon Labs Configurator (SLC) tools that read the project description from a .slcp file and generate the relevant files and build rules. An application can be generated using either the Project Configurator in Simplicity Studio 5 (SSv5) or the SLC-CLI. The files generated by the SLC tools take care of initializing and setting the configuration for the selected components.
Wireless Gecko MCU and Peripherals Configuration#
sl_system_init()
The sl_system_init()
function is used to initialize the system. It will call platform, driver, service, stack, and internal app init functions, which are located in the autogen
folder.
App_init()
The App_init()
function is used to initialize application-specific features.
Bluetooth Clocks#
The Bluetooth clocks are configured and initialized with clock manager by including clock_manager
component in the application project.
The clock settings are initialized in the sl_platform_init()
function in sl_event_handler.c
. Clock settings include initializations of oscillators (HFXO, LFXO, and LFRCO) with parameters such as tuning, initialization of the clocks (HFCLK, LFCLK, LFA, LFB, LFE), and the assignment of clocks to oscillators. Note: The peripheral clocks (like GPIO clock, TIMER clock) are not enabled in this function. They must be enabled when initializing a peripheral.
HFCLK
HFCLK is used for a radio protocol timer (PROTIMER). HFCLK is a high frequency clock where accuracy must be at least ±50 ppm. This clock needs an external crystal to be sufficiently accurate (HFXO).
The HFXO initialization configures the external crystals for timing-critical connection and sleep management. An HFXO has to be set as the high frequency clock (HFCLK) and physically connected to a Wireless Gecko’s HFXO input pins.
LFCLK
LFCLK, the low frequency clock, is used for two purposes. In the Bluetooth stack, it is used for Bluetooth protocol timing. It is also needed to keep track of time during sleep mode.
When a device enters into sleep mode, the current state of PROTIMER is saved. When the device wakes up, it calculates how many ticks of sleep clock have passed and adjusts the PROTIMER accordingly. To the radio it appears that PROTIMER has been constantly ticking.
The accuracy of this clock depends on the operating mode of the device. When advertising or scanning, accuracy is not that important, but when a connection is open, the accuracy must be at least ±500 ppm. This clock can be driven either by LFXO or LFRCO, depending on the accuracy requirements. If applications only re- quire advertising or scanning, LFRCO can be used as the clock source. However, if Bluetooth connections are required, the clock source must be either LFXO or LFRCO with High Precision Mode. When using LFRCO, the accuracy of the clock must be configured to ±500 ppm.
In the default configuration, LFXO is connected to the Wireless Gecko and set as the clock source for LFCLK. If the design only has PLFRCO or LFRCO with High Precision Mode, PLFRCO or LFRCO is connected and set as the clock source.
If none of LFXO or LFRCO with High Precision Mode is connected in the design, sleeping is disabled automatically if LF clock accuracy does not meet the 500 ppm requirement.
HFRCODPLL
HFRCODPLL is a high frequency clock that is used as a system clock with the Bluetooth stack. On EFR32[M|B]G21x, HFRCODPLL needs to be configured to 80 MHz and set as the system clock source.
CTUNE
The examples have the crystal tune (CTUNE) settings for both HFXO and LFXO set by default to work with all of the Silicon Labs’ Bluetooth modules, reference designs, and radio boards. However, in some cases the end-product design requires specific crystal calibration, either per device or per design. The CTUNE value can be adjusted according to the design using the clock manager.
For more information on configuring the HFXO and LFXO, refer to the EFR32 Reference Manual.
Default HFXO CTUNE Value
The system checks multiple sources for the default HFXO CTUNE value, using the following logical order:
CTUNE PSKEY is set. This key has ID
50
(32
in hex) and contains 2 bytes of data for the 16 bit CTUNE value. This can be programmed with the BGAPI commandsl_bt_nvm_save
. This method is not recommended.If the
clock_manager_oscillator_calibration_override
component is included in the application, that will initialize oscillator calibration settings using override key values stored in NVM. The override is stored in NVM3 ID HFXO_CTUNE_NVM3_RESERVED_ID 0x89800. See Clock Manager for more details how to write and read the override value.Calibration value exists in DEVINFO. Some modules contain a factory-programmed value in the DEVINFO-page.
Manufacturing token exists in the user data page. This is programmed by the developer, or it can be automatically set by Simplicity Studio if the board EEPROM contains the value. This token consists of 2 bytes, located at offset 0x0100 from the starting address of the User Data page. Refer to Bringing Up Custom Devices for the EFR32MG and EFR32FG Families to how to use manufacturing tokens.
If nothing else is found, use the default value from the clock manager.
Setting CTUNE via the BGAPI and NVM3 (step 1 above) is a Bluetooth-specific solution and is not recommended for new designs. New designs and applications should use the CTUNE setting mechanisms provided by the platform components, as these guarantee proper CTUNE settings regardless of which wireless stacks are running.
DC-DC Configuration#
On devices that have DC-DC, the configuration is set in the sl_device_init_dcdc()
function in sl_event_handler.c. The examples in the SDK have DC-DC configuration set to work with the Silicon Labs’ Bluetooth modules, radio boards, and reference designs, but custom designs might require specific DC-DC settings. These custom settings can be set in sl_device_init_dcdc_xx.c
.
/** DCDC regulator initialization structure. */
typedef struct {
EMU_DcdcMode_TypeDef mode; /**< DCDC mode. */
EMU_VreginCmpThreshold_TypeDef cmpThreshold; /**< VREGIN comparator threshold. */
EMU_DcdcTonMaxTimeout_TypeDef tonMax; /**< Ton max timeout control. */
bool dcmOnlyEn; /**< DCM only mode enable. */
EMU_DcdcDriveSpeed_TypeDef driveSpeedEM01; /**< DCDC drive speed in EM0/1. */
EMU_DcdcDriveSpeed_TypeDef driveSpeedEM23; /**< DCDC drive speed in EM2/3. */
EMU_DcdcPeakCurrent_TypeDef peakCurrentEM01; /**< EM0/1 peak current setting. */
EMU_DcdcPeakCurrent_TypeDef peakCurrentEM23; /**< EM2/3 peak current setting. */
} EMU_DCDCInit_TypeDef;
For more information on configuring the DC-DC, refer to the EFR32 Reference Manual, Chapter 11, and AN0948: Power Configurations and DC-DC.
LNA#
A low-noise amplifier (LNA) is an electronic amplifier that amplifies a very low-power signal without significantly degrading its signal-to-noise ratio. The LNA improves RF sensitivity.
An LNA is provided on-board in some MGM12P modules as part of front-end module (FEM). To use LNA in these modules, the FEM needs to be correctly configured and enabled. The FEM is configured in sl_fem_util_config.h.
FEM is initialized in sl_fem_util_init()
within the sl_service_init()
function if the board supports FEM.
PTI#
PTI (Packet Trace Interface) is a built-in block in the Wireless Gecko SoCs to route incoming and outgoing radio packets as raw data to the debug interface. These packets can then be captured and displayed in Simplicity Studio’s Network Analyzer. Network Analyzer has a decoder for Bluetooth packets and can be used to debug, analyze, and measure Bluetooth networks.
PTI is initialized in sl_rail_util_pti_init()
within the sl_stack_init()
function. The baudrate can be set using the SL_RAIL_UTIL_PTI_BAUD_RATE_HZ definition, and pins can be configured using the definitions with the SL_RAIL_UTIL_PTI_DOUT_ and SL_RAIL_UTIL_PTI_DFRAME_ prefix in sl_rail_util_pti_config.h.
Transmit Power#
Transmit power of Bluetooth depends on the maximum power allowed by the radio, the software configuration, RF path gain compensation, and usage of Adaptive Frequency Hopping (AFH).
The ETSI EN 300 328 standard requires using AFH when transmitter power is +10 dBm and over.
The maximum allowed power is limited to less than +10 dBm if prevented by adaptivity requirements. The ETSI standard requires that at least 15 channels are in use for AFH. This requirement prevents using +10 dBm and over in the following cases: legacy advertising, scan responses, and in connections, when not enough channels are available.
Wi-Fi Coexistence#
Wi-Fi coexistence (COEX) is a protocol where Bluetooth and Wi-Fi arbitrate which protocol can use the radio for transmitting. When enabled, it improves the performance of Wi-Fi and Bluetooth. The application can include the COEX functionality by including the rail_util_coex
component and configuring it in sl_rail_util_coex_config.h.
Mbedtls#
The Mbedtls cryptography library used by the stack is configured using a configuration file that defines which algorithms are supported, and if the implementation uses hardware acceleration or is done on software. The Bluetooth stack uses the new PSA crypto API for crypto operations. In addition to enabling crypto operations, the PSA crypto API enables storing long-term encryption keys encrypted on flash in Vault-enabled devices.
The Mbedtls needs to be initialized with sl_mbedtls_init()
. The Mbedtls configuration file path is given using #define MBEDTLS_CONFIG_FILE
. The default configuration files config/mbedtls_config.h
, autogen/mbedtls_config_autogen.h
, config/psa_crypto_config.h
, and autogen/psa_crypto_config_autogen.h
should be used as a template if the configuration needs to be changed.
In PSA crypto API, only a certain number of keys can be open at one time. Bluetooth pairing requires that 2 keys are open at the same time. By default, no key slots are reserved for the application to save RAM. If the application uses PSA crypto API, then the SL_PSA_KEY_USER_SLOT_COUNT
setting must be set to the value of the number of keys the application needs to stay open simultaneously. This can be changed with the SL_PSA_KEY_USER_SLOT_COUNT
setting located in config/psa_crypto_config.h
. Each key slot will use 40 bytes of RAM.
If any Mbedtls errors occur when the Bluetooth stack is using crypto operations, sl_bt_evt_system_error
is sent with the status set as SL_STATUS_BT_CRYPTO
and the data field containing the actual Mbedtls error code.
Note that the actual Bluetooth connection encryption uses RADIOAES, which does not have DPA countermeasures. RADIOAES only has access to temporary session keys.
Bluetooth Stack Configuration#
The Bluetooth stack core component, bluetooth_stack
, is available in all versions of the Bluetooth SDK and must always be included when the application wants to use Bluetooth functionality. The Bluetooth feature components represent features and functionalities that an application may optionally include into the build. To minimize the code size and flash usage, applications are encouraged to only include those feature components that the application requires. Most Bluetooth feature components correspond to a BGAPI class in the Bluetooth API. When the corresponding component is not included in the application project, the API class is not available, and its commands will return an error at runtime.
The set of available Bluetooth feature components can vary depending on the Bluetooth SDK version. Consult the API documentation and the components in the SDK that you are working with. The available configuration options may also differ between Bluetooth SDK versions. Some Bluetooth configuration parameters are part of the core component, bluetooth_stack
, while some parameters are part of the optional feature component. Each component that provides configurable parameters has an associated configuration header. Consult the configuration headers or the Project Configurator in the Simplicity Studio to see the description of each configuration parameter.
The subsections below describe some Bluetooth components or functionalities that affect Bluetooth as a whole or have special configuration considerations.
Bluetooth On-Demand Start#
With the Bluetooth on-demand start feature, the application can start and stop the Bluetooth stack from running when needed. The feature is enabled by including the bluetooth_on_demand_start
component. When this feature is enabled, the Bluetooth stack does not run until sl_bt_system_start_bluetooth()
is called. The main purpose of this feature is for the DMP use case, where Bluetooth is not needed all the time, and resources need to be freed for other application uses. The Bluetooth stack can be stopped with sl_bt_system_stop_bluetooth()
, which gracefully restores Bluetooth to an idle state by disconnecting any active connections and stopping any ongoing advertising and scanning. Any resources that were allocated when the stack was started are freed when the stack is stopped. When the Bluetooth stack is not running, all BGAPI classes other than System become unavailable.
If this feature is not enabled, Bluetooth stack is started automatically at boot time.
Bluetooth Buffer Memory#
The Bluetooth stack uses memory for buffering API events and the data transmitted in Bluetooth connections, advertising, and scanning. This buffer memory is allocated from the heap when the Bluetooth stack is started. The size of buffer memory in bytes is defined by C-define SL_BT_CONFIG_BUFFER_SIZE
in sl_bluetooth_config.h. The default value is an estimation for achieving adequate throughput and supporting multiple simultaneous connections. Consider increasing this value if the application needs higher data throughput over connections, or uses advertising or scanning with long advertisement data.
Number of Connections#
The absolute maximum number of simultaneous Bluetooth connections is 32. The amount of memory that is allocated for connection management further limits the number of connections. The memory is allocated from the heap when the Bluetooth stack is started. C-define SL_BT_CONFIG_MAX_CONNECTIONS
in sl_bluetooth_config.h can be defined to set the number of connections.
Software Timers#
The maximum number of available software timers can be configured by C-defineSL_BT_CONFIG_MAX_SOFTWARE_TIMERS
in sl_bluetooth_config.h. Each timer needs resources from the stack to be implemented. Increasing the number of soft timers may cause degraded performance in some use cases. Instead of using software timers, the recommend way for using timers is to use sleeptimer
component.
TX Power and RF Path#
TX Power
The system scope maximum TX power for Bluetooth can be configured by C-define SL_BT_CONFIG_MAX_TX_POWER. It specifies the maximum TX power for Bluetooth connections, advertising, scanning, and DTM testing.
The C-define SL_BT_CONFIG_MIN_TX_POWER is used only by the LE Power Control feature. It specifies the minimum TX power level for Bluetooth connections and DTM testing.
Gain
The application can define RF path gain values for RX and TX separately. Positive values mean gain on the given RF path, while negative values mean loss.
The Bluetooth stack takes TX RF path gain into account when setting TX power. The TX power is automatically adjusted so that the power radiated from the antenna matches the application request. For example, if maximum power requested by the application is at +10 dBm and path loss is -1 dB,then actual power at the RF pin is set to +11 dBm.
The TX RF path gain must be set with care and correspond to reality. The stack put limits on the TX power to comply with RF regulations. If the TX RF path gain is not set properly, the device may violate the regulations and may not pass RF certification!
Note: This setting is not meant for modules with integral antennas and should be ignored for such devices.
RX RF path gain is used to compensate the RSSI reports from the Bluetooth Stack.
.rf.tx_gain = -20; // RF TX path gain in unit of 0.1 dB. -20 means -2 dB loss on the TX RF path.
.rf.rx_gain = -18; // RF RX path gain in unit of 0.1 dB. -18 means -1.8 dB loss on the RX RF path.
Output selection
On EFR32[M|B]G21 SoC-based designs, the RF output can be selected.
.rf.flags = SL_BT_RF_CONFIG_ANTENNA; // enabling output configuration
.rf.antenna = 0; // desired output,
For the correct value refer to the antenna path selection in the RAIL header file rail_chip_specific.h
.
Security Manager#
To enable the Security Manager in the Bluetooth stack, the application needs to include the bluetooth_feature_sm
component into the application project. It is important to configure the Security Manager properly to ensure that security requirements can be achieved. Use sl_bt_sm_configure()
to set security flags and device’s IO capabilities. The IO capabilities define which pairing methods are possible and should be set to match the device’s capabilities. The security flags can be used to enforce certain security settings, such as requiring that pairing always uses bondable mode, pairing only uses secure connections, or whether authentication is required. Security Manager also has a flag to indicate whether authenticated or non-authenticated pairing is preferred if both are possible. If this flag is not set, and even if both devices’ IO capabilities allow authenticated bonding, it is not used if neither device requests authentication. Refer to the available options in API documentation, Security Manager.
The number of bondings that can be stored in the bonding database is set with sl_bt_sm_store_bonding_configuration()
. This command is also used to define what happens if the bonding database becomes full. Pairings are not stored in the bonding database unless both devices are in bondable mode. Enable the bondable mode with sl_bt_sm_set_bondable_mode()
. Including the bluetooth_feature_external_bonding_database
component can be used to handle storing bonding data by the application. This can be useful with applications that require a large number of bondings. With the external bonding database component, the Bluetooth stack does not limit the number of bondings.
Adaptive Frequency Hopping#
Bluetooth Stack implements Adaptive Frequency Hopping (AFH), conforming with the ETSI EN 300 328 standard. AFH is required when using transmit power +10 dBm and over. AFH may also provide performance improvement by avoiding congested channels.
To enable AFH in the Bluetooth stack, the application must include the bluetooth_feature_afh
component. In a central-peripheral connection, both ends can use AFH independent of each other. The central device may be non-adaptive, but the peripheral still may need to be adaptive. The standard allows using control transfer on a blocked channel. For compliance reasons, if the peripheral detects that a blocked channel is in use, it will only send a single packet on that channel to prevent connection timeouts.
Note: Legacy advertising does NOT use Adaptive Frequency Hopping. Legacy advertising uses 3 channels, and AFH needs a minimum of 15 channels to fulfill the requirements of the ETSI standard. Extended advertising must be used to enable AFH with advertising.
Even Connection Distribution Algorithm#
The even connection distribution algorithm is designed to be used especially with applications that involve several concurrent connections. The algorithm tries to distribute the connections such a way that they are distributed over time as evenly as possible without overlapping, and all connections should get an equal share of the air interface resource.
For optimal performance, the algorithm user should:
Initiate the first connection with the longest connection interval if all connections do not have the same interval.
Set the connection intervals of the other connections such that they are, or allow (via min-max range), integer fractions of the first interval.
Make the first interval long enough such that all connections would fit within the interval with a reasonable transmission time.
The algorithm and the connections can be expected to work if the above recommendations are not followed, but performance will not likely be optimal.
By default, the link layer uses the legacy Random Connection Distribution algorithm. The Even Connection Distribution algorithm can be enabled by including the component bluetooth_feature_ll_even_scheduling
or calling link layer functionll_connSchAlgorithmEvenEnable()
during the software initialization phase. As the even connection scheduling mechanism is meant to be used with multiple (up to 32) concurrent connections, the buffer size is recommended to be increased as follows.
SL_BT_CONFIG_BUFFER_SIZE 20160
Multiprotocol Priority Configuration#
When the Bluetooth stack is used with other protocols in a multiprotocol environment, it may become necessary to change the Bluetooth priority settings for RAIL to optimize certain use cases.
The application needs to allocate the configuration struct and provide it for the Bluetooth stack:
sl_bt_bluetooth_ll_priorities custom_priorities;
static const sl_bt_configuration_t config = {
//
.bluetooth.linklayer_priorities = &custom_priorities,
//
};
The sl_bt_bluetooth_ll_priorities
struct must be initialized to default state by the SL_BT_BLUETOOTH_PRIORITIES_DEFAULT
constant.
The sl_bt_bluetooth_ll_priorities
struct contains following fields:
scan_min, scan_max, scan step
- The priority range for scan operation.adv_min, adv_max, adv step
- The priority range for advertisement operation.conn_min & conn_max
- The priority range for connection packets.init_min & init_max
- The priority range for connection initiation.rail_mapping_offset
- The RAIL priority level where Bluetooth priorities are located.rail_mapping_range
- The RAIL priority range where Bluetooth priorities are located.
For each priority range, 0 is the maximum priority, and 0xff is the minimum priority. Bluetooth priorities are different from RAIL priorities. That is, Bluetooth has its own space between 0 and 0xff where all Bluetooth priorities are located. To map Bluetooth priorities to RAIL priorities, the values in fields rail_mapping_offset
and rail_mapping_range
are used to form single-degree equation:
RAIL_priority=(BT_priority/0xFF)*rail_mapping_range+rail_mapping_offset
Sleep#
Wireless Gecko’s sleep mode EM2 (energy mode two) is managed by the platform power_manager_deepsleep
component. Including the component automatically enables deep sleep. Including the power_manager_no_deepsleep
component in the application will disable deep sleep.
The sleep modes require that an accurate 32 kHz low-frequency clock (LFCLK) is present in the hardware. If an accurate sleep clock is not available for the Bluetooth stack and the application must support Bluetooth connections or periodic advertising synchronizations, then low power sleep modes cannot be entered. For applications where low power sleep modes are not needed, the LFXO or LFRCO can be left out.
Disabling Sleep at Runtime
If the application needs to disable sleep at runtime, it can be done by implementing bool app_is_ok_to_sleep()
function. The function is called when the device wants to sleep. While EM2 is disabled (/blocked), the stack will switch between EM0 and EM1. For more information, refer to Power Manager documentation.
PA#
On EFR32 SoC-based designs, the Power Amplifier (PA) configuration comes from component rail_util_pa
, the utility to aid with RAIL RF PA Support.
OTA Configuration for EFR32[M|B]G1x devices#
Bluetooth Over-the-Air (OTA) firmware upgrades are supported because part of the firmware upgrade is handled by the Bluetooth AppLoader application. On EFR32[M|B]G1x devices, enable OTA configuration with the bluetooth_feature_ota_config
component. On EFR32[M|B]G2x devices, AppLoader was merged with Gecko Bootloader.
The OTA mode can be configured using the sl_bt_ota_set_configuration()
function, which can, for example, set OTA to use a static random address, instead of a public address. For other options, refer to the BGAPI document.
When the Wireless Gecko is in AppLoader's OTA mode, its device name and the device name length can be configured with the sl_bt_ota_set_device_name()
function. The advertisement data used in OTA mode can be set to use custom data instead of the default one with sl_bt_ota_set_advertising_data()
.
If the device is not using the default RF path, it can be configured for OTA mode with sl_bt_ota_set_rf_path()
.
Finally, setting the device to OTA DFU mode should be secured so that only trusted devices have that capability.
For more details about OTA firmware updates, refer to UG266: Silicon Labs Gecko Bootloader User’s Guide for GSDK 3.2 and Lower, Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices), or Silicon Labs Gecko Bootloader User’s Guide for Series 3 and Higher, and Using the Gecko Bootloader with Silicon Labs Bluetooth Applications.
Radio Co-Processor Mode#
The Bluetooth controller can be used in Radio Co-Processor (RCP) mode with HCI interface. The link layer must be configured with vendor-specific HCI commands to allocate dynamic memory structures before the link layer can be used.
For more details about the RCP mode, refer to AN1328: Enabling a Radio Co-Processor using the Bluetooth LE HCI Function.