BLE Auto PA mode


The EFR32 families of chips each come equipped with two or three Power Amplifiers (PAs):

Each PA maps to different TX output power curves. While using high-power or medium-power PA, TX power under 0 dBm may get a very inaccuracy output. While using low-power PA, TX power cannot set above 0 dBm. In most use cases, the antenna matching network works well in one range only (either above 0 dBm or below 0 dBm), and hence this is not a big problem. In some use cases, however, high accuracy output is needed both above and below 0 dBm. In this case, an automatic switching between the PAs is needed. This article discusses how to achieve this.

Enabling Auto PA Mode

By default, the used PA can be configured under the configuration of RAIL Utility, PA software components, as shown here:

PA mode configuration

However, this lets you select a fixed PA only, and does not enable auto PA mode. Currently, auto PA mode can be enabled in source code by directly editing the config\sl_bluetooth_config.h in your project. Find the following configuration and change the .pa.pa_mode to SL_BT_BLUETOOTH_PA_AUTOMODE:

#define SL_BT_CONFIG_DEFAULT                                                   \
  {                                                                            \
    .config_flags = SL_BT_CONFIG_FLAGS,                                        \
    .bluetooth.max_connections = SL_BT_CONFIG_MAX_CONNECTIONS_SUM,             \
    .bluetooth.max_advertisers = SL_BT_CONFIG_MAX_ADVERTISERS,                 \
    .bluetooth.max_periodic_sync = SL_BT_CONFIG_MAX_PERIODIC_ADVERTISING_SYNC, \
    .bluetooth.max_buffer_memory = SL_BT_CONFIG_BUFFER_SIZE,                   \
    .scheduler_callback = SL_BT_CONFIG_LL_CALLBACK,                            \
    .stack_schedule_callback = SL_BT_CONFIG_STACK_CALLBACK,                    \
    .gattdb = &gattdb,                                                         \
    .max_timers = SL_BT_CONFIG_MAX_SOFTWARE_TIMERS,                            \
    .rf.tx_gain = SL_BT_CONFIG_RF_PATH_GAIN_TX,                                \
    .rf.rx_gain = SL_BT_CONFIG_RF_PATH_GAIN_RX,                                \
    .rf.tx_min_power = SL_BT_CONFIG_MIN_TX_POWER,                              \
    .rf.tx_max_power = SL_BT_CONFIG_MAX_TX_POWER,                              \
    .pa.config_enable = BT_PA_CONFIG_STATE,                                    \
    .pa.input = BT_PA_POWER_SUPPLY,                                            \
    .pa.pa_mode = SL_BT_BLUETOOTH_PA_AUTOMODE,                                             \

Note, that this, in itself, is not enough to switch between PAs automatically. You also have to define the rules of switching, i.e., between what circumstances you want to switch PAs. To define this, RAIL provides the RAILCb_PaAutoModeDecision() callback function, which can be overwritten in your application. For example, if you want to use high power PA above 10dBm, mid power PA between 0 and 10dBm and low power PA below 0dBm, apply the following function:

#include "rail.h"

RAIL_Status_t RAILCb_PaAutoModeDecision(RAIL_Handle_t railHandle,
                                        RAIL_TxPower_t *power,
                                        RAIL_TxPowerMode_t *mode,
                                        const RAIL_ChannelConfigEntry_t *chCfgEntry)
  if(*power < 0) {
    // Use the LP PA when is below 0dBm
  } else if((*power >= 0) && (*power <= 100)) {
    // Use the MP PA when TX power is from 0dBm to 10dBm
  } else {
    // Use the HP PA when TX power is over 10dBm


To verify whether the Auto PA mode is working properly, first check the set_max value returned by the sl_bt_system_set_tx_power() API command. This value tells you the actual (maximum) power level set by the stack, which may differ from the originally requested value because of the limitation of different PAs. The table below shows the requested and the actual set values for different TX power levels and different PA settings, tested on a EFR32xG21 chip. The following code example may help to test the same on your board: Testing TX Power Levels.

Note, that the unit used here is 0.1 dBm.

RequestedSet with HP PASet with MP PASet with LP PASet with Auto PA

For a full verification, also check the TX power levels with a spectrum analyzer. In this case, the following API is recommended: sl_bt_test_dtm_tx_v4(). This API lets you transmit packets continuously on a single channel with a given TX power. While unmodulated carrier is the ideal signal to measure, the API does not allow to set unmodulated carrier with TX Power > 12.7 dBm. As a result, the packet type sl_bt_test_pkt_11111111 should be used.

Note that when you measure the output TX power, the matching network also plays a big role. For guidance about the matching network design, see AN930.2.

Below you can see test results for two boards. Tester: Agilent E4405B spectrum analyzer Config: Frequency = 2440 MHz, Span = 2 MHz, Amplitude ref = 20 dBm, Amplitude offset = 1.6 dB

  1. BRD4180A with original matching network, tested between 0 dBm and 20 dBm.

    Matching Network for MP/HP PA

    Test Results for BRD4180A

  1. BRD4179B with modified matching network to support low power PA (see AN930.2), tested between -26 dBm and 10 dBm:

    Matching Network for LP PA

    Test Results for BRD4179B