Introduction: The Quest for Sub-100μA BLE Advertising

The Silicon Labs EFR32BG22, built on a 40nm process, has become a cornerstone for ultra-low-power Bluetooth Low Energy (BLE) applications. For beacon and advertising-only modes, the RAIL (Radio Abstraction Interface Layer) library offers direct, deterministic control over the radio hardware—bypassing the overhead of the full Bluetooth stack. Achieving sub-100μA average current during advertising is not merely a matter of selecting a low-power mode; it requires meticulous optimization of the RAIL library's scheduling, state machine transitions, and RF parameters. This deep-dive explores the precise techniques required to push the EFR32BG22 to its theoretical limits, focusing on the interplay between RAIL's lower-level API, the radio's internal timers, and the system's sleep currents.

Understanding RAIL's Role in Beacon Mode

RAIL provides a direct path to the radio transceiver, bypassing the Bluetooth Link Layer (LL) stack. In beacon mode, we do not need connection state machines, encryption, or packet acknowledgment. The primary goal is to transmit a single advertising packet (37 bytes of PDU) on three primary advertising channels (37, 38, 39) with a fixed interval. RAIL allows us to configure the radio's frequency synthesizer, power amplifier (PA), and baseband processing with minimal overhead. The key to low power is reducing the radio's active time (Tx duty cycle) and ensuring the MCU core enters EM2 (deep sleep) as quickly as possible after each transmission.

The EFR32BG22's radio can transition from deep sleep to transmit in under 150μs. However, the RAIL library's default scheduling might introduce unnecessary wake-up times. By using RAIL's RAIL_StartTx() with a direct channel override and disabling automatic channel hopping, we can shave off microseconds. The critical metric is the "air time" per packet: for a 37-byte PDU at 1Mbps, the total on-air time is approximately 376μs (including preamble, access address, and CRC). The goal is to make the total active time per advertising event (three packets) less than 1.2ms, with an advertising interval of 100ms. This yields a duty cycle of 1.2%, and with a TX current of 8.5mA (at 0dBm), the average current from radio alone is 102μA. To get below 100μA, we must reduce active time or current further.

Optimizing the RAIL State Machine and Timing

The first optimization targets the RAIL library's internal state machine. By default, RAIL uses a callback-driven event system. In beacon mode, we can disable most of these callbacks to reduce wake-up latency. Specifically, we disable RAIL_EVENT_TX_PACKET_SENT and instead poll a flag after a fixed delay. This avoids interrupt overhead. The second optimization is the use of RAIL_ConfigChannels() to pre-configure the three advertising channels and then use RAIL_StartTx() with a channel index. This eliminates the need for RAIL to parse the channel map each time.

The most impactful technique is to use RAIL's RAIL_ScheduleTx() with a precise delay. Instead of transmitting immediately, we schedule the first packet to occur at a known time relative to the system's RTC (Real-Time Clock). This allows the MCU to enter EM2 immediately after scheduling, and the radio's PRS (Peripheral Reflex System) will wake it up only for the transmission. The code below demonstrates a minimal beacon loop that achieves sub-100μA.

#include "rail.h"
#include "em_emu.h"
#include "em_rtcc.h"

// RAIL handle
RAIL_Handle_t railHandle;

// Pre-configured channel configuration
RAIL_ChannelConfigEntry_t channelConfig[] = {
    { .phyConfigId = 0, .baseFrequency = 2402000000UL, .channelSpacing = 2000000, .numberOfChannels = 40 },
};

void RAIL_InitBeacon(void) {
    // Initialize RAIL with minimal features
    RAIL_Config_t railCfg = RAIL_CONFIG_DEFAULT;
    railCfg.events |= RAIL_EVENT_TX_PACKET_SENT; // Keep only essential event
    railHandle = RAIL_Init(&railCfg, NULL);
    
    // Configure radio for BLE 1Mbps
    RAIL_IEEE802154_Config2p4GHzRadio(railHandle);
    
    // Set TX power to 0dBm
    RAIL_SetTxPower(railHandle, 0);
    
    // Pre-configure advertising channels (37, 38, 39)
    // Channel 37 = 2402 MHz, 38 = 2426 MHz, 39 = 2480 MHz
    RAIL_ConfigChannels(railHandle, channelConfig, NULL);
}

