Bluetooth Knowledge Base

      • BLE112 module antenna performance

        zovida | 12/342/2017 | 04:53 AM

        The carrier board design and the placement of the module strongly determine the module's antenna performance. In order to achieve the possible best RF performance the layout guidelines described in the module datasheet must be carefully followed.

        Additionally, here are some highlights in regards to the module placement recommendations below.

        - Place the module in the corner of the carrier board.

        - If placing the module in the corner is not possible then place the module at the carrier PCB edge and ensrue an at least 20 mm copper clearance keep-out area from the module antenna.

        - If the module is not being placed at the carrier board edge then the antenna gets de-tuned even if copper clearnace area is also ensured to the top direction from the antenna.

        - So, placing the module exactly to the corner or board edge of the carreir PCB is essential.

        - Also, try to avoid having any material in the close proximity (~ a few mm) of the module antenna. For metal material this minimum clearance is even higher, like 10-20 mm.

      • IAR 7.80.2 install package

        baadamff | 12/335/2017 | 09:04 AM

        Currently the Bluetooth SDK supports the IAR 7.80.2 and the GNU ARM v4.9.3. toolchains


        The IAR installer can be downloaded from here:


        The GNU ARM toolchain can be installed within Simplicity Studio package manager.



      • Custom communication over NCP

        baadamff | 11/327/2017 | 04:59 AM


        This article is demonstrating how to implement custom binary protocol between NCP target and host using specific features of BGAPI.

        BGAPI support

        Since Bluetooth SDK 2.6.0 the stack provides the following commands and events for that:

        • cmd_user_message_to_target
        • evt_user_message_to_host

        See the details in API reference manual [1].

        The cmd_user_message_to_target command can be used by an NCP host to send a message to the target application on device. To send a custom message with this API command the host have to send the byte sequence specified below to the target. Byte 4..255 can be the custom messsage itself.


        Once the target receives this byte sequence it must response with the byte sequence specified below. Byte 6 to 255 can be used for the custom response.


        Additionally, the evt_user_message_to_host event can be used by the target to send a message to NCP host. The target must send the byte sequence specified below.  Byte 4..255 can be the custom messsage itself.


        The native_gecko.h  provides a utility function which can send out the required byte sequence. See the declaration below.

         void gecko_send_evt_user_message_to_host(uint8 data_len, const uint8* data_data);  

        Example project

        In the attached example a user command handling framework has been added to the NCP example for demonstarting the feature. The framework calls handle_user_command function if a command ID is gecko_cmd_user_message_to_target_id.

        Default handle_user_command() is declared as weak so that user can override it in other source file of the application. In this example the handle_user_command() function overrided in the main.c

        The following codesnippets highlights the modifiaction against the default NCP example.

        Declaration of handle_user_command in ncp.h:

         * @brief
         * Called when a user command (Message ID: gecko_cmd_user_message_to_target_id)
         * is received.
         * @details
         * Implement this function if the BGAPI protocol is extended at application layer
         * between the host and target for data exchange. At the end of command handling,
         * a response to this command must be sent to the host. Use
         * gecko_send_rsp_user_message_to_target(uint16_t, uint8_t, uint8_t*) to send the
         * response.
         * The target can also initiate the communication by sending event messages
         * (Message ID: gecko_evt_user_message_to_host_id) to the host by using API
         * gecko_send_evt_user_message_to_host(uint8_t, uint8_t*).
         * Notice that events should not be sent in the context of user command handling.
         * @param[in] payload
         *   the data payload in the command message
        void handle_user_command(const uint8array *payload);

        The default implementation of handle_user_command() in ncp.c:

        void ncp_handle_command(){
        if (command_received()) {
            uint32_t *cmd_header = (uint32_t *);
            if (BGLIB_MSG_ID(*cmd_header) == gecko_cmd_user_message_to_target_id) {
            } else {
            // reset the buffer after the command is handled

        Application example

        The attached example echoes back the payload received from the host immediatly. Receiving the user message starts a 2 second long one shot timer.  To achive this the handle_user_command() has to  be overridden as it shown below.

         * handle for receiving message from the HOST
        void handle_user_command(const uint8array *payload)
          user_event_data_len = payload->len > USER_EVENT_DATA_MAX_LEN ? USER_EVENT_DATA_MAX_LEN : payload->len;
          memcpy(user_event_data, payload->data, user_event_data_len);
          /* Start one shot timer for generating a user event to demonstrate HOST to TARGET communication */
          gecko_cmd_hardware_set_soft_timer(2*SECOND, USER_EVENT_ID, 1);
          /* Loop back payload as a response */
          gecko_send_rsp_user_message_to_target(bg_err_success, payload->len, payload->data);

        Once the timer fires the target sends the previous payload again.

        /* soft timer fired event */
        case gecko_evt_hardware_soft_timer_id:
           /* check which softtimer fired */
           if (evt->data.evt_hardware_soft_timer.handle == USER_EVENT_ID) {
           /* user event can be sent out to HOST */
           /* echo the last custom message from the HOST */
              gecko_send_evt_user_message_to_host(user_event_data_len, user_event_data);

        Testing the example

        In SDK 2.6.0 the BGTool not supports the user event and command APIs. Therefore a terminal needed which supports binary communcation. On PC you may use H-Term [2].

        Terminal settings

        The attached example is using 115200 baud 8N1 with no flow control over J-Link USB CDC virtual COM port. 

        Communication sequence

        The caputered log below shows that first we sent a user message from the host to target with the payload 0x02 0x55 0xAA then the target sent back a response with the same payload.

        Then a timer event happened. After that a user message event occured with the same payload.



        [1] c:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v2.0\app\bluetooth_2.6\doc\bluetooth-api-reference.pdf


      • Throughput Tester Example

        tmonte | 11/325/2017 | 02:02 PM


        This article contains a throughput tester example which allows testing under a varying combination of parameters such as connection interval, MTU size, PHY and ATT operation (acknowledged on non-acknowledged)

        To understand how the aforementioned parameters affect throughput with Bluetooth Low Energy please read through our Throughput article.


        Creating the Throughput Tester Project

        Attached you can find a main.c and a gatt.xml files. With these you can create the throughput tester project for any of our radio boards based on EFR32xG1x or BGM modules. The steps to create the project are as follows:

        1. Create an soc-empty project for the desired radio board based on SDK 2.6.0
        2. Import the attached gatt.xml to VGE and press Generate
        3. Follow the WSTK LCD KBA steps 1-3 but careful that the paths for the source files are pointing to Gecko SDK 1.0, make sure to copy the files from Gecko SDK 2.0. You can either link to the source files or actually copy them. 
        4. Add this to the include paths: ${StudioSdkPath}/hardware/kit/common/drivers
        5. Add this to hal-config.h: #define HAL_SPIDISPLAY_FREQUENCY                      (1000000)
        6. Copy C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v2.0\platform\emdrv\gpiointerrupt\src to C:\Users\<your username>\SimplicityStudio\v4_workspace\<your project name>\platform\emdrv\gpiointerrupt
        7. Overwrite main.c with the attached file
        8. If you’re on xG13 platform add the function below to init_mcu.c and call it at the end of initMcu(). Finally include also em_rtcc.h at the top of the file.
        static void initMcu_RTCC(void)
              /* Enable clock to LE modules */
              CMU_ClockEnable(cmuClock_CORELE, true);
              /* Enable clock for RTCC */
              CMU_ClockEnable(cmuClock_RTCC, true);
              RTCC_Init_TypeDef rtccInit = RTCC_INIT_DEFAULT;
              rtccInit.enable                = true;
              rtccInit.debugRun              = false;
              rtccInit.precntWrapOnCCV0      = false;
              rtccInit.cntWrapOnCCV1         = false;
              rtccInit.prescMode             = rtccCntTickPresc;
              rtccInit.presc                 = rtccCntPresc_1;
              rtccInit.enaOSCFailDetect      = false;
              rtccInit.cntMode               = rtccCntModeNormal;


        Testing the Project

        The example has 2 modes, slave and master, so that the same firmware can be used to test between 2 of our radio boards. The mode is selected via PB0 after releasing reset, if PB0 is not pressed it will start as slave, if it's pressed it will start as master and connect to any device which has "Throughput Tester" as device name. The slave mode allows testing throughput against third-party devices, namely smartphones.

        In the GATT there is a service (UUID: bbb99e70-fff7-46cf-abc7-2d32c71820f2) which contains the characteristics used to exchange data for measuring throughput. One characteristic is for testing unacknowledged operatings using notifications (UUID: 47b73dd6-dee3-4da1-9be0-f5c539a9a4be) and another is for testing acknowledged operations using indications (UUID: 6109b631-a643-4a51-83d2-2059700ad49f). The GATT client can subscribe to either of these in order to receive data from the device.

        Then, once those are subscribed, you can press PB0 to push notifications or PB1 to press indications to the GATT client. Data will be sent by the application as fast as the stack allows. The LCD display refresh will halt for as long as the buttons are pressed.

        If you are working with 2 WSTKs and namely with EFR32xG13 devices which support all PHYs, it's possible to change the PHY by pressing PB0 on the master side. The PHY change will be shown on both device's LCD.

      • Bluetooth advertising using manufacturer specific data

        JaakkoV | 11/318/2017 | 02:00 AM


        The basic structure of advertising packets and how to the advertising data is set was covered in article Bluetooth advertising data basics. This article focuses on one specific type of advertising type: Manufacturer Specific Data (type 0xFF).

        Manufacturer specific data can be used to add any custom data into advertising packets, using any format that is suitable for your application. For example, you could create a beacon that includes the reading of a temperature sensor it the advertising data.

        Custom advertising data example

        Let’s assume the following requirements for a BLE beacon:

        1. The device must include its name in advertising packets
        2. The advertising data must also contain a counter value that changes dynamically

        We want to advertise the device name so that it is easy to identify the device using any BLE capable smartphone app, such as the Blue Gecko app for Android / iOS.

        To demonstrate dynamic changing of advertising payload, the counter is incremented/decremented when pushbuttons PB1/PB0 on the development kit are pressed. Let’s use one byte for the counter value, meaning that the range is 0..255. As an additional feature, we will also include one byte to indicate which button was pressed last.

        Example of an advertising packet that contains the device name and the 8-bit counter value is shown below.

        This advertising packet consists of three elements (as explained in the advertising data basics article):

        1. First element is the flags
        2. The second elements contains the counter value and an indication of which button was pressed last
        3. The third and last element is the device name

        The second element uses type 0xFF indicating manufacture specific data, meaning that we can formulate the data (almost) any way we want. The other two elements are using predefined AD types.

        Note that the custom AD element is formatted using the same convention as any other elements. It begins with a length indicator so that any client receiving this data can still parse the advertising packet element by element and simply jump over those elements that it does not know how to decode.

        The first 2 octets contain the Company Identifier Code. Company Identifiers are listed at remaining bytes in the custom element can be used for any purpose. The total size of the packet obviously cannot exceed the maximum size that is 31 bytes.

        In the example used in this article, the company ID is followed by two additional bytes: one to represent the number of button presses (zero in above example) and another byte to indicate which button was pressed last (0xFF in above example, meaning neither button has been pressed so far).

        Using custom advertising data with Silicon Labs Bluetooth SDK

        The following two API calls are needed to use custom advertising (and scan response) data:

        • cmd_le_gap_set_adv_data
        • cmd_le_gap_set_mode

        The first call is used to set the advertising data content before starting advertisements. Calling gap_set_mode starts the advertising. When using  custom data, it is important to note that the first parameter (discoverable mode) must be set to le_gap_user_data (value 4).

        Alternatively, you can use the following API calls if you prefer to use the new BT5 API that adds support for advertising sets:

        • cmd_le_gap_bt5_set_adv_data
        • cmd_le_gap_bt5_set_mode

        The code sample included in the next section sets up advertising using the custom format defined earlier in this article.

        Code sample

        The attached zip file includes sample code to demonstrate how to set custom advertising data. Functions for initializing and updating the custom advertising data content are found in custom_adv.c/h.

        This code can be easily added on top of the SoC Empty example. There are two main files provided in the package:

        • main_242.c (modified SoC Empty from BLE SDK 2.4.2)
        • main_260.c (modified SoC Empty from BLE SDK 2.6.0)

        To locate the code that is used to set up and update custom advertising, see event handlers for gecko_evt_system_boot_id and gecko_evt_system_external_signal_id.

        The example uses GPIOINT driver from EMDRV to handle button interrupts. Therefore you need to also add file gpiointerrupt.c to your project. It can be copied from the platform directory in the SDK installation. The paths for SDK 2.4.2 and 2.6.0, respectively, are shown below:


      • How to use Voice over Bluetooth Low Energy example for Thunderboard Sense

        tmonte | 11/317/2017 | 07:15 AM


        The SDK version 2.6.0 introduces a new example for the Thunderboard Sense (TB Sense) called SOC – Voice over Bluetooth Low Energy which samples data from the analog microphone on TB Sense, runs it through a filter and codec and sends it over the Bluetooth link to a GATT client.

        The GATT client application is also made available as source code in C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v2.0 \app\bluetooth_2.6\examples_ncp_host\voice_over_bluetooth_low_energy_app. You need to install a tool such as cygwin to build the project into an executable.


        How to Use It

        To test this solution you need one TB Sense and one WSTK with any of our EFR32xG or BGM radio boards.


        hunderboard Sense (GATT Server)

        For the TB Sense side you can simply open the SOC – Voice over Bluetooth Low Energy and flash it as is. The only option available in this application is which type of filter you want to use. The filter types are listed in filter_type_t in filter.h.

        /** Filter types */
        typedef enum {
          LPF,     /**< Low Pass Filter        */
          HPF,     /**< High Pass Filter       */
          BPF,     /**< Band Pass Filter       */
          NOTCH,   /**< Notch Filter           */
          PEQ,     /**< Peaking Band EQ Filter */
          LSH,     /**< Low Shelf Filter       */
          HSH      /**< High Shelf Filter      */

        The default filter is HPF which is defined in DEFAULT_FILTER in the same file so here you can change to any other of the available filters.

        /** Default filter */
        #define DEFAULT_FILTER                       \
          {                                          \
            HPF,  /** Default filter type */         \
            0,    /** Default gain */                \
            100,  /** Default frequency */           \
            8000, /** Default sampling rate */       \
            2,    /** Default bandwidth in octaves*/ \


        WSTK (GATT Client)

        On the WSTK side you can simply flash the pre-compiled NCP target – Empty example for the specific radio board that you are using to enable communication with the PC.

        Then open a command line prompt, navigate to the directory where the host side executable is located and run voice_over_bluetooth_low_energy_app.exe to get the help menu.

        Let’s go through each the options here:

        • COM Port: this is the COM Port for your NCP device, you can check it using BGTool, the WSTK lists as a “JLink CDC UART Port”.
        • Baud rate: NCP-empty example has 115200 by default and there is no need to change this
        • Output file name: filename where you want your audio data to be stored in, it doesn’t need to have any extension.
        • Remote device Bluetooth address: Bluetooth address of the TB Sense board that you are using as GATT client. This can be read using the Commander as instructed at the beginning of this article.
        • ADC sampling rate: the options are 16kHz or 8kHz, you only need to put the number e.g. –s 16
        • ADC resolution: the options are 8 or 12 bits, only number is needed as well e.g. –r 12
        • Enable/Disable filtering: default is disabled if you omit this option. To enable it write –f 1
        • Enable/Disable notification for Audio Data characteristic: this can be omitted
        • Help: prints out the help shown in the above image (which is also printed if you call the executable without any arguments)
        • Verbose: If this switch is added the application prints out status messages


        Running the Solution

        With the firmware SOC – Voice over Bluetooth Low Energy flashed into the TB Sense and the NCP – empty flashed into the radio board on the WSTK you can bring up the command prompt and navigate to the directory where the GATT client application executable is located. Then call the executable with your chosen sampling rate, resolution and output file name. In the example below we are using the maximum for both sampling rate and resolution (16kHz and 12 bits respectively) and saving the audio data in a file called my_audio_file.

        If you have activated verbose as in the above image you will get status messages from the GATT client application. The application will stop printing status messages after is has written all the configurations which in the above image is after enabling filtering. At this stage the application is just waiting for notifications from the GATT client with the audio data so it can be stored in the chosen file.

        You can then press SW1 button in the TB Sense to start streaming audio data and SW2 to stop streaming. All the audio data will be saved into the same file and if the file name given as parameter already exists then the audio data will be appended to the existing file.


        Importing to Audacity

        To listen to the audio you can use a freeware tool such as Audacity to import and decode the data. In Audacity select File -> Import -> Raw Data and select the audio file you have created. The select VOX ADPCM encoding and write down the sample rate that you used, either 8000 or 16000 Hz. In this example 16000 Hz was used.

        Once the file is imported you can listen to it by pressing the Play button on the top left corner. Then you can export the file to wav format through File -> Export Audio and upload it to Watson’s Speech to Text to get a speech transcription.


        How it Works

        The block diagram below summarizes the data flow from the analog microphone into the Bluetooth link.

        The EFR32 on the TB Sense samples the analog microphone using the ADC with the sampling rate and resolution configured by the GATT client. The sampled data is then run through a digital filter (if the filter usage is enabled) and coded using ADPCM codec before being sent via the Bluetooth link to the GATT client using notifications.

        On the GATT client side, the application starts by sending the configurations to the TB Sense and then it just waits for the audio data to be sent over notifications and stores into a file.

      • How to Import a Bluetooth Project into Simplicity Studio

        tmonte | 11/313/2017 | 04:17 AM

        To import a Bluetooth project into Simplicity Studio IDE do the following steps:

        • File -> Import
        • Select General - > Existing Projects into Workspace
        • Then you can select either the project directory (Select root directory) or a zip file containing the project (Select archive file)
        • Finish


      • Enabling Coexistence Feature in Bluetooth SDK projects

        baadamff | 11/311/2017 | 06:21 AM


        This KBA summarizes the Coexistence feature then walks through on how to enable the feature in a Bluetooth SDK project. Finally, it shows how the Coexistence signals behaves while the Bluetooth device advertising, scanning or in connection.

        What is Coexistence?

        Coexistence 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 described in IEEE 802.15.2 (2003) Clause 6. PTA 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.

        3-Wire PTA

        There are 1, 2, 3 and 4 wire PTA implementations exist. Silicon Labs Bluetooth SDK 2.6.0 supports the 3 wire PTA implementation which is the most common used in Wi-Fi devices. In later SDK versions the 1 and 2 wire options will be supported also. 

        In 3-Wire PTA 3 signals defined

        • GRANT
        • REQUEST
        • PRIORITY




        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. Unfortunately, the BLE SDK 2.6.0 release does not let to disable a PTA pin. However, it is possible to redirect PRIORITY to a not connected GPIO or even to an unbonded GPIO pad for given package.

        Project setup

        To enable the Coexistence 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.

        Coexistence library path is depending on the MCU variant and the complier. See the default path for EFR32BG1B device using GCC complier


        The Coexistence 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. 


        Coexistence configuration

        Once the libcoex.a library added to the project the Coexistence 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


        Coexistence API

        The Coexistence 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.

        Runtime options

        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:

        • Enable/disable coexistence: coex_option_enable
        • Abort TX in GRANT denial: coex_option_tx_abort
        • Enable/disable high PRIORITY: coex_option_high_priority


        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. 

        Coexistence signals in practice

        In this setup, all 3 Coexistence 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.

        Coexistence 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.

        Coexistence 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.

        Coexistence 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[10].CTRL = PRS_RAC_RX | PRS_CH_CTRL_EDSEL_OFF; // Set PRS channel 10 for RX
          PRS->CH[11].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_CH11LOC_MASK;        // Route the PRS ch 11 to LOC4(PC11)
          PRS->ROUTEPEN  |= PRS_ROUTEPEN_CH10PEN | PRS_ROUTEPEN_CH11PEN; // Enable PRS signals

        GPIO pins

        On the Bluetooth device 3 GPIO pin is need to be assigned for the REQUEST, PRIORITY and GRANT signals. For the optional RX/TX signals 2 more GPIO pin is needed.

        PRS channel allocation

        The REQUEST, PRIORITY and GRANT signals doeas not require PRS channels. But for the optional RX/TX signals 2 PRS channel is needed.

        In Bluetooth SDK 2.6.0 PRS channel 7 is allocated to the Bluetooth stack so it can not be used for the RX/TX signals. PRS channel alloaction may change in the fututre so please check the UG136 chapter 7 for the unused PRS channels.


        IEEE 802.15.2 (2003) Clause 6



      • BGM12x模块在layout的时候PIN53与PIN54一定不要直接相连

        JunFan | 11/311/2017 | 02:10 AM
      • BLE主设备以及GATT客户端例程(连接安卓手机)

        Kevin_Fu | 11/306/2017 | 03:32 AM







        1. 主设备扫描附近的广播,你可以加入广播过滤逻辑来确定哪个或者哪些广播的设备是你需要连接的,如过滤设备名称、服务UUID等。
        2. 如果找到设备,建立连接。
        3. 连接之后,扫描远端设备所支持的所有服务以及特征值。
        4. 对于具有通知(notify)或者指示(indicate)的特征值,如果有需要,配置Cline Characteristic Configuration(CCC)的值,其含义如下。
        • 0x0000 – 禁止
        • 0x0001 – 使能通知
        • 0x0002 – 使能指示





        • 一个EFR32BG或者EFR32MG开发板 – 本例程是直接基于BRD4103A Rev A01(EFR32BG12 radio board)开发的,但他可以很简单的移植到其他开发板或客户的板子。
        • 一个安卓智能手机 – 请确保此智能手机在硬件和软件上都支持BLE,安卓从3版本开始在软件上支持BLE。


        我加入了一个叫做“Demo service”的服务到GATT服务器,其包含了2个特征值,分别叫“NOTIFY_CHAR”和“RW_CHAR”,具体信息如下:



                            UUID                    属性

        Demo Service    df6a8b89-32d1-486d-943a-1a1f6b0b52ed


        NOTIFY_CHAR     0ced7930-b31f-457d-a6a2-b3db9b03e39a     通知

        RW_CAHR        fb958909-f26e-43a9-927c-7e17d8fb2d8d     读、写



        我将源代码附在了文件末尾,其基于BRD4103A Rev A01(EFR32BG12 radio board)和Bluetooth SDK v2.4.0.1开发的,同时安卓的APP安装文件也附上了。遵循如下步骤来让例程跑起来。

        1. 将工程导入Simplicity Studio v4中,加入symbol “RETARGET_VCOM”的定义,这样打印信息会被发送至USB口,编译并将工程下载至开发板。如果想了解更多RETARGET_VCOM的相关信息,可以参考下面文章。

        1. 你也可以跳过第一步,直接将“Central_Example.hex”文件烧录至开发板,并将apk文件安装至安卓手机。
        2. 打开串口工具来查看打印信息,打开app,手机和开发板会自动建立连接,并使能通知,手机会定时发送通知给开发板。
        3. 按PB0会将0x01和0x05来回地写入RW_CHAR特征值中,这个特征值的值决定了发送通知的周期。例如:特征值的值是5,那么手机会每隔5秒钟发送一次通知。







        三星 Galaxy Tab S3


        魅族 MX_4




        ·         CCC descriptor – CCC descriptor has the UUID 0x2902, but Android doesn’t support 16-bit UUID, so it needs to be change to 128-bit UUID - 00002902-0000-1000-8000-00805f9b34fb. The API gecko_cmd_gatt_set_characteristic_notification will return error that it can’t find CCC descriptor with UUID 0x2902 in the characteristic. So, I write the next handle of NOTIFY_CHAR which is the location of CCC descriptor of this characteristic on the server side as workaround. This problem didn’t happen when I tested with Android 7.0 devices.


         安卓APP的源代码可以在这里下载 -