Waking from Deep Sleep Using RF Sense


The EFR series of energy-friendly radios have the ability to wake themselves upon detecting an RF signal. This example code shows how to use this feature with the Silicon Labs Bluetooth stack.


The rfsense feature can be used to wake the device in any energy mode. This feature is accessed through a RAIL command. The first step is to initialize an additional RAIL configuration. The Bluetooth stack is also built on RAIL so the multiprotocol library is required here.

A simple RAIL_CONFIG_t struct can be used with most parameters left NULL.

static RAIL_Config_t railCfg = { .eventsCallback = NULL, .protocol = NULL, .scheduler = &railSchedState, };

A call to RAIL_Init with a pointer to this structure is made to initialize the RAIL configuration.

railHandleRfsense = RAIL_Init(&railCfg, NULL);

After the RAIL configuration is done, rfsense can be enabled. The rfsense feature in EFR32 can be accessed through the RAIL command RAIL_StartRfSense(). This command takes RAIL handle, the band, sensetime, and callback parameters. More specific information about this command can be found in the RAIL API reference guide, which is accessible from the launcher view in SimplicityStudio. After the call to RAIL_StartRfSense() is made, it is safe to go to EM4.

Building the Application

This section describes how to build the example based on the soc-empty-rail-dmp sample. This sample is used because it has the necessary settings to support multiprotocol.

Setting up

  1. Start by generating a copy of the soc-empty-rail-dmp sample app.
  2. Add the app.c and app.h files provided below to your project.
  3. Open main.c and:

    1. Add a call to appMain() just before the while loop in bluetoothAppTask().
    2. Remove the static keyword from the definition of boot_to_dfu to make it accessible from app.c.
    3. Add the preprocessor directive #include "app.h".
    4. Comment out the following call to OSTaskCreate that starts the proprietaryAppTask.

               "Proprietary App Task",
               (PROPRIETARY_APP_TASK_STACK_SIZE / 10u),
  4. Build the project and flash it to the target device.


In the provided example application, advertising starts for a fixed period of time. If no connection is made during this time, the device stops advertising, starts RF sense and goes into EM4 sleep mode. The system_boot event performs several tasks. First, it begins advertising to allow connections. Second, it initializes the RAIL configuration. At this point, it is also necessary to disable RFsense to avoid problems receiving packets. Lastly, a 30 second timer is started.

RAIL_StartRfSense(railHandleRfsense,RAIL_RFSENSE_OFF ,RFSENSE_TIME_MIN, rfsense_callback);

The timer will be used to stop advertising, start rf sense and go into EM4 mode. This is handled in the gecko_evt_hardware_soft_timer event.

case gecko_evt_hardware_soft_timer_id:

If a connection is formed, the gecko_evt_le_connection_opened event stops the timer to prevent going into EM4.

case gecko_evt_le_connection_opened_id: // if a connection is formed, stop the timer.

The easiest way to track the sleep mode is with the Energy Profiler. In EM4 the current consumption will be around 1.5 uA. To try this out, build and flash the application to your desired device, open the Energy Profiler, and start the energy capture. After reset, the average current will be approximately 4.1 mA. After the time expires, the device goes to EM4 and the average current drops to around 800 nA. To wake the device up, an RF signal > -20 dBm is required. This signal can be provided by placing a mobile phone in active discovery mode and placing it in close proximity to the EFR32. After the signal is detected, the device wakes up and the device once again begins advertising for the time specified. The length of time the RF signal must be detected for can be adjusted with the symbol RFSENSE_TIME_MIN. In the example it is set to 500 us.