Zigbee® Green Power (ZGP) is included in the Zigbee 3.0 specification (Z3) (Zigbee Alliance, Zigbee 3.0 specification, https://www.zigbee.org/zigbee-for-developers/greenpower/). It is an end-to-end open standard that allows ultra-low power devices called Green Power Devices (GPDs) to operate on Zigbee networks. The technology requires ultra-low power RF silicon that uses many orders of magnitude less power than required for a Zigbee sleepy or fully-networked wireless connection.
The EFR32xG22 EM2 and EM4 power modes along with the back-up RAM feature make it suitable to implement a periodic or event-based GPD sensor with bidirectional commissioning and secured key exchange.
There are two types of communication modes based on energy budget:
- Unidirectional: the device only transmits information to the Zigbee network
- Bidirectional: the device transmits and then receives information back, such as security material.
The bidirectional mode implementation uses EM2 power mode and the low energy sleep timer as a wake-up source between transmit and receive.
Commissioning and Security
The hardware acceleration in EFR32xG22 makes it possible to implement a GPD with the highest level of security (encryption and message integrity with application key exchange) during bidirectional commissioning.
Storage of Security Material
In a battery-backed GPD implementation, the back-up RAM can hold the security material during EM4 sleep.
The user guides on Green Power fundamentals and information about using the Silicon Labs Green Power framework can be found here:
Silicon Labs took the decision to deprecate its proprietary implementation of Thread and instead be a major contributor to the more popular OpenThread implementation.
The announcement was made as part of the release notes for Silicon Labs Thread (SL-Thread) SDK v126.96.36.199 which can be found here:
The notice indicates that the inclusion of the SL-Thread implementation will be removed from the Simplicity Studio release scheduled in December 2019.
The notice re-iterates that Silicon Labs has a continued focus on its Thread strategy and is committed to continuing as a leading-edge Thread supplier. Support for Thread will continue within the Silicon Labs software and hardware tools but the stack availability itself will be distributed through the commonly accessible OpenThread GitHub repository.
More information on the OpenThread implementation can be found at: https://openthread.io/platforms/efr32
In EmberZNet version 6.6, Silicon Labs has made changes to the underlying framework so that it uses the same user interface and metadata used by all of Silicon Labs’ other stacks including the xNCP, Silicon Labs Thread, and Flex. This change results in a slightly different user interface for the EmberZNet 6.6 stack in Simplicity Studio. The most noticeable change is that projects are no longer generated into the <stack>/app/builder directory. Instead projects are generated by default into the user’s workspace directory. What follows is a comprehensive guide to both the UI changes for the EmberZNet 6.6 stack in Simplicity Studio as well as a migration guide for moving a pre-6.6 project using Application Framework V2 to one using the Zigbee Application Framework in EmberZNet 6.6.
The first thing you will notice when creating an application in SDK version 6.6 is that the application framework is no longer called “ZCL Application Framework V2”, but rather “Silicon Labs Zigbee”.
Other than this minor change to the location of projects and naming of the application framework, the creation of an application is unchanged.
The AppBuilder interface is still broken up into Tabs, however the contents and names of some of the tabs have changed slightly. The ZCl global tab has been removed and its contents moved to the ZCL Clusters tabs or removed. All changes are detailed below.
1. The generation directory has moved out of the stack and away from the “app/builder” directory and into the user’s workspace by default:
2. There is no longer an option to “Automatically generate when file is saved”.
3. Multi-network configuration widget has moved to the Zigbee stack tab.
1. The ZCL Global tab has been removed.
2. The Manufacturer Code and Default Response Policy options have moved into the ZCL Clusters tab.
3. Specification versions pulldowns that were related to previous ZCL “Profiles” have been removed. Applications are always built against the latest Zigbee 3 ZCL cluster definition located in the stack’s app/zcl directory.
1. Includes the Manufacturer Code and Default Response Policy from the ZCL Global Tab.
1. The ZNet Stack tab has been renamed to the Zigbee Stack Tab.
2. Multi-network configuration has moved into the Zigbee Stack Tab from the General Tab.
3. “Interpan settings” has been removed.
4. The “Custom ZCL Additions” widget has been added. Custom ZCL .xml files used to be loaded into Simplicity Studio preferences and were applied to all projects. We have moved the interface into the project itself so that custom ZCL .xml files and additions are added on a project by project basis.
Prior to EmberZNet 6.6, ZCL .xml additions were added into the Simplicity Studio Preferences and thus affected all projects created for a given stack version as shown below. This is no longer an option for EmberZNet 6.6 and higher.
1. The Debug printing checkbox has moved into the “Debug Configuration” widget.
2. “Cluster debugging” has been renamed to the more generic “Application Specific debug printing”. All of the clusters are still listed in this section.
3. Individual plugin debug printing has been added.
4. The “CLI Options” widget has been renamed to “CLI”.
1. This tab has been renamed to “HAL”.
2. The “IO Configuration” widget has been renamed to “Serial Configuration”. The Command Line Interface pulldown has been moved to an App Framework Core plugin option.
3. The “Board Header” widget has been renamed to “Board Header Configuration”.
4. The “Manage integration…” widget has been renamed to ”Hardware Configurator Interface”.
5. The “Multi Protocol Stack Interface” widget has been renamed to “MPSI Configuration” with the acronym spelled out below.
The ability to expand the table, collapse the table, and show only selected plugins does not exist yet in the EmberZNet 6.6 interface.
This tab is unchanged.
The “Custom Events” widget is now renamed to “Event Configuration”.
This tab is unchanged.
This tab is unchanged.
1. Many of the key value pairs located in the pre-EmberZNet 6.6 stacks have been moved into “setup” configurations in the new .isc file format.
2. Pre-EmberZNet 6.6 .isc files are automatically upgraded to the new Zigbee Application Framework format when they are opened against an EmberZNet 6.6 stack.
Applications created with earlier versions of EmberZNet can be moved into the user’s workspace directory and migrated over to EmberZNet 6.6. The following is a step by step instruction on the migration process, starting with the creation of a pre-EmberZNet 6.6 application and resulting in an upgraded application. This process works for both SoC and Host applications.
1. In the SDK preferences navigate to and open your Pre-EmberZNet 6.6 stack. In this example I will use the EmberZNet 6.5 stack, part of Gecko SDK Suite 2.5.3.
2. Right click and close all open projects in the workspace. Now, create a new project using the earlier stack. In this case I’ll create an EmberZNet 6.5 Z3LightSoc.
3. Generate and compile the project. This will generate code into your <GSDK>/app/builder directory.
4. Right click and close all open projects in the workspace. Not doing so will re-enable the older stack versions upon restarting studio. In the Simplicity Studio V4 preferences disable earlier stack and enable EmberZNet 6.6.
5. Since you have generated and compiled against an earlier stack you should close Simplicity Studio in order to clear out any Hardware Configurator cached data. Hardware configurator data is cached in Simplicity Studio by default in order to speed up generation. Alternatively caching can be turned off in Simplicity Studio preferences.
6. In your user workspace directory create a directory called “<project name>_temp”. This is a temporary directory that you can copy your important project files into before they are imported into Simplicity Studio. For example, my user workspace is located at “/Users/<username>/SimplicityStudio/v4_workspace/.” My project is called Z3LightSoc so I created a directory at “/Users/<username>/SimplicityStudio/v4_workspace/Z3LightSoc_temp”
7. Copy your project’s .isc, .hwconf and callbacks.c files from the <GSDK>/app/builder/<projectname> directory into this temporary directory inside your workspace.
8. Start Simplicity Studio V4.
9. In Simplicity Studio V4 go to File > Import… and browse to the temporary directory that you have created containing your copied files.
10. Import the project. Be sure to set the stack to your EmberZNet 6.6 stack. The project name should default to the original name of the project, in my case Z3LightSoc.
11. You should see the project inside the Simplicity Studio IDE.
12. Double click on the .isc file in the Simplicity Studio to open the project in AppBuilder.
13. Change the generation directory from the old <GSDK>/app/builder directory to your project directory inside your workspace. In my case this is /Users/<username>/SimplicityStudio/v4_workspace/Z3LightSoc
14. Be sure to change the path to any “Included” files in your project by modifying the “Other Options Tab” as necessary.
15. Generate your application.
16. As a final step you should copy the files out of your <projectname>_temp directory into your actual project directory by right-clicking on the files in Simplicity Studio and choosing “Copy Linked Files into Project”.
17. Compile your application.
This is a guide is for creating, building, and running a Dotdot OTA Server and Client using available sample applications. The OTA Server will be on a Host application on the Raspberry Pi that has an NCP connected. This KBA assumes that the user has reviewed UG116 and is familiar with running a Raspberry Pi Host with NCP. (Please note, it is not a requirement for the OTA Server to also be a Border Router).
This KBA was written with the following software tools:
With the following recommended hardware:
Create projects for the following sample applications found in Gecko SDK version 2.5 through the Application Wizard. These can be found through the File menu going to File -> New -> Project -> Silicon Labs AppBuilder Project.
The Light and OTA Server are pre-commissioned and will be in the same network at startup, unless the devices were already in a previous network. Resetting the network parameters will coax the devices to enter the networking state-machine. The reset command is as follows:
ota-server> network-management reset
OTA Server Configuration
The OTA Server (Host) Sample application has all the plugins required to be an OTA Server. Most notable are the following:
In OTA Server Sample app we recommend making the following changes for testing:
Generate, transfer to Raspberry Pi, Compile the OTA server application. Also, compile ip-driver-app found under v2.x/protocol/thread/ with the following command:
$> make -f app/ip-ncp/ip-driver-app.mak
Light OTA Client Configuration
The OTA Client is based on the Light sample app. The following plugins are used to enable the OTA functionality. Here we assume the device you are using has external EEPROM:
In the OTA Bootload Client options set the following to maximize the recurrence of OTA Client/Server communication:
In the OTA Bootload Client Policy options note the following and/or set them to something unique. These will be used for creating the OTA image:
In the OTA Bootload Storage EEPROM plugin make sure the value of EEPROM OTA Storage End Address is one less than the value found in SPI Flash Storage Bootloader Slot 0 size (under the Storage tab). If the size does not match the download will fail.
We also recommend enabling the following plugins for testing:
As well as the following for debug output under the Printing tab:
Generate, Build, and Flash the Light application and bootloader to the EFR32.
Building OTA Image
Recall the values in OTA Bootload Client Policy plugin for the Light. In order for the Light application to flash an image it must verify if the image has met the criteria of the OTA policy. The Manufacturer ID, Image Type ID need to be the same, and the Firmware Version must be a higher value. We will need to create a second image with a higher version number. For example, the first image will be version 0x00000001 and the new image will have version 0x00000002. Go back to AppBuilder and update the project to have a higher version number by changing the setting, generating, and compiling. (Note: this will overwrite your old image. If it needs to be available store it in a different place or rename the GBL file.)
The Image Builder tool will wrap the GBL file in an OTA file. The tool can be found under the SDK directory tree ../gecko_sdk_suite/v2.5/protocol/thread/tool/image-builder/. The following command can be called in a terminal:
$> ./image-builder-linux -c 1234-5678-00000002-light.ota -m 0x1234 -i 0x5678 -v 0x00000002 -s 4 -t 0 --security-credentials=3 -f "light292BRD4163A_02.gbl"
More information can be found in AN716: Instructions for Using Image-Builder
Kicking off OTA upgrade
Copy the OTA image to the same directory where the Server Host application is called. Start the ip-driver-app followed by the ota-server.
$> sudo ./ip-driver-app -u /dev/ACM1 -t tun0 -m 4901 & $> sudo ./ota-server -m 4901
In ota-server call the following command to see if it has found the OTA image.
ota-server> ota-bootload-storage info
The output should be similar to the lines below:
ota-server: 1234-5678-00000002-light.ota: m=0x4X t=0x4X v=0x8X ota-server.nvm: Load files found 1 files OTA Bootload Storage Info: maximumFileSize = 1000000, fileCount = 1 File 0: m=0x1234 t=0x5678 v=0x00000002 size = 311919
On the Light side open the console and check the network parameters using the info command and make sure it is on the same network as the OTA Server. The results should be similar to the lines below:
light_01> info network status: 0x03 eui64: >000B57FFFE25FAFC macExtendedId: >776A3C93A3776E86 network id: precommissioned node type: 0x02 extended pan id: >4F8EC75FB4E1EFC6 pan id: 0x1075 channel: 19 radio tx power: 3 dBm ula prefix: fd01::/64 mesh-local: fd01::1f0e:750c:b36:7ce5 link-local: fe80::756a:3c93:a377:6e86
To kickoff the search for an OTA Server use the following command:
light_01> ota-bootload-client update
The following lines should output to console:
Sent discovery command: .well-known/core?rt=urn:zcl:c.2000.s& get 0x00 Using upgrade server discovery Discovered server: fd01::63e6:a84:377c:3305->5683
If the server is discovered then the OTA transfer will start in ~1 minute (as we configured in OTA Bootload Client plugin).
The ISA3 Utilities are a set of software tools for the Silicon Labs Ember ISA3 Debug Adapter. With these tools you can manipulate adapter firmware as well as program chips in the EM35x and EM35xx family of parts. The latest downloads of these parts can be found here:
For assistance using these utilities, please refer to this user guide:
If you are having the issue mentioned in the title after an update to EmberZnet 188.8.131.52 please consider updating to the Gecko Bootloader. If it is not an option for you the following is an explanation on why this problem occurs followed by a proposed solution.
Although support of Ember Standalone Bootloader for EFR32 based products has ended in 2017. There could still be some devices in the field that were initially manufactured with the Ember Standalone Bootloader and are now unable to upgrade to the Gecko Bootloader.
Since the 2.5 GSDK release modules are regarded as first class citizens and while the Gecko bootloader has been upgraded to facilitate this update the Ember Bootloader was not because it is no longer being developed.
This update causes the AAT header in .ebl files built during the post-build process in Simplicity Studio to be interpreted as corrupt by the Ember Standalone Bootloader.
The problem is that the value of byte 0x78 used to be 0x10 for EFR32MG1P or 0x11 EFR32MG1B and after the update it is set to 0x01 for MGM111.
If this is the issue the advised solution is to convert the created .s37 file to .ebl using the 'em3xx_convert' tool.
This should be located at "(StudioFolder)\developer\adapter_packs\em3xx\utils"
Open any command line tool at this location and you can convert a .s37 to .ebl with the correct AAT header using the following command.
"em3xx_convert.exe --chip EFR32 (path)/(filename).s37 (path)/(filename).ebl"
If your existing Host-NCP solution is lacking Green Power proxy support and you want to add it to the design these steps will walk you through the process of adding it.
First, go to the ZCL Clusters tab and find the Multiple endpoint configuration section at the top. Click the New button to add an endpoint to your device, this will create a second endpoint on the device with identifier 2. Now we need to convert this to a green power endpoint.
In the Configuration column, click the Primary name, which will bring up a button with 3 dots
Click the box to bring up the Endpoint type window
Select the option Create new endpoint type and name your new endpoint Green Power. Click OK.
Keeping the endpoint selected, go to the pull-down menu for ZCL Device Type and change the device to GP Proxy Basic (under GP devices). When this is selected, this will make the endpoint change to number 242. This should also enable Cluster 0x0021, the Green Power cluster, on the device.
Now go to the Plugins tab and on the search bar, enter Green – this will find 4 plugins in the Green Power section:
Check the box next to the Green Power Client and Green Power Common plugins, this will enable them. There isn't any need to change any of the default settings within the plugins, so you can leave those alone.
At this point you should be able to generate and build your host application with no issue and Green Power will be supported. However support for green power needs to be enabled within the NCP.
As you are configuring your NCP application, go to the plugins tab and enable the Green Power Stack Library plugin. Make sure the Green Power Stack Stub Library is disabled:
Since this is just a proxy, you can leave the settings as defaulted, proxy table size of 5 and sink table size of 0. However you will need to consider your potential network when configuring your table sizes. A larger proxy table might be needed for supporting all devices on the network.
This is all you need for NCP support. You can generate and build your NCP and combined with your new host code, green power proxy support should be ready to go.
What is the maximum allowed power for ZigBee applications under ETSI EN 300 328?
Although ETSI EN 300 328 allows 20dBm RF output power, there is a limitation for PSD (Power Spectral Density) for wide band modulations other than FHSS. This PSD limit restricts the maximum allowed power for ZigBee applications.
Section 184.108.40.206 in EN 300 328 V2.1.1 details the test method for PSD. The ZigBee modulated signal measured according to Option 2, Step 3 (with sweep time set to 10s):
CW signal with the same power level and spectrum analyzer settings:
The peak power difference between the ZigBee and CW signal measured with RMS detector is ~2.3dB. In order to meet the PSD limit of 10dBm per MHz, the maximum allowed power is 12.3dBm (EIRP).
Note: The 12.3dBm power limit is radiated (EIRP), which means that in case of an antenna with 0dBi, the maximum conducted power allowed is 12.3dBm. For antennas with lower gain than 0dBi, conducted power can be increased, while for antennas with higher gain than 0dBi, conducted power should be reduced.
Measurements were performed on an EFR32MG13 based reference board (BRD4158A Rev A01).
We are now in the home stretch and ready to build our switch to work interfacing a button. The first thing we need to do is put some hooks into our project to give us a place to put our code.
If you remember back when you made the switch project, we enabled the Button Interface plugin, as the name suggests, this gives you an interface for buttons within our callbacks section. If you look at the callbacks tab, you will see these callbacks under the Plugin-specific callbacks. There are callbacks for different button states as well as long and short presses. For this example, let’s pick button 0 as it is generally clear of the ribbon cable on the Thunderboard. We also don’t need much more than a single button press, so let’s make use of the Button0 Pressed Short callback, check the box next to that identifier. *
* Quick note – a short press is by default defined as less than 250 mSec, you can look through the plugin code and the button timeout definition within the plugin to see how this is defined.
Like the light, make sure at the bottom of your callbacks page you have the “Generate project-specific callbacks file” box checked. This will ensure your new callbacks file is generated for your application. You can then save your .ISC file and hit generate to add this new callback. You will get a box that talks about overwriting files. Make sure your Project_callsbacks.c file is checked, you should also create backups, just in case. Then hit OK.
When you see the Generation Successful window, you’re ready to move to the next step.
Locate your project callbacks file on the left view titled Project Explorer and open the file in your editor. You will see that your callbacks file now includes a new, blank function named emberAfPluginButtonInterfaceButton0PressedShortCallback(). This function is called anytime the button is pressed for a short time.
Now we need to take our CLI calls and use this function to make these calls happen within this function. Looking back at our configuration, we send two commands via the CLI to send a message:
zcl on-off toggle
and then either
send 0 1 1
which sent our message outright to a node and endpoint we specified, or
which used a binding table entry to remove our need to know the exact device we were sending a message to.
First let’s look at zcl on-off toggle. To do this, we need something that will construct our message for us. We can look in the Application Framework reference guide and then refer to the Ember Application Framework API Reference and then the Application Framework Command Buffer Loading Interface. In here you will find a number of commands that will help load command or response buffers which can be sent out with some form of a send command.
If you search for the word ‘toggle’ through this document, it should find the function
which is a basic command which constructs our command buffer for us automatically. The benefit of this command is that it handled much of the overhead by utilizing the command buffer, making sending the message much easier later. So, add a call to this function to your button callback function.
Now we need to find a command to send our buffer over the air for us. So let’s return to the Application Framework and click over to the General Application Framework Interface and search for functions that deal with sending messages. On this page, you can search for the word messaging, which locates the function that deal with sending messages within the application framework. If you look through this section, there are a lot of functions which you can call.
You could use a function like emberAfSendUnicast. But this has a lot of parameters. And as we noted, the benefit we had about using the a FillCommand function is that the command buffer overhead has been handled for us. If you look down the list, you will find a number of functions that start out emberAfSendCommand… these are the functions we want to look at. Since this is a specific command send directly to a single node, you can use emberAfSendCommandUnicast(). This takes two options, the first is a messages type and the second is some sort of integer argument that differs based on what your message type is.
emberAfSendCommandUnicast (EmberOutgoingMessageType type, uint16_t indexOrDestination)
If you follow the link for the EmberOutgoingMessageType, you will see a number of different message types. EMBER_OUTGOING_DIRECT would allow you to send a message directly to a node id. Alternatively, a few lines down, you will find EMBER_OUTGOING_VIA_BINDING, which would allow you to leverage a previously made binding to send your message. Let’s take a look at each of these and you can pick the way you want to send your toggle.
If you choose to send a direct unicast to your node ID, this is the same operation as using the command send 0 1 1 to send your message. If you take a look at the send command’s help you will see the pieces you are providing with the numbers:
send (args) short id of the device to send the message to The endpoint to send the message from The endpoint to send the message to
Looking at the emberAfSendCommandUnicast function, your two options are a type and destination. In the case of using type EMBER_OUTGOING_DIRECT, the destination is our short ID of our target. As we noted before, you can use 0x0000 since this is a short id.
emberAfSendCommandUnicast (EMBER_OUTGOING_DIRECT, 0x0000);
This takes care of your node address. But we set our endpoints in the send command, and these are not yet handled. We need some function to configure the endpoints. And we need to configure this before we send our message otherwise it will be too late. Let’s return to the top level of the application framework and look around at operations that manipulate endpoints. If you search for the word endpoints, you will eventually come across the command emberAfSetCommandEndpoints(), which requires a source and destination endpoint. In our case we know both end points are 1, so you can hard code that if you would like, If you want, you can use emberAfPrimaryEndpoint() as the first argument because it’s the only endpoint of our device. However, in the case of the destination endpoint, you can only specify 1 as you need to hard code this.
Now you can test this out. Save your callbacks file and compile your code. Put this new application on your “switch” Thunderboard and press button 0, you should see your light turn on and off.
Alternative to sending a direct message to your node, you can leverage the fact that you have already created a binding and send directly to that. The advantage of this is that it already takes care of all of your settings like node address and endpoints. However, now you must know your binding entry to where you can send this to the on/off cluster.
So go to your console and enter the command ‘option binding-table print’ to display your binding table.
# type nwk loc rem clus node eui 0: UNICA 0 0x01 0x01 0x0003 0x0000 (>)000B57FFFEDEA263 1: UNICA 0 0x01 0x01 0x0006 0x0000 (>)000B57FFFEDEA263
The on-off cluster is 0x0006, so we want to send this to binding table entry 1. You can place this in as the second argument to your function:
emberAfSendCommandUnicast (EMBER_OUTGOING_VIA_BINDING, 1);
Like in _DIRECT format, now test this out. Save your callbacks file and compile your code. Put this new application on your “switch” Thunderboard and press button 0, you should see your light turn on and off.
In the end, this isn’t the cleanest code possible. Because this function is hard coded on the button, we are always sending our message. In the included MySwitch_callbacks.c file we have included some code that you can use to check that your network is currently up. We also have print statements to display sensible messages when your light or switch are operating.