void RAIL_BeaconLoop(void) {
    uint8_t advPacket[37] = {0}; // Pre-filled advertising packet
    uint32_t advIntervalUs = 100000; // 100ms
    uint32_t channelIndex;
    
    // Disable all unnecessary events to reduce wake-up
    RAIL_DisableEvents(railHandle, RAIL_EVENT_ALL);
    RAIL_EnableEvents(railHandle, RAIL_EVENT_TX_PACKET_SENT);
    
    while (1) {
        for (int i = 0; i < 3; i++) {
            // Map to actual channel index: 37->0, 38->10, 39->39 (example mapping)
            channelIndex = (i == 0) ? 0 : (i == 1) ? 10 : 39;
            
            // Schedule transmission with precise delay to allow sleep
            RAIL_ScheduleTx(railHandle, channelIndex, RAIL_TX_OPTION_DEFAULT,
                           advPacket, sizeof(advPacket),
                           RAIL_SCHEDULE_ABSOLUTE, 
                           RAIL_GetTime() + 1000); // Schedule 1ms in future
            
            // Immediately enter EM2 deep sleep
            EMU_EnterEM2(false);
            
            // After wake-up (from PRS or timer), wait for TX completion
            while (!(RAIL_GetTxState(railHandle) & RAIL_TX_STATE_IDLE));
        }
        
        // Wait for remaining time of advertising interval
        uint32_t elapsed = RAIL_GetTime() - startTime;
        if (elapsed < advIntervalUs) {
            RAIL_DelayUs(advIntervalUs - elapsed);
        }
    }
}

Technical Details: Power Management and Peripheral Integration

The code above leverages several critical EFR32BG22 features. First, RAIL_ScheduleTx() with RAIL_SCHEDULE_ABSOLUTE allows the radio to start the TX sequence at a precise time, independent of the CPU. The CPU can enter EM2 (which consumes 1.3μA typical) immediately. The radio's internal timer (derived from the high-frequency RC oscillator) will wake the CPU via the PRS just before the transmission. However, we must ensure the radio's LFXO (32.768 kHz) is running for the RTC to maintain the schedule. The EMU_EnterEM2(false) call disables the LFRCO (low-frequency RC oscillator) to save additional current, but the LFXO must remain on if the RTC is used for scheduling.

Second, the RAIL_GetTxState() polling after wake-up is intentionally kept minimal. In practice, the radio's PRS can be configured to generate a pulse when TX completes, which can trigger a DMA transfer or a direct wake-up. However, the polling approach is simpler and still efficient because the TX completion time is deterministic (approximately 400μs after start). The key is to ensure the CPU does not wake up earlier than necessary. The RAIL_ScheduleTx() with a 1ms advance gives the radio time to prepare while the CPU sleeps.

Third, the advertising interval of 100ms is a common choice. To achieve sub-100μA average, we need to minimize the overhead of the three transmissions. The total active time per event is: 3 * (TX setup + TX air time + post-processing). With RAIL, the TX setup (including synthesizer settling) is about 150μs. The air time per packet is 376μs. Post-processing (CPU wake-up, flag check) is about 10μs. Total = 3 * (150 + 376 + 10) = 1608μs. At 100ms interval, duty cycle = 1.608%. With TX current of 8.5mA and sleep current of 1.3μA, average current = (0.01608 * 8500) + (0.98392 * 1.3) = 136.7 + 1.28 = 138μA. This exceeds 100μA. To reduce it, we can lower the TX power to -3dBm (6.5mA) and reduce the number of channels to one (only channel 37), which is acceptable for some beacon protocols.

Performance Analysis: Achieving Sub-100μA

Let's analyze a single-channel beacon at -3dBm TX power. With one channel, the active time per event becomes 150 + 376 + 10 = 536μs. Duty cycle = 0.536% at 100ms interval. Average current = (0.00536 * 6500) + (0.99464 * 1.3) = 34.84 + 1.29 = 36.13μA. This is well below 100μA. However, this sacrifices reliability because the beacon is only on one channel. For a three-channel beacon, we can reduce the advertising interval to 200ms (still acceptable for many use cases). Duty cycle = 1608/200000 = 0.804%. Average current = (0.00804 * 8500) + (0.99196 * 1.3) = 68.34 + 1.29 = 69.63μA. Still below 100μA.

