At the end of the knowledge-base article at http://community.silabs.com/t5/Bluetooth-Wi-Fi-Knowledge-Base/BT121-Legacy-pairing-and-fixed-PIN-code-or-Passkey/ta-p/173703 the lack of a mechanism in the Secure Simple Pairing (SSP) framework to always force a fixed/known PIN code to be entered at both sides during the pairing procedure was discussed. Conclusion was that, with a device with no input nor output capability having Just-works as the only possible pairing mechanism, the only way to have authentication/authorization is by mean of security at the application level.
In this knowledge-base article we are presenting an idea of how to implement some security at the application level (in a BGScript in particular) for both BLE and the Serial Port Profile in the Bluetooth Classic. In the latter case this will be a BGScript version of the C implementation seen in the main.c of the host example program under the directory \host_example\spp_server\ of the SDK (since version 1.1.1 build 168) where the first incoming string over the RFCOMM link is parsed and checked against a secret string in the code before the data exchange can continue.
The starting point is the script in the example project under the directory \example\bgdemo\ of the SDK. This is being modified to provide the authentication/authorization at the application level which is missing in the original example, where the Just-works mode is configured with the “call sm_configure(0,3)” under the system_initialized event, and where security is never increased with the command sm_increase_security while a BLE connection is ongoing. The resulting script is called "bgdemo_enh.bgs" and is found inside the zip file attached to this case. The rest of the article gives a short description of the main changes and added parts enabling the additional security.
At first, the script introduces a couple of constants (holding the secret code and the length of the secret code) and a couple of variables (a buffer to compare the incoming SPP data with the constant buffer, and an index to take into account that it might take multiple events to get the code from the remote party):
const secret_code() = "12345"
const secret_code_len = 5
dim secret_compare(260)
dim secret_compare_index
Starting with the Bluetooth Classic part, the first major change happens under the system_initialized event where the streaming_destination parameter of the command bt_rfcomm_start_server is changed to be the script itself:
call bt_rfcomm_start_server(2,1)
The impact of this modification is that, upon any new RFCOMM-based SPP connection, all the incoming data from the remote party is directed to the script for being processed by the script itself. In this way, we can control the incoming data and for example arrange so that the very first incoming bytes will have to match those of the secret code for the connection and other operations to then proceed as in the original script. This is possible thanks to the code below being added to the original script:
event endpoint_data(endpoint, data_len, data_data) # Let's capture the incoming data just after the connection is established and until the secret code can be read
if (endpoint = rep) then
memcpy(secret_compare(secret_compare_index), data_data(0), data_len) # Let's fill the variable buffer with data from the remote party - This is the data that will be compared with the secret code
secret_compare_index = secret_compare_index + data_len
if (secret_compare_index < secret_code_len) then # We have not yet received enough data to compare with the secret code
call endpoint_send(0,,"More characters needed to verify secret code...\r\n")
else
if memcmp(secret_compare(0), secret_code(0), secret_code_len) then # We have enough data in the variable buffer to compare with the constant buffer holding the secret code
call endpoint_send(0,,"Secret code match, transparent SPP comunication can continue...\r\n")
if (secret_compare_index != secret_code_len) then # We happen to have more bytes in the variable buffer than in the secret code, so the rest of the bytes are user data that we must send out of the UART
call endpoint_send(0, secret_compare_index - secret_code_len, secret_compare(secret_code_len:secret_compare_index - secret_code_len)) # Does not send the secret code
#call endpoint_send(0, secret_compare_index, secret_compare(0:secret_compare_index)) # Sends also the secret code if desired
end if
call endpoint_set_streaming_destination(endpoint,0) # Let's map the data from the remote side directly to the UART for the full transparent data in both directions from now on, like in the original bgdemo
call hardware_set_soft_timer(1000,0,0) # Start the repeating timer that in the original bgdemo is always started at boot (under the system_initialized event) and continue like in the original bgdemo example
else
call endpoint_send(0,,"Secret code mismatch or not enough data, communication will be closed in 1s!\r\n")
call hardware_set_soft_timer(1000,1,1) # Timer needed here because it is not allowed to use endpoint_close under the endpoint_data event
end if
secret_compare_index = 0
end if
end if
end
By the endpoint_send commands the script is sending status messages out of the UART interface until the secret code is verified, and the transparent data exchange over UART can re-start, as in the original script, following here the “call endpoint_set_streaming_destination(endpoint,0)”. Please, follow the comments in the code and the UART status messages to realize what is going on. In case of a code mismatch the script will close the connection without allowing further data exchange. In the ideal case the endpoint_close command would be issued together with the code above, but since it is not possible for such command to appear under the endpoint_data event according to the API reference, a single-shot timer is started with handle of 1 and the SPP connection will be closed when the timer times out, under the event hardware_soft_timer as seen below:
event hardware_soft_timer(handle)
if handle = 1 then
call endpoint_close(rep) # This command is used to close both le and br/edr connections (using connection ID or RFCOMM endpoint respectively - we are using the variable rep for both for simplicity)
rep = -1
return
end if
[…]
end
Let’s see now how authentication/authorization is implemented for the BLE part. In the approach proposed here, a custom Service and a custom Characteristic are added to the GATT database via the gatt.xml project file, as seen below:
The characteristic with an arbitrary 128-bit UUID, of fixed length equal to the length of the secret code, whose handle number is held in the BGScript by the constant called “security”, is to be written by the remote GATT Client with the exact secret code within a desired timeout since the connection is opened, otherwise the connection is automatically closed. As in the case of the Classic connection, here is the added code with the comments and status messages explaining the functionality:
event le_connection_opened(address, address_type, master, connection, bonding)
rep = connection # Let's reuse the rep variable for simplicity, assuming there will not be le and br/edr connections at the same time
call endpoint_send(0,,"BLE connection opened. 5s to execute SSP pairing and/or security increase...\r\n") # Debug message out of UART
call hardware_set_soft_timer(5000,1,1) # Let's launch a 5s one-shot timer with handle of 1 - At timeout we will be closing the connection if the normal Bluetooth Just-works pairing has not happened
call sm_increase_security(connection) # Start encryption to protect the secret code written by the other side - Once connection is secured, the event le_connection_parameters with security_mode set to 1 will be triggered (see below)
end
event le_connection_parameters(connection, interval, latency, timeout, security_mode, address)
if connection = rep && security_mode = 1 then # If pairing has happened and encrypted connection is started
call endpoint_send(0,,"Just-works SSP pairing successful. 10s more to write secret code...\r\n") # Debug message out of UART
call hardware_set_soft_timer(0,1,1) # Stop the running 5s one-shot timer with handle of 1
call hardware_set_soft_timer(10000,1,1) # Let's launch a 10s one-shot timer with handle of 1 - At timeout we will be closing the connection if the intended characteristic for security will not be written by the remote application with the expected secret code
end if
end
event gatt_server_attribute_value(connection, attribute, att_opcode, offset, value_len, value_data)
if connection = rep && attribute = security && memcmp(value_data(0), secret_code(0), secret_code_len) then # If the correct secret code was written to the intended characteristic within 10s from opening the connection
call endpoint_send(0,,"Correct secret code written to intended characteristic. Communication can continue...\r\n") # Debug message out of UART
call hardware_set_soft_timer(0,1,1) # Stop the 10s one-shot timer with handle of 1
call hardware_set_soft_timer(1000,0,0) # Start the repeating timer that in the original bgdemo is always started at boot (under the system_initialized event) and continue just like in the original bgdemo example
end if
end
As can be noticed, as soon as the BLE connection is opened the sm_increase_security command is launched to get the Just-works pairing to happen within 5 seconds. This is the first security step for all the GATT transactions to become encrypted. After pairing and bonding, another timer (also with handle of 1) is started and the remote GATT Client is given a limited interval (10 second here) to write the secret code to the dedicated Characteristic. Upon the GATT Server communicating to the script via the event gatt_server_attribute_value the received code, this is compared against the secret code which is hardcoded in the script, and only in case of a match the timer is stopped, otherwise it will naturally expire and the timer timeout will trigger the same endpoint_close as in the RFCOMM-based case (where the “rep” variable in this case is not the RFCOMM endpoint but is being re-used as the BLE connection handle.)
This article demonstrates how to use an external MCU to upgrade Silabs Bluetooth devices under NCP mode. It aims to provide a base code, which is as simple as possible, to make it can be easily migrated to the real use case. Before starting with this article, please have a look at the below resources.
UART DFU host example provided in the Bluetooth SDK. If you have downloaded Simplicity Studio and Bluetooth SDK, you will find it in "C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v2.5\app\bluetooth\examples_ncp_host\uart_dfu".
Above resources could be a good starting point, you can get information such as what is NCP mode, how to generate gbl file, how to do a simple DFU and verify it, etc.
Environments
SDK – Simplicity Studio, 32-bit MCU and Bluetooth SDK (The latest version to the date is always recommanded)
Kits – EFM32PG(SLSTK3401) acts as NCP HOST and any Bluetooth compatiable EFR32 board acts as NCP TARGET
Serial configuration
Baud rate: 115200
Data bits: 8
Stop bit: 1
Flow control: False
Connection and peripherals
Both kits are powered by USB. The connection between them is shown as below table.
Expansion header on EFM32PG
Expansion header on EFR32BG
GND
GND
Pin 9 (PD10) - UART TX
Pin 14 (PA1) - UART RX
Pin 11 (PD11) - UART RX
Pin 12 (PA0) - UART RX
Getting Started With the Sample Code
A simple way to verify the UART DFU is to program a firmware firstly, then use the host device to upgrade it with another firmware. Use the difference between these 2 firmwares to identify the success of UART DFU.
Create Gecko Bootloader
To use the UART DFU functionality, make sure you have flashed the "BGAPI UART DFU Bootloader" to your board.
NOTE: the UART settings of the gecko bootloader project should align with the NCP target. Follow below steps to create and program the Gecko bootloader to your board.
Create "BGAPI UART DFU Bootloader" from the latest Gecko Bootloader SDK.
Open the $project_name.isc file and click on "Plugins" -> "UART, provides API: uartDriver", modify it to align with your UART settings. Use the default value for the sample project. Click the "Generate" button on the top-right corner.
Comment out the HAL_VCOM_ENABLE symbol definition in hal-config.h file in the project.
Compile the project and flash the output file named ${project_name}-combined.s37 to the NCP target board.
Create the NCP Target and GBL File
A simple way to identify the success of device firmware update is by the device name. The default device name in the "NCP target - Empty" project is "BLE Device", we will firstly program the board with this name, then generate a GBL file with a different name. Finally, we use the EFM32PG board to upgrade it, and use the name to verify if it succeeds. Follow below steps to create and flash the NCP target for the EFR32BG board.
Create "NCP target - Empty" project from the latest SDK.
Open the hal-config.h and modify below 2 symbol definitions
Open the ${project_name}.isc file, click the "Device Name" in the right part of the page, the modify the value in "Value" label, e.g. "UART DFUed", then click "Generate" button.
Compile the project and double click the "create_bl_files" script in your project. It will generate a folder named "output_gbl" and full.gbl in it. Ignore the other files which are used for OTA.
Copy the full.gbl to full.bin then record its size in byte.
Create the HOST application
The host application will read the GBL file as stream, then send it to the NCP target device after it is booted into DFU mode. Programming the gbl file to its unused area of flash is the simplest way for a host application to read it out.
Create "SLSTK3401A_vcom" from the latest 32-bit MCU SDK.
Copy and paste all the files in the attachment to the 'src' folder of project.
There are 2 parameters needed to pass to the application.
The GBL_FILE_START_ADDR is the starting address you program the full.bin to, and the GBL_FILE_SIZE is the recorded file size in the previous step 6. 4. Use Simplicity Commander to flash the full.bin file with offset GBL_FILE_START_ADDR. See figure 1. 5. Build and flash the EFM32PG board.
Figure 1. Simplicity Commander
Verify it
Connect the 2 device - EFM32PG and EFR32BG boards, and press the reset button on EFM32PG board to sync up.
Use Blue Gecko smartphone app to see the current advertising device name.
Open a serial terminal connecting to the EFM32PG board VCOM to get debug information. See figure 2.
Press the button 0 on EFM32PG board to start UART DFU.
After the UART DFU is done, use the Blue Gecko to verify the device name is changed.
In the previous article we wanted to demonstrate how to enable the SPI communication with the accelerometer and the display which are integrated in the DKBT. The accelerometer in particular was read so to turn on and off the DKBT’s LEDs depending on the orientation of the board among others.
On the other hand, the example in the SDK is meant to demonstrate how the module can be used to enable a simple wireless mouse based on the Bluetooth Classic’s HID profile. With this example, the mouse pointer is remotely moved up and down, left and right, by pressing the DKBT’s buttons.
With the example project files shared here, we want to turn the DKBT into a Bluetooth “air” mouse, allowing the mouse pointer to be remotely moved similarly, but controlled instead by the orientation of the board being revealed by the regular accelerometer’s readings over the SPI interface while the board is being tilted.
Another important reason for sharing this project is to disclose a new command which is dedicated to reading and writing data over the module’s SPI interface: this new command is introduced since version 1.1.1 build 168 of the firmware/SDK and is called cmd_hardware_read_write_spi . This is a very handy command in that it activates at the same time SPI data writing and data reading and Chip Select (CS) signaling, all in all replacing with a single command the sequence of commands and events cmd_hardware_write_gpio + cmd_endpoint_send + evt_endpoint_data + cmd_hardware_write_gpio seen in the previous article for the same functionality, while removing the limitation of having to wait for a short interval before returning the CS line to the un-select state, which was also a point of concern in the previous article.
Also with this example project the most of the discussion goes for the BGScript called here air_mouse.script.bgs .
Among the rest of the project files (most already covered in the application note and in the previous article mentioned above), the hardware configuration file called hardware.xml and the gatt.xml defining the GATT database are worth an annotation: the latter is not so critical, given that in this example the BLE part is not touched, however it has been simplified by removing the Health Thermometer Service (a leftover in the project from the previous article), while the option sdp="false" has been added to the <service … > tags in order to prevent the two mandatory GATT services to be loaded as SDP records in addition to the DID and HID records.
As for the hardware-related file, the configuration of the SPI interface is as demanded by the DKBT, the UART interface is kept enabled, this time not for debugging purposes but to enable the DFU re-programming of the module, while the GPIOs in use are configured, some as output (we are still turning on and off the LEDs here when the mouse pointer is being moved) and one as input (for the mouse left-button press when connected, or for restarting into DFU mode when not connected), as seen below from the xml file:
<!-- Accelerometer CS is PA13 -->
<port index="0" output="0x2000"/>
<!-- GPIOs connected to DKBT's LEDs 2 to 5 as output -->
<!-- GPIO connected to DKBT's button 1 as input-interrupt -->
<port index="1" output="0x3600" input="0x100" interrupts_rising="0x100"/>
Back to the script, let’s see now the (new) parts worth of note (the rest is either commented in the script itself or already discussed in the previous article and in the application note.)
When the module is started the two events system_boot and system_initialized are triggered in a sequence. Within the latter we notice the same calls we are seeing in the other scripts as well, so nothing to add here. Under the system_boot event we are configuring the initial state of the output GPIOs, in particular the one connected to the accelerometer’s CS pin is set to high, while all of those connected to the DKBT’s LEDs are set to high as well, but only after the accelerometer is initialized correctly, things that happen also in the system_boot event using for the first time the new command hardware_read_write_spi . This all is summarized in the code below:
event system_boot(major,minor,patch,build,bootloader,hw)
[...]
# Accelerometer CS line high - It will be toggled low then high by the hardware_read_write_spi which will use active low for the pin polarity
call hardware_write_gpio(0,$2000,$2000)
# Here setting the accelerometer into measurement mode - POWER_CTL (register 0x2D) to 0x08 to set the Measure Bit
call hardware_read_write_spi(spi_channel, acc_cs_port, acc_cs_pin, acc_cs_polarity, 2, 2, "\x2d\x08")(resp_result, resp_data_len, resp_data(0:resp_data_len))
if resp_result = 0 then
# With the accelerometer initialized, set a repeating software timer with handle of 1 to timeout every 200ms so to regularly trigger the accelerometer's x-axis and y-axis readings
call hardware_set_soft_timer(200,1,0)
# All LEDs turned on after the accelerometer is initialized and until a HID connection is established
call hardware_write_gpio(1,$3600,$3600)
end if
end
With the new command hardware_read_write_spi there is no more need to worry about separate commands to control the CS line or additional events to read the data coming from the sensor: all is taken care by the command itself, and the data from the sensor is carried directly by the response to the command.
Above we are also seeing that a repeating timer is started once the accelerometer is initialized. Every time it times out, the code checks if a HID connection is ongoing, and only in that case the sensor is read, then all LEDs are turned off, and finally the value from the sensor is verified for the mouse to be moved (by sending the appropriate HID report with the call bt_hid_send_input_report) and for the intended LED to be turned on, depending on the board orientation. This is summarized in the simplified code below:
event hardware_soft_timer(handle)
if hid_connected then # Let's process the calls under the hardware_soft_timer only if a HID connection exists
# Read values from the accelerometer - Notice that the received data in resp_data(2:1) holds the most significant byte of the twos complement x-axis measurement while resp_data(2:1) the least significant (and the same is valid for the y-axis measurement...)
call hardware_read_write_spi(spi_channel, acc_cs_port, acc_cs_pin, acc_cs_polarity, 5, 1, "\xf2")(resp_result, resp_data_len, resp_data(0:resp_data_len))
# Let's turn on and off the LEDs depending on the DKBT orientation and move the mouse pointer accordingly
call hardware_write_gpio(1,$3600,$0) # All LEDs off except in one of the cases below
if (resp_data(2:1) & $3) = $1 then # When output data for the x-axis is positive and above 255 (that is, above 0.510g - resolution is 10 bits and range is +-g and scale is 2mg/LSB)
# Only LED2 (PB9) is turned on
call hardware_write_gpio(1,$3600,$200)
# Send a HID report corresponding to moving the mouse pointer 10 pixels down
call bt_hid_send_input_report(hid_endpoint, 2, 3, $0a0000)
return
end if
[...]
end if
end
In the script, events like endpoint_status and endpoint_closing and bt_hid_state_changed exist to take care of the Bluetooth HID connection and disconnection. They are used for example to set the variable indicating if the connection is ongoing, and in case of disconnection to turn all LEDs on, like at the start.
The last important part of the script is shown below and refers to the handling of the interrupt triggered by the press of the button 1 of the evaluation board. Pressing it while a connection is ongoing translates into the HID report being sent to the HID-Host for the mouse button click. Pressing it at a time when there is no connection triggers a reset of the module into DFU module allowing the re-programming of the module using the BGAPI-based DFU commands.
event hardware_interrupt(interrupt,timestamp)
# When button 1 (PB8) on the evaluation board is pressed while a HID connection exists
if interrupt = $100 && hid_connected then
# Send a HID report corresponding to main (left) mouse button click
call bt_hid_send_input_report(hid_endpoint, 2, 3, $000001)
call bt_hid_send_input_report(hid_endpoint, 2, 3, $000000)
return
end if
# When button 1 (PB8) on the evaluation board is pressed while there is no HID connection
if interrupt = $100 && hid_connected = 0 then
# Reset to DFU mode to allow reprogramming of the module over the UART interface (needs to be enabled in the hardware.xml)
call dfu_reset(1)
end if
end
Please, find more below an attached zip file containing all the project files ready for building this example firmware with the bgbuild.exe from the SDK.
A video of the firmware in action follows, showing the mouse pointer of a Smartphone being controlled with the DKBT:
The example code provided at the end of this article shows how to use the BLED112 dongle as OTA client to update Bluetooth applications running on BGMxxx (or EFR32BG).
NOTE: when testing OTA updates, make sure you first test with a target device that can be easily accessed with J-Link debugger in case something unexpected happens.
This example application is only for experimental use. It has not been extensively tested and it is not intended for production use.
The target device must be based on BGMxxx module or EFR32BG SoC. This application is NOT suitable to update any BLExxx devices.
Target device must be running application built with SDK 2.0.0 or later and the application must have OTA enabled as specified in AN1045. Recommended minimum SDK version: 2.0.3 or 2.1.1.
BLED112 dongle is needed. The Bluetooth Smart SDK for BLE product family is not necessary.
What the example does?
The example code provided here is basically the "OTA host example" from the Bluetooth Smart SDK that has been ported to BLED112 dongle. This host example is explained in more detail in AN1045.
Running the example
The attached zip includes a makefile for building the project. This has been tested on Windows using Cygwin but it should work on other platforms as well.
Before running the example, you need to have the EBL file(s) that are suitable for updating your target device.
If you run the example without any parameters it shows the possible usage options as follows:
--- Usage: ----
./OTA list => check COM port number of BLED112
./OTA <COMx> scan => scan for BLE devices (stops automatically after 5 seconds)
./OTA <COMx> <address> <EBL file> => run OTA update
By running the program with option list you can easily check what is the COM port number associated with your BLED112 dongle.
The second option allows you to scan for BLE devices. This is convenient if you don't already know the Bluetooth address of the target device. You can also use it to make sure that the target device is advertising. When lauched with the scan option the program listens for advertisements and then automatically stops after 5 seconds has passed.
Finally, to run the OTA update you need to pass three parameters:
- COM port number
- Bluetooth address of the target device
- name of the EBL file
The attached file named example_run.txt shows example usage of the program (copied from Cygwin console).
This article shows how tune the antenna integrated into the BGM12x with the specific use case of placing a coin-cell battery behind the SiP, therefore enabling extremely compact designs.
Effects of placing coin-cell battery in tuned design
To understand the effects of the coin-cell battery on the antenna matching we took a BGM121 test board and placed a coin-cell in the back with a piece of blu-tak to keep it in place.
Figure 1 - BGM121 test board with coin-cell battery attached
The antenna matching can be seen in the following figures, first for the test board without battery and then after attaching the coin-cell battery.
Figure 2 - Original antenna matching for the BGM121 test board
Figure 3 - Antenna matching for BGM121 test board after attaching the coin-cell battery
Markers 1, 2 and 3 correspond to the beginning, middle, and end of the Bluetooth band. As it is visible in Figure 3 the presence of a metallic body (coin-cell) shifts the antenna tuning outside of the Bluetooth band. This is mostly due to the fact that the coin-cell is covering part of the copper clearance area and therefore reducing the antenna current loop.
Re-tuning the antenna
To counteract this frequency shift we can extend the clearance area simply by scrapping away the ground layer as shown in Figure 4. Due to the the underlying uncertainty on how much it needs to be extended we’ll just extend it about 50% more as it is then easier to re-add a metal plane in order to fine-tune the clearance area.
Figure 4 - Extending the copper clearance area
The antenna matching of the modified board is show in the next figure.
Figure5 - Antenna matching after extending the copper clearance area
The matching is still off-band but this time it is towards the lower frequencies which can be compensated by reducing the copper clearance. To reduce the copper clearance we simply cover it with a piece of metal (a shield from one of our modules in this specific case) until we get the correct matching as shown in the next figure.
Figure 6 - Reducing the copper clearance area to fine tune antenna matching
The antenna matching is now back into the Bluetooth band and very close to the original design.
Figure 7 - Antenna matching after reducing size of the copper clearance area
Conclusion
The presence of metal very near to the BGM12x can have a negative impact on the antenna matching. However, it is easy to compensate the effect by adjusting the size of the copper clearance area to bring the antenna matching back into the Bluetooth band and ensure the best RF performance for your design.
Bluetooth Knowledge Base
BT121 firmware example - Application level security to cope with the missing legacy PIN code in SSP
KBA_BT_0702: UART DFU - Upgrading BGM111 by EFM32PG example
Introduction and Preparations
This article demonstrates how to use an external MCU to upgrade Silabs Bluetooth devices under NCP mode. It aims to provide a base code, which is as simple as possible, to make it can be easily migrated to the real use case. Before starting with this article, please have a look at the below resources.
Above resources could be a good starting point, you can get information such as what is NCP mode, how to generate gbl file, how to do a simple DFU and verify it, etc.
Environments
SDK – Simplicity Studio, 32-bit MCU and Bluetooth SDK (The latest version to the date is always recommanded)
Kits – EFM32PG(SLSTK3401) acts as NCP HOST and any Bluetooth compatiable EFR32 board acts as NCP TARGET
Serial configuration
Baud rate: 115200
Data bits: 8
Stop bit: 1
Flow control: False
Connection and peripherals
Both kits are powered by USB. The connection between them is shown as below table.
Getting Started With the Sample Code
A simple way to verify the UART DFU is to program a firmware firstly, then use the host device to upgrade it with another firmware. Use the difference between these 2 firmwares to identify the success of UART DFU.
Create Gecko Bootloader
To use the UART DFU functionality, make sure you have flashed the "BGAPI UART DFU Bootloader" to your board.
NOTE: the UART settings of the gecko bootloader project should align with the NCP target. Follow below steps to create and program the Gecko bootloader to your board.
Create the NCP Target and GBL File
A simple way to identify the success of device firmware update is by the device name. The default device name in the "NCP target - Empty" project is "BLE Device", we will firstly program the board with this name, then generate a GBL file with a different name. Finally, we use the EFM32PG board to upgrade it, and use the name to verify if it succeeds. Follow below steps to create and flash the NCP target for the EFR32BG board.
Create the HOST application
The host application will read the GBL file as stream, then send it to the NCP target device after it is booted into DFU mode. Programming the gbl file to its unused area of flash is the simplest way for a host application to read it out.
The GBL_FILE_START_ADDR is the starting address you program the full.bin to, and the GBL_FILE_SIZE is the recorded file size in the previous step 6. 4. Use Simplicity Commander to flash the full.bin file with offset GBL_FILE_START_ADDR. See figure 1. 5. Build and flash the EFM32PG board.
Figure 1. Simplicity Commander
Verify it
Figure 2. Serial Terminal Output
BT121 firmware example – HID “air” mouse based on SPI communication with DKBT's accelerometer
In this knowledge-base article we propose to the reader’s attention an example project which is a combination of the customized firmware already presented at http://community.silabs.com/t5/Bluetooth-Wi-Fi-Knowledge-Base/BT121-firmware-example-SPI-communication-with-DKBT-s/ta-p/173742 and the example under the directory \example\classic_hid_mouse_demo\ of the SDK which is discussed in detail in the application note called “AN1032: HID over Bluetooth BR/EDR” and found at http://www.silabs.com/support/resources.p-wireless under the “Application Notes” section.
In the previous article we wanted to demonstrate how to enable the SPI communication with the accelerometer and the display which are integrated in the DKBT. The accelerometer in particular was read so to turn on and off the DKBT’s LEDs depending on the orientation of the board among others.
On the other hand, the example in the SDK is meant to demonstrate how the module can be used to enable a simple wireless mouse based on the Bluetooth Classic’s HID profile. With this example, the mouse pointer is remotely moved up and down, left and right, by pressing the DKBT’s buttons.
With the example project files shared here, we want to turn the DKBT into a Bluetooth “air” mouse, allowing the mouse pointer to be remotely moved similarly, but controlled instead by the orientation of the board being revealed by the regular accelerometer’s readings over the SPI interface while the board is being tilted.
Another important reason for sharing this project is to disclose a new command which is dedicated to reading and writing data over the module’s SPI interface: this new command is introduced since version 1.1.1 build 168 of the firmware/SDK and is called cmd_hardware_read_write_spi . This is a very handy command in that it activates at the same time SPI data writing and data reading and Chip Select (CS) signaling, all in all replacing with a single command the sequence of commands and events cmd_hardware_write_gpio + cmd_endpoint_send + evt_endpoint_data + cmd_hardware_write_gpio seen in the previous article for the same functionality, while removing the limitation of having to wait for a short interval before returning the CS line to the un-select state, which was also a point of concern in the previous article.
Also with this example project the most of the discussion goes for the BGScript called here air_mouse.script.bgs .
Among the rest of the project files (most already covered in the application note and in the previous article mentioned above), the hardware configuration file called hardware.xml and the gatt.xml defining the GATT database are worth an annotation: the latter is not so critical, given that in this example the BLE part is not touched, however it has been simplified by removing the Health Thermometer Service (a leftover in the project from the previous article), while the option sdp="false" has been added to the <service … > tags in order to prevent the two mandatory GATT services to be loaded as SDP records in addition to the DID and HID records.
As for the hardware-related file, the configuration of the SPI interface is as demanded by the DKBT, the UART interface is kept enabled, this time not for debugging purposes but to enable the DFU re-programming of the module, while the GPIOs in use are configured, some as output (we are still turning on and off the LEDs here when the mouse pointer is being moved) and one as input (for the mouse left-button press when connected, or for restarting into DFU mode when not connected), as seen below from the xml file:
Back to the script, let’s see now the (new) parts worth of note (the rest is either commented in the script itself or already discussed in the previous article and in the application note.)
When the module is started the two events system_boot and system_initialized are triggered in a sequence. Within the latter we notice the same calls we are seeing in the other scripts as well, so nothing to add here. Under the system_boot event we are configuring the initial state of the output GPIOs, in particular the one connected to the accelerometer’s CS pin is set to high, while all of those connected to the DKBT’s LEDs are set to high as well, but only after the accelerometer is initialized correctly, things that happen also in the system_boot event using for the first time the new command hardware_read_write_spi . This all is summarized in the code below:
With the new command hardware_read_write_spi there is no more need to worry about separate commands to control the CS line or additional events to read the data coming from the sensor: all is taken care by the command itself, and the data from the sensor is carried directly by the response to the command.
Above we are also seeing that a repeating timer is started once the accelerometer is initialized. Every time it times out, the code checks if a HID connection is ongoing, and only in that case the sensor is read, then all LEDs are turned off, and finally the value from the sensor is verified for the mouse to be moved (by sending the appropriate HID report with the call bt_hid_send_input_report) and for the intended LED to be turned on, depending on the board orientation. This is summarized in the simplified code below:
In the script, events like endpoint_status and endpoint_closing and bt_hid_state_changed exist to take care of the Bluetooth HID connection and disconnection. They are used for example to set the variable indicating if the connection is ongoing, and in case of disconnection to turn all LEDs on, like at the start.
The last important part of the script is shown below and refers to the handling of the interrupt triggered by the press of the button 1 of the evaluation board. Pressing it while a connection is ongoing translates into the HID report being sent to the HID-Host for the mouse button click. Pressing it at a time when there is no connection triggers a reset of the module into DFU module allowing the re-programming of the module using the BGAPI-based DFU commands.
Please, find more below an attached zip file containing all the project files ready for building this example firmware with the bgbuild.exe from the SDK.
A video of the firmware in action follows, showing the mouse pointer of a Smartphone being controlled with the DKBT:
KBA_BT_0806: Using BLED112 to do Over-the-Air update of BGMxxx
Introduction
The example code provided at the end of this article shows how to use the BLED112 dongle as OTA client to update Bluetooth applications running on BGMxxx (or EFR32BG).
NOTE: when testing OTA updates, make sure you first test with a target device that can be easily accessed with J-Link debugger in case something unexpected happens.
This example application is only for experimental use. It has not been extensively tested and it is not intended for production use.
Prerequisites
OTA updates are explained in detail in the following application note:
AN1045: Bluetooth® Over-the-Air Device Firmware Update
The target device must be based on BGMxxx module or EFR32BG SoC. This application is NOT suitable to update any BLExxx devices.
Target device must be running application built with SDK 2.0.0 or later and the application must have OTA enabled as specified in AN1045. Recommended minimum SDK version: 2.0.3 or 2.1.1.
BLED112 dongle is needed. The Bluetooth Smart SDK for BLE product family is not necessary.
What the example does?
The example code provided here is basically the "OTA host example" from the Bluetooth Smart SDK that has been ported to BLED112 dongle. This host example is explained in more detail in AN1045.
Running the example
The attached zip includes a makefile for building the project. This has been tested on Windows using Cygwin but it should work on other platforms as well.
Before running the example, you need to have the EBL file(s) that are suitable for updating your target device.
If you run the example without any parameters it shows the possible usage options as follows:
By running the program with option list you can easily check what is the COM port number associated with your BLED112 dongle.
The second option allows you to scan for BLE devices. This is convenient if you don't already know the Bluetooth address of the target device. You can also use it to make sure that the target device is advertising. When lauched with the scan option the program listens for advertisements and then automatically stops after 5 seconds has passed.
Finally, to run the OTA update you need to pass three parameters:
- COM port number
- Bluetooth address of the target device
- name of the EBL file
The attached file named example_run.txt shows example usage of the program (copied from Cygwin console).
KBA_BT_1304: Antenna tuning for BGM12x (coin-cell usage example)
Introduction
This article shows how tune the antenna integrated into the BGM12x with the specific use case of placing a coin-cell battery behind the SiP, therefore enabling extremely compact designs.
To better follow this article it is recommended to watch our BGM12x related videos, BGM121/123 Hardware Design Guidelines and BGM121/123 Antenna Robustness.
Effects of placing coin-cell battery in tuned design
To understand the effects of the coin-cell battery on the antenna matching we took a BGM121 test board and placed a coin-cell in the back with a piece of blu-tak to keep it in place.
Figure 1 - BGM121 test board with coin-cell battery attached
The antenna matching can be seen in the following figures, first for the test board without battery and then after attaching the coin-cell battery.
Figure 2 - Original antenna matching for the BGM121 test board
Figure 3 - Antenna matching for BGM121 test board after attaching the coin-cell battery
Markers 1, 2 and 3 correspond to the beginning, middle, and end of the Bluetooth band. As it is visible in Figure 3 the presence of a metallic body (coin-cell) shifts the antenna tuning outside of the Bluetooth band. This is mostly due to the fact that the coin-cell is covering part of the copper clearance area and therefore reducing the antenna current loop.
Re-tuning the antenna
To counteract this frequency shift we can extend the clearance area simply by scrapping away the ground layer as shown in Figure 4. Due to the the underlying uncertainty on how much it needs to be extended we’ll just extend it about 50% more as it is then easier to re-add a metal plane in order to fine-tune the clearance area.
Figure 4 - Extending the copper clearance area
The antenna matching of the modified board is show in the next figure.
Figure 5 - Antenna matching after extending the copper clearance area
The matching is still off-band but this time it is towards the lower frequencies which can be compensated by reducing the copper clearance. To reduce the copper clearance we simply cover it with a piece of metal (a shield from one of our modules in this specific case) until we get the correct matching as shown in the next figure.
Figure 6 - Reducing the copper clearance area to fine tune antenna matching
The antenna matching is now back into the Bluetooth band and very close to the original design.
Figure 7 - Antenna matching after reducing size of the copper clearance area
Conclusion
The presence of metal very near to the BGM12x can have a negative impact on the antenna matching. However, it is easy to compensate the effect by adjusting the size of the copper clearance area to bring the antenna matching back into the Bluetooth band and ensure the best RF performance for your design.