Q: I have <pmux regulator_pin="X" /> on my hardware file but I don't see pin X toggling to control the DC/DC converter.
A: On the BLE1xx C-SDK the pmux is only automatically configured on BLE121LR because it is also used to control the 'on-module' RF front end. For all the other parts (BLE112/BLE113 on both memory variants) it must be manually configured by adding the following code to your project.
/* -------------------------------------------------------------------------
Add this to your code and call hw_pmux_init after blestack_config_init
------------------------------------------------------------------------- */
#define PMUX_DREGSTA BIT(3)
#define PICTL_PADSC BIT(7)//IO pin drive strength
void hw_pmux_init(void)
{
/**
* Read configuration from flash only if valid
*/
if(!(config_flags & HWCONFIG_INVALID))
{
HAL_BANK(hwconfig_page,{
//SETUP PMUX configuration
PMUX=~hwdata.pmux;
if(PMUX&PMUX_DREGSTA)
{
//if regulator status is output, then assumes that dc-dc is connected and vdd is less than 2.6v
// -> enable strong pull-ups
PICTL|=PICTL_PADSC;
}
});
}
//put pmux output pin to down
if(PMUX&BIT(3))
{
uint8 pin=BIT(PMUX&0x7);
//pull down
P1&=~pin;
//put to output
P1DIR|=pin;
}
}
The example project files in the zip attached to this knowledge-base article are meant to create a customized firmware for the BT121 that demonstrates the simultaneous SPI communication between the BT121 and the display + accelerometer that are found in the main board of the DKBT development kit.
The main functionality provided by the application embedded in this firmware is to let the module autonomously read the x-axis and y-axis g data from the accelerometer at the desired interval, and then present such data to the user via the display. Additionally, the application is designed to control the main board’s LEDs so that they turn on and off depending on the orientation of the board, while at the same time the same data presented at the display is also sent out of the module’s UART interface, with the added z-axis measurement.
The main parts of the two key project files (the hardware.xml and the acc_demo.bgs) are discussed below. However, in order to better understand the whole example, please refer to the documentation of the accelerometer (ADXL350 from Analog Devices) and of the display (NHD-C0216CZ-NSW-BBW-3V3 from Newhaven Display International) in addition to all the documentation of the BT121.
Let’s see at first the hardware configuration file. This is called hardware.xml and it contains the following entries which are relevant in this project:
The first entry enables the UART interface to operate at a baudrate of 115200 with RTS/CTS flow control, and disables the BGAPI protocol over it, since this interface is only used for debugging purposes while the module is supposed to operate in standalone mode and not in Network Co-Processor (NCP) mode. The second entry enables and configures the SPI interface of the module over which the communication with the accelerometer and the display is being carried. With the last two entries the exact GPIOs to be taken in use as outputs are defined.
The most important project file is the BGScript by which we are designing the actual built-in functionality. This is the acc_demo.bgs and its basic-like event-driven code comes with comments that should help in clarifying the commands/events and also the flow of the application.
At boot the script initializes the GPIOs in use and set them all high, then immediately proceeds with the initialization of the display. The second event always generated by the system is the system_initialized event: this comes when the radio chipset has become ready and carries the MAC address of the module, so the script has some code under this event to capture the address data and process it so to present it in human readable format in the first row of the display. Back to the display initialization, below you can see how this is done:
event system_boot(major,minor,patch,build,bootloader,hw) [...] call hardware_write_gpio(1,$4000,$0)
call hardware_write_gpio(0,$6000,$2000)
call endpoint_send(spi_endpoint,11,"\x30\x30\x30\x39\x14\x56\x6d\x70\x0c\x06\x01") end
With the first line we are setting low the pin 14 of port B (PB14) which is connected to the LCD’s Register Select input (where 0=Instruction and 1=Data). With the second line we are setting low the pin 14 of port A (PA14) which is connected to the LCD’s active-low Chip Select (CS) input, while maintaining the pin 13 of port A (PA13) high as this carries the corresponding CS signal for the accelerometer which is not yet supposed to listen to data from the module. When the calls in the first two lines are executed the script will launch the next call to send the 11-bytes initialization string over the SPI interface to the LCD.
As can be noticed above, the last call is not followed by an instruction to return the CS line to the high state: in fact it is important to highlight here that there has to be always a certain delay after the last byte is sent to a peripheral before the corresponding CS line is set back high. This delay is taken care by arranging for the CS status change to happen always after the script has processed the data coming from the peripheral (or after a timer). This is seen for example in the code below which exists for the subsequent initialization of the accelerometer:
event endpoint_data(endpoint, data_len, data_data)
[…]
if endpoint = spi_endpoint && data_len = 11 then
call hardware_write_gpio(1,$4000,$4000)
call hardware_write_gpio(0,$6000,$4000)
call endpoint_send(spi_endpoint,2,"\x2d\x08")
return
end if
[…]
end
As can be noticed above, only after the script has received the 11 bytes from the LCD the instruction to raise the PB14 is given, so to turn the LCD into data mode (since from now on only characters to show will be sent to the LCD), and then PA14 is turned high while at the same time the PA13 is turned low to make sure that the next 2-bytes initialization string sent out of the module will reach the accelerometer.
The same endpoint_data event is then processing similarly the 2-bytes data coming from the accelerometer, in which case both CS signals are returned to the high state and a one-shot timer is started.
When this particular timer has expired the LCD is ready to receive the characters to display (given that the Register Select line is already high) so within the event hardware_soft_timer, and under the handle of 0 that was used when the one-shot timer was started, the LCD’s CS line is set low and display data is sent to LCD (including at this time only the MAC address.) After the data is sent to the display, the CS line is not set to high as discussed above, but a new timer, repeating at the desired interval, is started with handle of 1.
From this moment the application enters in a loop triggered by the repeating timer: at every timeout the accelerometer data will be read then the data will be presented at the display and out of the UART and will also be used to decide under which circumstances one of the evaluation board’s LEDs will be turned on. All of this is implemented in the following way according to the script:
event hardware_soft_timer(handle)
if handle = 1 then
call hardware_write_gpio(0,$6000,$4000)
call endpoint_send(spi_endpoint,7,"\xf2\x00\x00\x00\x00\x00\x00")
return
end if
[…]
end
Above, when repeating timer has expired, simply the appropriate 7-bytes string is sent to accelerometer after switching the PA13 low and the PA14 high. A comment in the BGScript briefly describes the syntax of that strings, which in practice commands the accelerometer to return the current g values of the 3 axis.
And then we have the following code (simplified so that only the code related to the x-axis is shown):
event endpoint_data(endpoint, data_len, data_data)
if endpoint = spi_endpoint && data_len = 7 then
display_data(40:2)= "X="
display_data(42:1)=HEX(((data_data(2:1)/16)&15):1)
display_data(43:1)=HEX((data_data(2:1)&15):1)
display_data(44:1)=HEX(((data_data(1:1)/16)&15):1)
display_data(45:1)=HEX((data_data(1:1)&15):1)
[...]
call hardware_write_gpio(0,$6000,$2000)
call endpoint_send(spi_endpoint,80,display_data(0:80))
call endpoint_send(uart_endpoint,,"\r\nX=")
call endpoint_send(uart_endpoint,1,data_data(2:1))
call endpoint_send(uart_endpoint,1,data_data(1:1))
[...]
call hardware_write_gpio(1,$3600,$0)
if (data_data(2:1) & $3) = $1 then
call hardware_write_gpio(1,$3600,$200)
return
end if
[...]
return
end if
[...]
end
Above, the event endpoint_data comes again as a consequence of the 7 bytes sent with the instruction under the repeating timer, and when the expected data is captured into the data_data variable the script will in order 1] prepare the hex data into human readable format for the display, 2] switch the PA13 high and the PA14 low (opposite compared to the status changes commanded under the timer), 3] send the display data to LCD over the SPI, 4] send the same data out of the UART, 5] turn all LEDs off just before checking the content of the most significant bits of the x-axis and y-axis readings in order to then switch on the appropriate LEDs depending on the board’s orientation.
As written in some of the comments in the script which are not reported in the code above or in the previous parts, let’s highlight also here that data_data(2:1) holds the most significant byte of the twos complement x-axis measurement while data_data(1:1) the least significant, and let’s remind here as well that readings are 16-bit twos complement but resolution is set to 10bits and that is why the two least significant bits of the most significant byte are checked to define if to turn on a LED or not.
Important notice: the official version 1.1.0 build 154 has a known bug that prevents proper SPI communication (actually module’s incoming data is corrupted), so in order to test this firmware, or if you need a working SPI for your application please consider the newer firmware version 1.1.1 build 168 or newer. In addition, notice that since firmware version 1.1.1 build 168 a new command exists which is fully dedicated the communication over the SPI communication: this is called hardware_read_write_spi and is discussed in the companion article at http://community.silabs.com/t5/Bluetooth-Wi-Fi-Knowledge-Base/BT121-firmware-example-HID-air-mouse-based-on-SPI-communication/ta-p/187248
Note: This KBA has been deprecated. For additional peripheral examples to those found in the Bluetooth Knowledge base please refer to the peripheral examples github repository which also includes examples for the EFR32.
Question
Where can I find peripheral examples like SPI, ADC & other I/Os for Blue Gecko?
Answer
For the peripheral examples check the c:\SiliconLabs\SimplicityStudio\v3\developer\sdks\efm32\v2\kits\SLSTK3401A_EFM32PG\examples\
These examples are written to a Pearl Gecko kit but the MCU is the same EFR32 as in the Blue Gecko.
Note: This KBA has been marked as deprecated. A more updated KBA can be found here.
One of the features of the Bluetooth Smart stack is ability to indicate transmit or receive activity with a GPIO pin. Currently, pins 6 through 11 on PortC are available for this purpose. To enable this functionality in the C-SDK, first add the following to your stack configuration struct
This indicates to the stack which pins to use for signalling transmit and receive activity.
Next, it will be necessary to disable any peripheral which shares these pins. If you are using our WSTK board, this will be USART1. The easiest way to disable it is to comment out the call to
USART1_enter_DefaultMode_from_RESET() in
enter_DefaultMode_from_RESET()
which is found in InitDevice.c.
Finally, it is necessary to power cycle the WSTK for the changes to take effect.
The Bluetooth Classic Friendly Name reported in the Extended Inquiry Responses or in the responses to SDP queries is different from the BLE Device Name carried by the advertisement packets which are transmitted by a BLE advertising slave.
The Friendly Name can be easily configured at any time using the dedicated BGAPI/BGScript command called system_set_local_name(...)
Notice here that it is not necessary to stop and restart the RFCOMM server or cycle visibility and connectability of the module for any name change to become effective. Notice as well that the currently configured name is stored in the Flash memory of the module so it will be preserved across resets and power-cycles.
However, there is no corresponding command to change the BLE Device Name during runtime. In fact, the Device Name used by the BT121 stack in the advertisement packets is normally taken from the gatt.xml, in particular from the dedicated characteristic having UUID of 2a00. The gatt.xml is one of the project files that are used by the bgbuild.exe to create a custom firmware: in particular, it defines the fixed structure of the whole GATT Database that will be in use by the GATT Server running in the module.
If you want to change the Device Name during runtime, you have two options:
and then during runtime issue the command gatt_server_write_attribute_value(handle_of_ble_local_device_name,....) to change the name that the BT121 firmware will add in the advertisement packets. Remember that the characteristic with UUID of 2a00 will have to be initialized before the command to start advertising is launched for the first time after every reboot. In fact, differently from the Classic Friendly Name case, the Device Name configured in this way is not preserved across resets and power-cycles, because like with every other non const characteristic, this too will have to be initialized.
Notice that the important change in the database definition is to make the characteristic non const, and notice also that in the command above the handle must be used (as found in the "constants" file generated by the bgbuild.exe when the id="..." option is used in the gatt.xml), and not the UUID.
2] Use the commands le_gap_set_adv_data(0,...) + le_gap_set_adv_data(1,...) + le_gap_set_mode(le_gap_user_data,...) to define and start your custom advertisements and scan responses carrying the desired Device Name among others. Of course the Device Name will go either in the advertisements or in the scan responses, not in both.
In that article you will find an extract of the Core Specification describing the format of advertisement packets (you will be fully responsible for the whole packet, including for example the correct usage of the Flags AD Type) and a script with concepts that are valid also for the BT121.
In both the above cases 1] and 2] for the new Device Name to come into effect you will have to stop and restart advertisements before and after the renaming operation.
One important new feature introduced with the public official version 1.1.0 build 154 of the BT121 firmware is the support for legacy pairing.
In order to enter the legacy shared PIN code the new command to use is sm_enter_pin_code(...) and this command should be launched within 30 seconds from receiving the event sm_pin_code_request(...). Read more about the new command and event in the BGAPI pdf reference or in the HTML-based reference called dumo.html and found under the directory \hostbgapi\ of the SDK.
Notice the following: - No PIN code can be stored by the Smart Ready stack so that it is used automatically whenever legacy pairing is to be carried on. - The BT121 must be made bondable beforehand, with command sm_set_bondable_mode(1), for the link keys created during the pairing process to be locally stored for any future connection (until devices are un-bonded). This is in fact required for Bluetooth Classic. - When the BT121 makes a SPP call, and the called device is not already bonded, then pairing is always requested by the BT121, and the same PIN code must be entered at the both sides in case the remote device uses legacy pairing. - When the other side using legacy pairing calls the BT121, and the two devices are not already bonded, then the remote side might or might not request for pairing: if pairing is requested, then the same PIN code must be entered at the both sides; if pairing is not requested, then the BT121 will accept the clear-text connection.
You can see a typical case in the two pairs of attached logs: looking for example at the two *test1*.txt logs from the BT121 perspective, at the remote side we have a WT11i (with mac of 00:07:80:43:69:9c) where Secure Simple Pairing (SSP) is disabled and where we configured a legacy PIN code of "0123456789" - at the BGTool being used to test with the BT121, the legacy PIN code is entered with command seen at timestamp 09:14:30,0566 following the event seen at timestamp 09:14:18,0664
Of course the mandatory SSP is also supported by the Smart Ready stack in the BT121. With it you first have to clarify which capabilities your device supports and then define if you want Man-In-The-Middle (MITM) protection or not: configuration will then happen with the BGAPI command sm_configure(...). Depending on the above configuration you might be prompted to display or confirm or enter a passkey respectively with the events sm_passkey_display or sm_confirm_passkey or sm_passkey_request. As a consequence your device will show the passkey to the user to be confirmed at the other side (for example if you have Display-only capability) or you will confirm or enter a passkey with the BGAPI commands sm_passkey_confirm(...) or sm_enter_passkey(...) respectively.
One typical question is if there is any way to force a known PIN code for pairing in general. Unfortunately with SSP there is no way to do that according to the specification, except if you configure the module to have Keyboard-only capability and have your host MCU to enter the desired passkey with the command sm_enter_passkey(...). However, this requires the other side to also have Keyboard-only capability, otherwise, if the other side has for example Display-only capability, it will just display a randomly generated passkey that you will have to enter to module for pairing. Please refer to the tables below, which are part of the specification (and found also at https://developer.bluetooth.org/TechnologyOverview/Pages/LE-Security.aspx) to understand the possible SSP pairing mechanisms and which of them is selected depending on the capabilities at the Initiator and at the Responder.
Only the legacy pairing allows the use of a shared PIN code to be entered or pre-configured at both sides (like the typical 0000 or 1234 of many old Bluetooth hands-free headset), but legacy pairing happens only when at least one of the two sides is based on the very old Core Specification 2.0 and below. In fact, it is important here to notice that SSP is the mandatory pairing framework between two devices both supporting Core Specification 2.1 and above.
So, again, it is not possible to configure a specific known passkey with the Secure Simple Pairing. In SSP the closest match to the legacy pairing is when both devices declare support for the capability called Keyboard-only. If you have control of both sides, then you can configure both for Keyboard-only capability, and in BT121 this is done with command dumo_cmd_sm_configure(1,2). With that configuration in place, you would then make sure that users at both sides enter the same known passkey, and in BT121 you would have your host program (or a BGScript) to simply issue sm_enter_passkey(connection, fixed_known_passkey) upon receiving the event sm_passkey_request. Unfortunately, it is rare to happen that you have full control of both sides: instead, a more typical case is when you want to force a PIN code to be entered by the user of some smartphone app, but it is a fact that for example smartphones and PCs normally declare to support for Keyboard+display which prevents the above workaround.
Despite the demand for allowing a developer to disable SSP in the BT121 Smart Ready stack, so to fall back in any case to legacy pairing, and thus having the opportunity to use the fixed PIN code, our decision is for the moment not to introduce this configuration option, reason being that our Bluetooth stack would go out of specification. If you need the kind of security provided by the old legacy pairing mechanism between two devices following the Core Specification 2.1 and above, you will have to consider alternatives at the application level.
For example, with the BR/EDR Serial Port Profile you might consider authentication/authorization handshaking implemented by your application and carried on over RFCOMM just after SSP Just-works pairing (if you wish no additional user action) and connection establishment. Just to give an idea, this is the Apple's approach with iAP. One simple example of application level security has been added into the main.c of the host example program under the directory \host_example\spp_server\ of the latest SDK version 1.1.1 build 168.
For BLE things might be even easier: in case of a product with no display and also with no keyboard or a Yes/No button, then only the un-authenticated Just-works pairing mechanism would be available. In order to add a level of authentication/authorization, a characteristic in the GATT database could be used to verify/hold/enter a secret user code before the actual data exchange is started. Notice that this method would not replace the Bluetooth pairing itself, but it would be a replacement, or an addition to that, to overcome the lack of authentication/authorization in the Just-works mode.
This knowledge-base post discusses the three current methods for programming a BT121 module with a .bin firmware image file.
The firmware image files can be either 1] one of your own files with your own customized firmware obtained by running the bgbuild.exe free compiler found inside the Smart Ready SDK (this is the typical case), or 2] one of the pre-compiled images available in the SDK within the example project directories.
The three methods are exposed below, but before getting into that you might want to take a moment and read about the module’s factory default firmware here.
Method 1 - BGAPI-based DFU over UART
- This method allows the MCU in a host system to re-program the BT121 over the UART interface using BGAPI commands which are similar to the rest of the commands used for controlling and configuring the module in its normal operations.
- The best way to understand how this method works is to read through the source code of the host example program found under the directory \host_example\dfu\ of the SDK (since version 1.1.0 build 154.)
- With the first release of the firmware (version 1.0.0 build 97) the guidelines were as follows:
when the BGAPI-based bootloader is ready for the DFU upgrade, for example after soft rebooting into DFU mode using the BGAPI/BGScript command system_reset(1) without raising the BOOT0 pin, the first command to enter over the UART host interface is the dfu_flash_set_address(...) with address of 0x00000000.
Next step is to issue as many dfu_flash_upload(...) commands as there is data to extract from the whole .bin firmware image file. These multiple commands are issued to upload to module the full firmware file. Pointer to the next intended flash memory address to write to is automatically updated by the bootloader code after each command.
When all raw binary data from the .bin image is sent to module, finalize the process by issuing the dfu_flash_upload_finish() followed by the dfu_reset(0) to restart the module in normal mode with the new firmware.
- With BGAPI-based DFU the UART configuration depends on the hardware.xml project file that defined the whole hardware configuration at the time the firmware currently running in the module was built. This means for example that the UART configuration of the BGAPI-based bootloader in a module still running the default factory firmware is 115200, 8N1, with flow control.
- Starting from the version 1.1.0 build 154 a new bootloader is officially in use, which is 4KB in size instead of 8KB. This requires a BGAPI-based DFU re-flash to take this into account when upgrading from any earlier release.
In this case, a BT121 firmware upgrade consists then of two parts: updating the bootloader first, and updating the firmware itself thereafter.
The bootloader version is given by the dfu_boot event that follows a system_reset(1). Currently it is 1 for builds 97-138 and 2 for builds 139 onward.
Notice that the Smart Ready software in the module depends on its specific companion version of the bootloader: in fact, the Smart Ready stack will not start if the bootloader version does not match, in which case the module will keep on rebooting into the DFU mode.
The bootloader cannot be downgraded to the older version using BGAPI-based DFU. To return to build 138 or older, one of the ST-based re-flashing methods must be used instead (see methods 2 and 3 below.)
The C source code example under the directory \host_example\dfu\ of the SDK (since build 154) was indeed introduced to show how to perform the bootloader and firmware update using BGAPI, and it works fine for old to new firmware upgrades and also for new to new firmware upgrades (for old to old firmware upgrades, you might need to edit the code to discard the new firmware check in the example from SDK 154, or simply refer to the improved version found in SDK build 168 or later.)
- The new procedure to update the firmware using BGAPI-based DFU is as follows:
1) Reset to DFU mode
a) Send system_reset(1) to reboot the module into DFU mode.
b) Wait for dfu_boot event. Check the version parameter. If it is 2, then proceed to section 3,
otherwise proceed to section 2.
2) Bootloader update
a) Send dfu_flash_set_address(...) using address of 0x2000
b) Upload all except the last 2KB (2048 bytes) of the .bootdfu temporary image file
generated by the bgbuild.exe using dfu_flash_upload(...)
c) Send dfu_flash_set_address(...) using address of 0x1e800
d) Upload the last 2KB of the .bootdfu file using dfu_flash_upload(...)
e) Send dfu_flash_upload_finish()
f) Send dfu_reset(0)
g) Wait for dfu_boot event. Check version. If it is 2, then proceed to section 3.
Otherwise there was an error, thus go back to 2a and repeat the steps.
3) Firmware update
a) Send dfu_flash_set_address(...) using address of 0x0
b) Upload the whole .bin firmware image using dfu_flash_upload(...)
c) Send dfu_flash_upload_finish()
d) Send dfu_reset(0)
e1) system_boot event is received. Firmware has been successfully updated
and module is ready to use...
e2) ...or dfu_boot event is received, meaning that there was an error updating
the firmware. Go back to 3a and repeat the steps
- Below is a screenshot of the dfu.exe in action. The executable was built with Visual Studio Community 2015 directly from the sources at the directory \host_example\dfu\ of the new SDK. Again, this source example provides the principal mean to understand (and use) the BGAPI-based re-flashing.
Method 2 - ST-based DFU over UART
- This method can be carried on among others by using either the bgupdate.exe found inside the \bin\ directory of the SDK, or via the "Upload tool" section of the BGTool Windows demo program (which actually uses the same code as the bgupdate.exe)
This is the preferred method if you have the DKBT development kit, because our tools will recognize the Prolific USB-serial chip in the main board and will use this chip to assert the BOOT0 pin and reset the module.
Only starting from the SDK version 1.1.0 build 154 the tools work also without the Prolific chip, but you will have yourself to first reset the module while asserting the BOOT0 pin. More on this below.
- Details about this method:
when you keep the BOOT0 pin high while resetting the module, the ST bootloader will not launch the Smart Ready software's own bootloader (which implements the BGAPI-based DFU functionality seen above) which in turn will then not launch the Bluetooth Smart Ready stack. In that case, the ST bootloader will remain waiting for the host system to start communicating using the ST protocol to re-flash the module over the UART.
As for the UART configuration in use by the ST bootloader, notice that RTS/CTS flow control is not required, 8E1 is in place, and baudrate is auto-sensed, however the host is recommended to use half a MBaud or less.
For more details on the protocol used by the ST bootloader, you might want to refer to the documentation by ST: see for example here and/or here.
As well, notice that there are open source solutions that implement the ST bootloader protocol, for example see here and here.
This is actually what our bgupdate.exe tool mainly does under the hood. In particular, starting from the version found in SDK build 154, the bgupdate.exe (and the re-flashing functionality in the BGTool) has been improved so to recognize if the Prolific chip is in use. If not, then just the ST-based re-flash will be carried on, otherwise the chip is used to reset the module while asserting the BOOT0 pin, before starting the ST-based re-flash.
In other words, if the Prolific chip is recognized to be present, then it will be used to assert the BOOT0 line and to reset the module before proceeding with the ST-based re-flash. And if the Prolific chip is recognized to not exist instead in between, then the bgupdate.exe will not get stuck like with the previous release, but will immediately talk the ST protocol for the re-flash, meaning that the utility should be launched only after the module has been reset, with the BOOT0 asserted, by some other mean that is up to the customer to define.
- Below you will find some screenshots showing the usage of bgbuild.exe (for building your custom firmware image based on your own firmware project files) and of bgupdate.exe (for uploading your firmware to module) and you will find as well the corresponding screenshots when BGTool is used instead:
Method 3 - Re-programing over the ARM Serial Wire Debug interface
- With this method it is possible to re-program the BT121 over its ARM Serial Wire Debug interface
See the command in action in the screenshot below. This command should be launched while the module is under reset, and the process will start after the reset is released. Notice also the address of 0x08000000 in use here: according to the memory map of the microcontroller inside the module, the Flash memory boundary addresses are 0x08000000 - 0x0801FFFF (as a side note, address of 0x0 used by the dfu_flash_set_address in our BGAPI in fact corresponds to the 0x08000000 boundary address.)
MAC address considerations
There are cases when the current MAC address in use will go lost during a re-flash. Please see more in the knowledge-base article here.
OTA
As for the Over-the-Air (OTA) upgrade, contrary to the BGM and BLE products unfortunately the bootloader of the BT121 does not support it at the moment.
With that being said, you could still make OTA upgrades if you would arrange to first send the firmware image over a Bluetooth link to the host system, and then let the host system to locally upgrade the module over UART using for example the BGAPI-based DFU.
Questions & Answers
Q1.
I could not find any dfu.exe file in the SDK, so where can I find such executable?
A1.
The dfu.exe is not included in the SDK, but must be created by the customer from the sources in the SDK under the directory \host_example\dfu\ for a specific platform. The one shown in the first screenshot of this article was created using the Microsoft Visual Studio for testing in a Windows PC.
Q2.
What are the reasons to change the bootloader from v1 to v2? Bug fixes or implementation of a better protocol?
A2.
The only reason was to free 4KB of Flash memory. Remember here that, because of memory remapping the bootloader v2 is needed to launch the Smart Ready software created with build 154 and above.
Q3.
What will it happen if the BGAPI-based bootloader update procedure is failed or interrupted or mis-handled? Will the bootloader die?
A3.
You will have no other option than to recover the module using the ST-based re-flash over UART (or SWD re-flash). This to say that it is impossible to brick a module, since it will always be recoverable over the last two methods mentioned above. In other words, it is always possible to recover a module with the ST-based DFU over UART or via the SWD interface if there is no hardware failure.
Q4.
Does a *.bin image file contain the BGAPI-based bootloader?
A4.
Yes, all .bin firmware image files contain the appropriate Smart Ready software’s own BGAPI-based bootloader. The ST-based re-flash methods always write also such bootloader, which is included in the .bin file, on top of the existing one. On the other hand, the BGAPI-based bootloader is designed not to overwrite itself during the BGAPI-based DFU re-flash (when for instance you are performing a normal re-flash after sending the dfu_flash_set_address(...) using address of 0x0), and in fact when you think you are writing the sectors containing the bootloader code, these very bytes are silently discarded.
Q5.
Each dfu_flash_upload(...) command writes 128 bytes to the flash. The filesize of .bootdfu is 12,288 (0x3000) bytes. For step 2b, it needs (12288-2048)/128 = 80 of dfu_flash_upload(...). For step 2d, 2048/128 = 16 of dfu_flash_upload(...). Are these figures correct?
A5.
Yes, they are correct.
Q6.
For step 2c, the starting address is 0x1e800 (or 0x0001e800). If BGAPI binary code is used, is it 0x20 04 00 01 00 01 e8 00 ?
A6.
The binary string is actually 0x20 0x04 0x00 0x01 0x00 0xe8 0x01 0x00 (remember little endian – and, well, you should not worry about this as the BGLib-based code under the directory \host_example\dfu\ should automatically take care of creating the right binary sequence.)
Q7. Is the .bootdfu that is generated with the SDK build 154 (or newer) fixed, or does it change always when building a project? Can we just build it once and use that version of the .bootdfu regardless of changes to the project files? A7. The .bootdfu file changes only if the hardware.xml is changed, because the bootloader will get the UART configuration from the hardware.xml You can keep on using the same .bootdfu file, provided that 1] you keep into account its UART configuration at the time it was built (bootloader's UART configuration might not match the UART configuration of the Smart Ready software if the latter was changed in the meantime via a new different hardware.xml) and 2] you are not going to program an older Smart Ready software which would be incompatible with the bootloader v2
Q8. Every time I load a new firmware image, I can no longer connect to the BT121 from my Windows PC, using SPP, unless I delete the bonding and re-create it. A8. The bonding information stored in the Flash memory of the BT121 is preserved if re-programming of the module happens via the BGAPI-based DFU. Bonding information is instead deleted with any other re-flashing method. So, depending on the re-programming method of your choice, and depending on the Bluetooth stack running at the remote side, you might have to remove the BT121 from the bonded devices listed at the remote side after a module's update.
Q9. Could you tell us more about CRC checksums, if any is used within a firmware image? A9. Please have a look at the second half of the article here.
Q10. My module does not reset into BGAPI-DFU mode (it does not send the dfu_boot event and there is no way to proceed with re-programming) even though I am verifying with a logic analyzer that the system_reset(1) or the dfu_reset(1) command is correctly sent over UART. Note that during runtime I can send the system_hello command and I obtain the expected response from the module. A10. Please consider the Reset chapter in the datasheet from where we read that "On an internal reset, the RESET pin will be briefly pulled low internally. It is recommended that an external reset source is of an open drain type." In other words, you need to allow the module's reset line to be internally pulled low for the module to reboot successfully.
This article is about the factory default firmware used for the BT121. There are actually two possible default firmware images used in production: one flashed into the bare modules and another one flashed into the modules that populate the carrier boards of the DKBT development kits. These two firmware images are shortly discussed below, and a few notes will follow for your consideration.
- The factory firmware for the modules in the carrier boards of the development kits is obtained from the project files under the directory \example\bgdemo\ of the SDK.
According to the configuration line <uart baud="115200" flowcontrol="true" bgapi="false" /> in the hardware.xml you can realize that the BGAPI host serial protocol over UART is disabled. In fact, the module operates fully in standalone mode thanks to the demo application defined in the BGScript called bgdemo.bgs, which is one of the other project files found under the same directory, and made part of the firmware by the instruction <script in="bgdemo.bgs" /> entered into the project.xml file. You can test this firmware by following the steps in the Quick Start Guide that comes with the DKBT. Additionally you can learn more about it in the "Software Getting Started Guide" available at http://www.silabs.com/products/wireless/bluetooth/bluetooth-low-energy-modules/bt121-bluetooth-smart-ready-module
- On the other hand, the bare BT121 modules come with a factory firmware obtained by using the bgbuild.exe of the SDK version 1.0.0 build 97 with the example project files found under the directory \example\bt121\ of the same SDK. From the hardware.xml configuration file you can see that the BGAPI host serial protocol is enabled over the UART at 115200 with flow control enabled, according to the line <uart baud="115200" flowcontrol="true" bgapi="true" />. In this case, the module operates in hosted mode (also known as Network co-processor mode, or NCP mode) and there is no autonomous functionality provided by a BGScript. For instance, there is no script running that would start LE advertisements or that would turn BR/EDR visibility on, so the module at start is idle and invisible to other Bluetooth devices in range, as it is just waiting for the first instructions from its host system.
Generally speaking, if you are good with the factory default UART configuration of the bare modules, and you are not after the standalone functionality provided by a BGScript, while the default GATT database is also fine with you because for example you are going to use the module as a GATT Client, then you do not need to re-flash a module and you are ready to have your host MCU to configure and control the module using the BGAPI serial binary protocol over the UART interface.
But in any other case (the majority, according to our customer base) you would consider developing a firmware fully tailored to your application, by creating new, or editing existing project configuration files. With the appropriate project files you would then build the firmware image for your modules using the bgbuild.exe free compiler found in the SDK, and you would program your modules as discussed in the article at http://community.silabs.com/t5/Wireless-Knowledge-Base/Programming-the-BT121/ta-p/173579
Update: as of the release of the firmware/SDK version 1.1.2 build 184, the old version 1.0.0 build 97 has become deprecated, thus it is strongly recommended to re-program your modules in any case, so to make sure that they are running the latest firmware release, either based on your own project files, or on the updated version of the factory default firmware which is still found under the directory \example\bt121\ of the SDK (ready image file having name of BT121_BGAPI_UART115k.bin) Notice here as well, that our Sales and Field Marketing teams are available to give guidance to our customers on how to create custom parts, so that the BT121 modules would be pre-programmed in our factory lines with any firmware image provided by the customer.
Bluetooth Knowledge Base
BLE1xx PMUX usage with C-SDK
BT121 firmware example - SPI communication with DKBT's accelerometer and display
[Deprecated] Blue Gecko peripheral examples
Note: This KBA has been deprecated. For additional peripheral examples to those found in the Bluetooth Knowledge base please refer to the peripheral examples github repository which also includes examples for the EFR32.
Question
Where can I find peripheral examples like SPI, ADC & other I/Os for Blue Gecko?
Answer
For the peripheral examples check the c:\SiliconLabs\SimplicityStudio\v3\developer\sdks\efm32\v2\kits\SLSTK3401A_EFM32PG\examples\
These examples are written to a Pearl Gecko kit but the MCU is the same EFR32 as in the Blue Gecko.
[Deprecated] Observing Tx and Rx activity
Note: This KBA has been marked as deprecated. A more updated KBA can be found here.
One of the features of the Bluetooth Smart stack is ability to indicate transmit or receive activity with a GPIO pin. Currently, pins 6 through 11 on PortC are available for this purpose. To enable this functionality in the C-SDK, first add the following to your stack configuration struct
.radio_obs.flags = RADIO_OBS_FLAGS_ENABLED,
.radio_obs.tx_pin = 6,
.radio_obs.rx_pin = 7
This indicates to the stack which pins to use for signalling transmit and receive activity.
Next, it will be necessary to disable any peripheral which shares these pins. If you are using our WSTK board, this will be USART1. The easiest way to disable it is to comment out the call to
USART1_enter_DefaultMode_from_RESET() in
enter_DefaultMode_from_RESET()
which is found in InitDevice.c.
Finally, it is necessary to power cycle the WSTK for the changes to take effect.
BT121 - Changing BLE Device Name during runtime
BT121 - Legacy pairing and fixed PIN code or Passkey
Programming the BT121
BT121 factory firmware