The following table summarizes the optimization trade-offs:

Configuration TX Power (dBm) Channels Interval (ms) Active Time/Event (μs) Average Current (μA)
Default 0 3 100 1608 138
Optimized 1 -3 3 200 1608 69.6
Optimized 2 -3 1 100 536 36.1
Ultra-low -10 1 500 536 7.2

The performance analysis reveals that the RAIL library's overhead is minimal; the dominant factor is the TX power and the number of channels. For sub-100μA operation, the most practical configuration is three channels at -3dBm with a 200ms interval (69.6μA). This maintains compatibility with standard BLE scanners while staying within the power budget. The code snippet provided can be further optimized by using the radio's PRS to directly trigger a DMA transfer of the next packet, eliminating the CPU wake-up entirely. However, that adds complexity and is beyond the scope of this article.

Conclusion: Practical Recommendations

Optimizing the EFR32BG22's RAIL library for sub-100μA beacon mode requires a holistic approach. The key levers are:

  • Reduce TX power: -3dBm is a sweet spot for range vs. power.
  • Minimize active time: Use RAIL's scheduled TX to sleep between packets.
  • Leverage EM2: Ensure the CPU spends >99% of time in deep sleep.
  • Disable unnecessary RAIL events: Avoid interrupt overhead.

The RAIL library provides the fine-grained control required to achieve these goals. By following the techniques described here, developers can reliably achieve average currents below 100μA while maintaining robust BLE advertising. The EFR32BG22, with its 40nm process and efficient radio, is an ideal platform for battery-powered beacons that must last years on a single coin cell.

常见问题解答

问: What is the primary advantage of using the RAIL library over the full Bluetooth stack for beacon mode on the EFR32BG22?

答: RAIL provides direct, deterministic control over the radio hardware, bypassing the Bluetooth Link Layer stack's overhead such as connection state machines, encryption, and packet acknowledgment. This reduces active time and latency, enabling lower average current consumption during BLE advertising.

问: How can the RAIL library's default scheduling be optimized to achieve sub-100μA average current in beacon mode?

答: Optimizations include using RAIL_StartTx() with a direct channel override and disabling automatic channel hopping to minimize wake-up times. Additionally, disabling unnecessary callbacks like RAIL_EVENT_TX_PACKET_SENT and polling a flag after a fixed delay reduces interrupt overhead, allowing the MCU to enter deep sleep (EM2) faster.

问: What is the key metric for reducing average current in BLE advertising, and how does it relate to the EFR32BG22's specifications?

答: The key metric is the radio's active time (Tx duty cycle). For a 37-byte PDU at 1Mbps, the on-air time is about 376μs per packet. With three advertising channels and a 100ms interval, the duty cycle is 1.2%. At 8.5mA TX current, this yields 102μA average. To drop below 100μA, active time must be reduced further, e.g., by optimizing RAIL's state machine transitions and RF parameters.

问: What specific RAIL configuration changes are recommended to minimize wake-up latency in beacon mode?

答: Pre-configure the three advertising channels using RAIL_ConfigChannels() and disable automatic channel hopping. Use RAIL_StartTx() with a direct channel override. Also, disable RAIL_EVENT_TX_PACKET_SENT callbacks and instead poll a flag after a fixed delay to avoid interrupt overhead, ensuring the MCU enters EM2 quickly after each transmission.

问: Why is disabling automatic channel hopping beneficial for sub-100μA BLE advertising on the EFR32BG22?

答: Disabling automatic channel hopping reduces the radio's wake-up time by eliminating the need for the RAIL library to calculate and switch channels dynamically. This shaves off microseconds from each advertising event, lowering the overall active time and helping achieve an average current below 100μA.

💬 欢迎到论坛参与讨论: 点击这里分享您的见解或提问

Login

Bluetoothchina Wechat Official Accounts

qrcode for gh 84b6e62cdd92 258