This KBA summarizes the COEX feature itself then walks through how to enable the feature in a Bluetooth SDK project. Finally, it shows how the COEX signals behaves while the Bluetooth device advertising, scanning or in connection.
What is COEX?
COEX feature is a 3 wire PTA implementation introduced in Silicon Labs Bluetooth SDK v2.6.0 release.
What is PTA?
PTA stands for Packet Traffic Arbitration and PTA is described in IEEE 802.15.2 (2003) Clause 6 and is a recommendation, not a standard. The PTA mechanism coordinates sharing of the medium dynamically, based on the traffic load of the two wireless networks, in this case Bluetooth and Wi-Fi.
There are 1, 2, 3 and 4 wire PTA implementations exist. Silicon Labs Bluetooth SDK supports the 3 wire PTA implementation which is the most common used in Wi-Fi devices.
In 3-Wire PTA 3 signals defined
The Wi-Fi device asserts a GRANT signal when Wi-Fi is not busy transmitting or receiving. When GRANT is asserted, the Bluetooth radio can transmit or receive.
The REQUEST signal is allowing the Bluetooth radio to request the 2.4 GHz ISM band. The Wi-Fi device internally controls the prioritization between Bluetooth and Wi-Fi and, on a conflict, the Wifi device can choose to either GRANT Bluetooth or Wi-Fi.
The PRIORITY signal is allowing the Bluetooth radio to signify a high or low priority message is either being received or transmitted. The Wi-Fi device compares this external priority request against the internal Wi-Fi priority, which may be high/low or high/mid/low and can choose to either GRANT Bluetooth or Wi-Fi.
Note: PRIORITY can be implemented as static or time-shared (enhanced) priority. As of PTA support implementation in Silicon Labs SDKs only supports static priority.
• Static: PRIORITY is either high or low during REQUEST asserted for the transmit or receive operation.
• Time-Shared: PRIORITY is either high or low for a typically 20 µs duration after REQUEST asserted, but switches to low during receive operation and high during transmit operation. Given the relatively low RF duty cycle of 802.15.4, static PRIORITY can be always asserted at the Wi-Fi/PTA input with the EFR32 PTA operating in 2-Wire mode. This frees a GPIO pin on the EFR32 and eliminates a circuit board trace.
To enable the COEX feature in a Bluetooth SDK project the libcoex.a library has to be added to the project.
The library can be used only with Bluetooth stack, not compatible with other Silicon Labs stacks. The library increases flash consumption by ~1kB. It has dependencies to em_gpio.c, gpiointerrupt.c files which are provided by the gecko sdk suit.
In Simplicity Studio, the library name and the library path has to be added to the project.
COEX library path is depending on the MCU variant and the complier. See the default path for EFR32BG1B device using GCC complier
The COEX library name and the library path can be specified in the project properties dialog as shown below. In case using GCC the lib prefix has to be removed from the library name.
Once the libcoex.a library added to the project the COEX feature has to be configured for the system needs. There are options which can be configured in compile time via preprocessor switches (#defines) and there are options which can be configured runtime via API calls.
Compile time options
The following #define-s must be set in hal-config.h. The file can be found in Bluetooth SDK example-s root.
// Enable 802.11 co-ex feature in gecko_init #define HAL_COEX_ENABLE 1 // Request window in microseconds // How many us before the TX/RX request signal is enabled #define HAL_COEX_REQ_WINDOW 500 // Grant signal polarity, pin and port #define BSP_COEX_GNT_ASSERT_LEVEL 0 #define BSP_COEX_GNT_PIN 12 #define BSP_COEX_GNT_PORT gpioPortD // Priority signal polarity, pin and port #define BSP_COEX_PRI_ASSERT_LEVEL 0 #define BSP_COEX_PRI_PIN 11 #define BSP_COEX_PRI_PORT gpioPortD // Request signal polarity, pin and port #define BSP_COEX_REQ_ASSERT_LEVEL 0 #define BSP_COEX_REQ_PIN 10 #define BSP_COEX_REQ_PORT gpioPortD // Shared request in case multiple EFR32 radios are used #define HAL_COEX_REQ_SHARED 0 // Enable priority signal (set both to 1) #define HAL_COEX_TX_HIPRI 1 #define HAL_COEX_RX_HIPRI 1 // Abort TX if grant is denied during ongoing TX operation #define HAL_COEX_TX_ABORT 1
The COEX feature have to be initialized by calling gecko_initCoexHAL() API function. For convenience this is done by the void gecko_init(const gecko_configuration_t *config) API by default.
The gecko_cmd_coex_set_options(uint32_t mask, uint32_t options) API can be used for modify COEX options in runtime. The following option can be configured:
See the API documentation and chapter 2.1 in the Bluetooth API reference
Shared REQUEST feature
The Shared REQUEST feature is needed when one master (Wi-Fi) controls multiple EFR32 slaves. In this case all devices share the same REQUEST, PRIORITY, and GRANT signals therefore it is mandatory that GPIO configuration (polarity, open drain/source mode, pull-up/down resistor) is consistent across the devices. This feature can be turned on by the #define HAL_COEX_REQ_SHARED preprocessor switch.
COEX signals in practice
In this setup, all 3 COEX signals and the radio RX/TX signals of the Bluetooth device connected to a logic analyzer.The radio TX/RX signals are active high signals so they are high if there is a radio activity ongoing
The GRANT signal configured to active low and it is always low. So, the Wi-Fi device always let the Bluetooth device to transmit or receive once it requested.
The REQUEST signal configured to active low. So, it is low when Bluetooth device requests the radio usage.
The PRIORITY signal is active low so the priority is high when the signal is low.
COEX signals in connectable advertising
At A1 marker, the REQUEST signal is active with high priority. After 500 usec at A2 marker, the TX starts followed by RX. Note that the actual radio operation starts 500 usec later then the REQUEST signal is active. This is because the HAL_COEX_REQ_WINDOW defined to 500 in hal-config.h.
The RX/TX sequence repeated for all 3 advertising channels. After the last RX, the REQUEST signal deactivated and the PRIORITY set to low.
COEX signals in scannig
During the scan interval, the REQUEST signal is active and the radio get RX interrupts as it is indicated by the RX signal.
COEX signals in connection
In a connection as slave device, EFR32 is receiving first, then transmitting. The actual radio operation is again delayed 500 usec after REQUEST because the configured request window.
How to add radio activity signals
For debug purposes, it is wise to enable radio RX/TX signals however these are not mandatory in real world application.
Adding the radio activity signals can be done in few steps. See this KBA about the process:
Or you can configure the radio signals directly with the code snippets below:
#include <em_cmu.h> #include <em_gpio.h> CMU_ClockEnable(cmuClock_PRS, true); // Enable PRS clock CMU_ClockEnable(cmuClock_GPIO, true); // Enable GPIO clock GPIO_PinModeSet(gpioPortC, 10, gpioModePushPull, 0); // Set PC10 GPIO mode to push-pull GPIO_PinModeSet(gpioPortC, 11, gpioModePushPull, 0); // Set PC11 GPIO mode to push-pull PRS->CH.CTRL = PRS_RAC_RX | PRS_CH_CTRL_EDSEL_OFF; // Set PRS channel 10 for RX PRS->CH.CTRL = PRS_RAC_TX | PRS_CH_CTRL_EDSEL_OFF; // Set PRS channel 11 for TX PRS->ROUTELOC2 &= ~_PRS_ROUTELOC2_CH10LOC_MASK; // Route the PRS ch 10 to LOC4(PC10) PRS->ROUTELOC2 |= PRS_ROUTELOC2_CH10LOC_LOC4; PRS->ROUTELOC2 &= ~_PRS_ROUTELOC2_CH11LOC_MASK; // Route the PRS ch 11 to LOC4(PC11) PRS->ROUTELOC2 |= PRS_ROUTELOC2_CH11LOC_LOC4; PRS->ROUTEPEN |= PRS_ROUTEPEN_CH10PEN | PRS_ROUTEPEN_CH11PEN; // Enable PRS signals
IEEE 802.15.2 (2003) Clause 6