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.
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
Baud rate: 115200
Data bits: 8
Stop bit: 1
Flow control: False
Both kits are powered by USB. The connection between them is shown as below table.
|Expansion header on EFM32PG||Expansion header on EFR32BG|
|Pin 9 (PD10) - UART TX||Pin 14 (PA1) - UART RX|
|Pin 11 (PD11) - UART RX||Pin 12 (PA0) - UART RX|
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.
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.
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.
#define HAL_UARTNCP_FLOW_CONTROL HAL_UART_FLOW_CONTROL_NONE #define HAL_VCOM_ENABLE (0)
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.
#define GBL_FILE_START_ADDR 0x7800 #define GBL_FILE_SIZE 0x27AD0
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
Figure 2. Serial Terminal Output
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:
<!-- 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.
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.
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.
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.
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.
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
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.