The Project board is for sharing projects based on Silicon Labs' component with other community members. View Projects Guidelines ›

Projects

    Publish
     
      • Using a script language in EFM32 environment

        Attila Varga | 06/182/2020 | 11:59 AM

        Using a script language in EFM32 environment

        This article describes the usage of a script interpreter in EFM32 environment. The chosen language is the Lua language, the used board is the Silicon Labs Pearl Gecko (SLSTK3402A) starter kit board and the development environment is the standard IDE of Silicon Labs: Simplicity Studio. In the next section a brief description of the script language is provided followed by the goals, requirements and architecture descriptions. You can also find an attached source code and an explanation how to use this example project.

        For the impatient:

         

        • flash the provided .s37 file onto a Pearl Gecko
        • use a terminal emulator (over VCOM) to see the menu (type: help)

        Contents:

          - 1. Brief description of Lua
          - 2. Why do I need a script interpreter?
          - 3. Goals
          - 4. Requirements
          - 5. Architecture
          - 6. Implementation
          - 7. Uploading scripts
          - 8. How to use
          - 9. Future improvements
          - Additional notes:
          - Examples
          - Fazit (conclusion)

        1. Brief description of Lua

        According to the Lua website:
        "Lua is a powerful and fast programming language that is easy to learn and use and to embed into your application."

        The emphasis is here on "embeddable". Lua is a software package designed from start to embed into a so-called "host", which is (in most cases) a foreign, compiled language. Most often it is C, but it can be also any other language. Lua is used in a wide variety  of application, aerospace, photography, research and mostly: in games (due to its speed). It is easy to learn, the hello-world example is a one-liner and the language elements have a low learning threshold.

        An example of Lua code:

        local function run()
          print("--Run--")
          while counter < threshold do
            if IsBtnPushed() then
              if (counter % 8) == 0 then
                print("down")
              end
              Delay(10)
              counter = counter + 1
            else
              counter = 0
            end
          end
        end

        2. Why do I need a script interpreter?

        C is a powerful language, why do I need then an other language?
        What Lua does offer is what C is not good for: dynamic structures, no redundancies, ease of usage, safe environment, automatic memory management and handling strings and other kinds of data with dynamic size.

        Other aspects are that the language is easier to learn by non-programmer thus it gets an environment for a broader user attendance.

        An embeddable script language has the advantage that it can be used as part of the application that is frequently changed without the need of recompilation, for example in handling configuration parameters, automatic test cases, measurements, tryout/oneshot programs, user provided code, customize layout and/or behavior, etc.

        You can give the user the possibility to change something in the application. It is easy to develop and platform independent. But bear in mind that if you provide the possibility to modify something in your application then it must be a safe environment. Fortunately Lua can be configured to have this kind of 'sandbox'.

        3. Goals

        The goal of the project to use a working interpreter embedded in C code. It is not intended to be a complete, full-featured development environment for some kind of application but to provide a firm base to develop one.

        4. Requirements

        The Lua interpreter requires a processor and some amount of random access memory (RAM), it can be satisfied with few resources but - because it is not a stripped down package - it needs some. At startup the Lua interpreter consumes about 17kB of RAM but memory usage depends on the allocation of variables. The interpreter itself needs some memory too and a larger amount of flash for the code itself. Therefore a starter kit with 256kB with RAM and 1MB of flash is used: a Pearl Gecko.

        The starter kit has some hardware, LEDs, buttons, temperature-sensor, LCD display. It provides the possibility to show how a hardware element can be controlled by Lua.

        Also there must be a possibility to upload programs to the starter kit to change its behavior, therefore we need a mechanism to deliver script code (from outside to the kit) that can be executed on the board.

        5. Architecture

        The structure of the project can be seen on the next picture.


        To the main application a Lua interpreter module is linked but it (the main) does not call into it directly. Instead an interface is created where the application can request some services.

        In this project it can require only two things:

        • load a script (from outside)
        • execute the loaded script

        Lua can do a little bit more:

        • control the LEDs (on/off/toggle)
        • read the button states (up/down)
        • read the values from the temperature sensor
        • read and write from/to stdin/stdout (see later)
        • write onto the LCD screen (lines/circles)

        6. Implementation

        Because Simplicity Studio creates makefiles on the fly, it is not difficult to add a Lua interpreter to the project. You have to create a simple example project that fits your needs and add a new folder inside the project directory. Download the Lua source files from the website and copy all the source files into the newly created directory, except `lua.c` and `luac.c` (or exclude both files from the compilation). Both are in the Lua distribution to demonstrate the use of the Lua package. `lua.c` passes the overgiven parameters from the command line to the interpreter; `luac.c` is a Lua 'compiler' (Lua converts the scripts into tokens before executing it). Both has a `main()` function therefore they cannot be added to the project. Don't forget to add the folder to the include directories that other files can include the Lua header files.

        The next step is to create an interface to Lua. This has a predefined protocol. Because Lua is a dynamically typed language, data exchange to the host language occurs over a so-called 'virtual stack'. Lua (or the C code) places values onto that stack and the other language can use it.

        The other thing is to have an interface from Lua to the Gecko SDK (thus to the hardware). This can be done by simply calling functions of the SDK, all the examples and applications do that.

        To have access to the Gecko SDK, Lua has to be extended with C code. C code that is called from Lua must be registered in the interpreter, that means that if the script executes an appropriate statement (e.g. a function call) then the corresponding C code is executed. It communicates (overgives parameters and returns results) over the previously mentioned virtual stack.

        In the example application interface to controlling the LEDs, the LCD display, reading the temperature sensor is implemented. Read and write to the standard input/output files is also implemented (only partly). The Gecko does not have console therefore these read/write operation are redirected to the already present VCOM interface and by connecting a computer to the serial line (with a terminal program) this can be used as a text based interface (for humans and applications).

        Functions that can be called from Lua are as follows:

          print(...)              -- print to console
          LED(0, true)            -- switch LED on/off
          temp, rh = TempRh()     -- measure temperature
          Delay(400)              -- sleep for x miliseconds
          ToggleLED(1)            -- invert LED state
          ClrScr()                -- clear the LCD display
          Line(1,2,3,4)           -- draw a line (on LCD)
          Circle(64,64,40)        -- draw a circle
          LCDrefresh(bool)        -- switch LCD refresh on/off
          bool = IsBtnPushed()    -- read button state (BTN1)
          str  = ReadCon()        -- read a line from terminal
          DrawPixel(x, y)         -- draw a dot on LCD

        To have a console-like user interface the project redirects standard I/O files to a serial line. The SDK has already predefined files for that. Add

        retargetio.c
        retargetserial.c

        to the project files. These pass `printf/getch` type function outputs to the already on the board present VCOM serial line and reads the input from that line. The data will be sent through the USB port to the connected computer. You can use a terminal emulator program (Tera Term, minicom, PuTTY) on your computer to communicate with the board.

        The provided project export (the .sls file) has to be imported (into Simplicity Studio), compiled and flashed onto the Gecko board. The user can use a terminal program to communicate with the application. I use Teraterm because it has the ability to upload files with the XMODEM protocol already implemented. The computer side can be of course a custom application. In that case other type of serial protocol can be used but it have to be implemented on both sides. In that case the file `lfg_xmodem.c` has to be changed/replaced. Baud rate has to be set to the value of 115200.

        lfg_xmodem has a very simple interface, it provides only one function: 
         

        int lfg_XmodemReceive(char *recvBuffer, int recvBufSize, int *actSize);


        It starts the communication and places the received data into the provided text buffer and reports the number of received data into the variable that points `actSize` to. Return value can be LFG_OK or an error code.

        7. Uploading scripts

        There is not much of use of an application when the scripts has to be inserted/compiled into the C code. It loses the flexibility provided by the script language. Therefore the example project uses the XMODEM protocol to copy scripts from a computer to the Gecko board over the serial line. Fortunately there is already a serial line present called VCOM. If you plug in your board via the USB connector it does three things. Implements a JTAG interface, creates an USB mass storage device, realizes a serial communication interface. The latter is used to upload scripts to the board. COM port number can be determined by the Device manager or by the /dev/ttyUSBx file (in Linux).

        XMODEM is a simple file transfer protocol, it allows users to transmit files between computers when both sides use the same protocol. The next picture shows the program structure to receive data:

        8. How to use

        By pressing the reset button on the Gecko board the following lines are displayed on the terminal:

        Lua for Gecko - example application
        memory used :   11.18164 kB
        
        Enter command (or help).
        >
        

        Enter 'help' to display the available commands.

          led 0 on        switch led 0 on
          led 0 off       switch led 0 off
          led 1 on        switch led 1 on
          led 1 off       switch led 1 off
          temp            measure temperature
          clrscr          clear the LCD display
          cls             clear the console
          ---------       ---------------------
          load            load script (from PC) with xmodem protocol
          cat             display loaded script
          dump            display loaded script as hex
          forget          clear loaded script
          run             run loaded script
          help            display help

        Most of them are fairly straightforward, one thing has to be explained: the script upload.

        The XMODEM protocol requires that the receiver (the Gecko board) starts the communication, but the sender (the terminal program) has to be already in 'send' mode and waiting (for the start signal) to start sending. Therefore the first thing is to put the Gecko board into send mode by entering the `load` command. This does not start the communication but waits for an event to start. The Tera Term program must be instructed to send a file (File -> Transfer -> xmodem -> Send... menu item). It will wait for a start signal from the receiver. The start signal can be issued by pressing the `BTN0` button on the Gecko board. Press BTN0.

        That loads a script onto the board. There are already some example scripts that the user can upload (e.g. example1.lua ...). This uploads but does not start the script automatically. To run the script the `run` command has to be entered. Type 'run'.

        a.) enter 'load' on the terminal (Tera Term)
        b.) use send-file in Tera Term
        c.) press 'BTN0' on the Gecko board
        d.) type 'run' into the terminal

        9. Future improvements

        If all went well you have a working environment where you can evaluate Lua running on a Gecko board. But there is a lot of space for improvement.

        • Persistence
          • Scripts should be stored in a persistent storage that they can live also after reset. There is only one such kind of storage: the flash. For that the so-called 'user page' or the 'NVM3' can be used. On a Giant Gecko an SD card can be used.
        • Debug
          • More complex script have also more complex behavior. Sometimes it needs to be evaluated by a step-by-step execution.
        • Radio
          • A good improvement would be to deliver scripts over the air by using a radio board.

        Additional notes:

        • the used XMODEM implementation is not for a production scale application. It has no timeout, no error recovery. Only receive is implemented. It has been only used for the task to deliver code to the board.
        • in the file `luaconf.h` the #define LUA_32BITS is activated to use 32 bit integers.

        Examples

        There are already some examples in the `src` folder:

        • example1.lua:
          •   demonstrates the use of LEDs, measuring temperature and drawing lines on the LCD screen
        • example2.lua:
          •   reads the BTN1 button state and reports it to the terminal
        • example3.lua:
          •   reads a line from the console
        • example4.lua:
          •   displays graphic on the LCD screen

        Fazit (conclusion)

        "Lua is becoming the language of choice for anyone who needs a scripting language that is simple, efficient, extensible, portable, and free. Currently, Lua is being used in areas ranging from embedded systems to Web development and is widely spread in the game industry, where knowledge of Lua is an indisputable asset." (Google.books)

        Lua has a lot of sophisticated additional things under the hood (tables, metatables, threads, user defined types ...), this article scratches only the surface of the possibilities that can be reached by using a powerful script language.

        Thank you. 

      • Simple BLE scanner for Thunderboard (or any EFR32BG kit)

        Tyler | 05/131/2020 | 08:25 PM

        This is a very simple project. It seems that there is no BLE scanner example available for the Blue Gecko parts. Some of the examples involve scanning (for example the SPP example or throughput tester example) but I could not find a simple "hello world" type scanner example. So I decided to write one.

        I tested the example on Thunderboard BG22 kit, but basically it should work on any kit. It is based on the soc-empty example. Only small modification is needed to the source code (app.c) to turn the soc-empty into a BLE scanner.

        The source code is attached. To try it out:

        • create the soc-empty example for your kit
        • replace the original app.c with the attached version
        • in app.h, set DEBUG_LEVEL to 1 and DISABLE_SLEEP to 1

        When you run the example, it starts scanning immediately at boot (unlike the original soc-empty that starts advertising).

        Scan responses are handled in function process_scan_response(). This is based on the code that I copied from the SPP example. I modified the code so that it looks for vendor specific advertising payloads (AD type = 0xFF) and prints the company ID to console. It recognizes Apple company ID (0x004C). If you need to look for any other company identifiers, then the complete list can be found at https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers/

        The example is intentionally left very simple. It includes the basic processing of advertising packets (you can detect device name or company ID). It should be simple to modify the code to parse any kind of packets (such as iBeacon format, or any custom format you might be working with).

        Any questions or suggestions? Drop a note below.

        Here's a sample of what the output looks like:

        If the advertising data contains device name (either full or shortened), then the name is also printed to terminal.

      • Theremin over BLE

        Jesus Grillet | 04/107/2020 | 11:09 AM

        Theremin over BLE project

        The following article goes over an example project for a job fair where the Silicon Labs Budapest participated.

        Project Background:

        The goal of this project was to create an interactive and fun Demo that would catch the attention of the public while being simple and using our hardware. A Theremin accomplishes this by being fun to play with and loud to catch people's attention while showing the capabilities of our wireless and sensor kits.

        Description:

        The theremin will be composed of an EFR32MG12(BRD4162A) and a Si1133/Si115x Optical Sensors Expansion Board(BRD8009A). The sound is played in a mobile phone or a tablet using the MIDI over BLE service.

        Setup

        Project Overview:

        The following image illustrates the setup:

        Diagram

        1. the Optical Sensors Expansion Board(BRD8009A) was used to control the sound, an interface was created using the Gesture mode to poll 2 of the 3 IR LEDs, left and right side. Left side channel controls the volume and right side channel the sound pitch, this is done by measuring the proximity of the hand to the irLED.

        User guide for the Optical sensor board: UG163: Si1133/Si115x Optical Sensor Evaluation Board Rev 3.0 User's Guide Optical Programmer's Toolkit: Si115x_PGM_Toolkit.exe This toolkit is useful for looking at the demos and for evaluating how the part would behave in a real product. We urge customers to add their own overlays or optics to this board and then use this application to see what kind of optical signal their system would see.

        1. The sensor board communicates to the EFR32 via I2C using the Expansion connector

        2. BRD4162A contains an EFR32MG12, it is used in SoC mode as peripheral device advertising to create an application that will parse the data receive from the sensor board to the Midi protocol.

        3. The EFR32 will transmit said data to a connected device using the Midi over BLE protocol. To add this functionality the [KBA_BT_0911: Midi over BLE] (https://www.silabs.com/community/wireless/bluetooth/knowledge-base.entry.html/2019/06/19/kba_bt_0911_midioverble-ZvKw) was used.

        4. Depending on the mobile device used (Android or iOS), an app needs to be downloaded to receive the Midi data in your device. iOS: KORG Module free version app can be used. Android: MIDI BLE Connect app. This app will allow to connect to BLE Midi devices and after connecting the device can be used with any app that supports midi.

        5. In the case of android device a midi output app is needed. FluidSynth MIDI Synthesizer was used in this project, to either output to the phone speaker or to an external one via the headphone jack. For iOS devices the KORG app handles the BLE connection and the midi output.

        Source files

        1. Create a soc-empty example from the SDK example projects.

        2. Copy the files attached in the project root folder and overwrite the existing files.

        3. From the Gatt configurator import the gatt.xml file that was copied into the project root folder.

        4. Copy \developer\sdks\gecko_sdk_suite\v\platform\emdrv\gpiointerrupt\src\gpiointerrupt.c to the soc-empty project

        5. Build and flash

        6. Connect to your device using a Smartphone/Tablet: *Android: download MIDI BLE Connect app and FluidSynth MIDI Synthesizer app. Connect with MIDI BLE connect and open FluidSynth MIDI Synthesizer and select the device. *iOS: download KORG module and connect via the BLE midi menu.

        7. Play with your hands over the sensor.

      • EFR32MG21A010F768 PWM

        li ye | 11/317/2019 | 07:43 AM

        Silicon Labs 无线SOC EFR32MG21的PWM的输出需要将TIMER的CC端口配置到GPIO上,如下:

         GPIO->TIMERROUTE[0].ROUTEEN = GPIO_TIMER_ROUTEEN_CC0PEN | GPIO_TIMER_ROUTEEN_CC1PEN;

          GPIO->TIMERROUTE[0].CC0ROUTE =

            (LED0_PORT << _GPIO_TIMER_CC0ROUTE_PORT_SHIFT)

            | (LED0_PIN << _GPIO_TIMER_CC0ROUTE_PIN_SHIFT);

          GPIO->TIMERROUTE[0].CC1ROUTE =

            (LED1_PORT << _GPIO_TIMER_CC1ROUTE_PORT_SHIFT)

            | (LED1_PIN << _GPIO_TIMER_CC1ROUTE_PIN_SHIFT);

        请问,GPIO_TIMER_ROUTEEN_CC0PEN这些宏都定义在哪个文件下,为啥我的工程无法识别

      • Control a WIFI-based Device with an Tmall Genie

        Victor Hu | 12/363/2018 | 01:25 AM

        1 Introduction

        People used to regard mobile phones, TVs or routers as the control centers of smart homes until the emergence of smart speakers. It should be that you control your smart devices just by saying a sentence such as "Open the light of living room", rather than by clicking on the phone screen. Now, there are so many smart speakers in market for controlling the smart device, two of the most famous are Google Home from Google and Echo from Amazon. In China, the most famous smart speaker are XiaoAi from XiaoMi and Tmall Genie from Alibaba. Now, all of these companies have developed IoT platform so that the manufacturer who produce smart homes can connect their smart productions to these smart speakers. This project is intended to introduce how to control a Silicon Labs Wi-Fi device.with TmallGenie.

        The software architecture of project consists of:

        • Firmware running on EFM32GG11 STK
        • Web server running on cloud.

        The hardware consists of :

        • A EFM32GG11 STK
        • A WGM110 Wi-Fi Expansion Kit
        • A Tmall Genie smart speaker.

        User can control the LED0 in EFM32GG11 STK through one of two methods below.

        We assume the whole device combine the EFM32GG11 STK and the WGM110 module is a smart light. The block is illustrated below.

        2 Preparation

        2.1 Device Connection

        Connect the boards as illustrated in the picture below. Configure the EFM32GG11 STK board switch as AEM and configure the WGM110 Expansion Kit switch as High Power. 

        2.2 Firmware

        Import the firmware to Simplicity Studio, open file "app_wifi_cfg.h", modify the macro APP_WIFI_AP_SSID to your Wi-Fi SSID and modify APP_WIFI_AP_PWD to your Wi-Fi password, as the picture shown below. Then compile it. Program the Hex file to EFM32GG11 Giant Gecko Starter Kit (SLSTK3701A) to make it as a smart light device. The compiled firmware is located directory Bin/, the default Wi-Fi SSID is "netis_1F7506" and the password is "password", if you want to recompile the firmware you can configure your Wi-Fi.

        When the firmware is runing for the first time, it needs to report itself to silabs-iot. It will issue a http request to silabs-iot so that web server of silabs-iot will add information of the device to database, then the device can been used by one of users.

        2.3 Bind the device with your account

        You need to bind the device and declare it belongs to you then you can control it. Please follow to the steps below to bind a device.

        • After you sign up or log in, you will enter the MyDevice page, as the picture shown below. 

        • Click icon "+" to add a device, fill the Mac address and device name in the pop-up window, the Mac address can be found in the EFM32GG11 STK LCD screen when you push BTN1(Before that, make sure your devcice have connect Wi-Fi correctly, you can only bind the device which has connected internect and hasn't been binded by other users. For testing, we provide 3 fictitious mac addr: 0123456789, 0123456788 and 0123456787, you can choose one for testing and remeber to unbind it after using). Click "OK" will finish binding. 

        3 Control device by Browser

        After binding your device, you can see it on the MyDevice page. click the device and will pop up a window on which there is a switch, you can turn on/off the LED just by click the switch. 

        4 Control device by Tmall Genie smart speaker

        At first, you need to download a Tmall Genie App into your phone and bind your Tmall Genie following the hint of Tmall Genie App. Please follow to the steps below to bind Silabs-iot with Tmall Genie.

        • Click "我的" ("Mine")
        • Click "添加智能设备" ("Add Smart Device")
        • Find SiliconLabs in device list and click it
        • Click "绑定账号" ("Bind Account")
        • Input the account and password that you get from silabs-iot.com and click "LOGIN AND AUTHORIZE".
        • Return to "我的" the device in silabs-iot.com will be shown in the window. 

        Now, you can control the device just by talking to Tmall Genie, such as "天猫精灵,开灯" ("Tmall Genie, Open Light Please"). The video attached demonstrate how to control the device with Tmall Genie by voice.

         

        Note: The Tmall Genie only supports Chinese and it supports turn on/off and query on this case.

        5 Web Server

        The web server of silabs-iot is developed with ThinkPHP5.1, ThinkPHP is a free, open source, fast and simple object-oriented PHP development framework for web application development, visit it from https://www.kancloud.cn/manual/thinkphp5_1/353946.

        5.1 Processes of Control by Tmall Genie

        The following image illustrates the processes of communication among the web server of user, Tmall Genie, silabs-iot, alibaba web server and device.

         

         

        • Alibaba web server needs to obtain limited access to silabs-iot so that it can get device information and control it, get details from section 5.2  Authorization between Alibaba and silabs-iot .
        • Alibaba will issue a http request to silabs-iot to get all device information. The web server of silabs-iot will check the identify of visitor and then return all devices list owned by the user.
        • Alibaba get the deice information and display them in device list of Tmall Genie App.
        • User say a command to Tmall Genie.
        • Tmall genie will upload the voice to Alibaba web server.
        • Alibaba parse the voice.
        • Alibaba issue a new http request to silabs-iot according to the result of voice parsing, for example turn on light. The web server of silabs-iot will update the database after receiving the request from alibaba and return response immediately.
        • The device will poll the state by issue a http request periodic to silabs-iot and update itself. Get details from section 5.3 Communication between device and silabs-iot
        • Alibaba return response to Tmall Genie
        • Tmall Genie plays a voice as a repsonse of user's voice command.

        5.2 Authorization between  Alibaba and silabs-iot

        The authorization protocol between them is based on OAuth2.0. OAuth2.0 is an open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications, get more details from https://oauth.net/2/ . The OAuth2.0 server on this case is based on the library from Brent Shaffer, download it from GitHub:  https://github.com/bshaffer/oauth2-server-php. The process is divided into the following steps, as the picture shown below.

         

        1. The Alibaba web server will jump into the Log in page of silabs-iot.com when you click 3rd-party login in Tmall Genie App.
        2. Input account and password to log in, if success, the web server of silabs-iot will generate a code.
        3. Return the new code to Alibaba web server, the code only used by Alibaba and can only use once.
        4. Alibaba get the code and request an access_token to silabs-iot.com with it.
        5. The web server of silabs-iot checks the code and identify of visitor, it will generate a access_token and refresh token if success. The access_token is time-sensitive and the time can be configured, it is 2 days in this case. The refresh_token is used to request a new access_token when the access_token is expired.
        6. Alibaba web server will store the access_token and refresh_token. Now, it can access silabs-iot with access_token.

         

        5.3 Communication between device and silabs-iot

        The communication between devices and web server is based on Http protocol. The device need to visit web server periodic so that it can update the LED0 once the Tmall Genie change the state of light.

        1. Device issues a new http request to silabs-iot.
        2. The web server gets the mac address and query the state in database.
        3. The web server returns the state value of the device.
        4. The device parses the http response and update LED0 according to the results.

      • Win a Wireless Xpress BGX13P Starter Kit!

        Nari Shin | 10/295/2018 | 09:31 AM

        We’re excited to introduce the new Wireless Xpress BGX13P starter kit, which helps you jumpstart your design with no software development necessary. Some of the key features of this kit include:  

        • Bluetooth 5 BGX13 module requiring no firmware development
        • Zero-overhead serial-to-Bluetooth cable replacement solution
        • Smartphone app for Bluetooth LE command, control, and sensing
        • Secure connections with encrypted communication, bonding, and ‘just works’ and passkey pairing options
        • Ideal solution for smart home products requiring Bluetooth control with a mobile app, and the ability to add point-to-point wireless interface to industrial applications

        Want to try it for yourself? We’re giving away five Wireless Xpress BGX13P starter kits to our community members, and this is your chance to get your hands on one.

        How to Participate:

        Explain up to 2 ideas on how you want to use the Xpress kit for your project and why. You can submit your idea by leaving a comment below on this page by November 11th (CDT). 

        Judging Criteria

        Our Wireless marketing team will judge submissions based on the following criteria:

        • Market Potential (50%)
        • Differentiation (30%)
        • The fit between the Xpress kit and your project (20%)

        Prize

        Number of Winners: 5

        Prize: 1 x Wireless Xpress BGX13P starter kit

        Contest Period

        Oct 22nd 2018 – Nov 11th 2018 (CDT)

        The winners will be announced on this page soon after the end of the contest.

        By entering the contest, you acknowledge that you have read and agree to the attached Community Contest Terms and Conditions.

      • Oscilloscope Simulation System

        Victor Hu | 09/257/2018 | 02:57 AM

        1 Introduction

        The Oscilloscope Simulation System based on EFM8UB1 works as a tool to sample an ADC value and display it as waveform on a computer screen. Although it is a combination of hardware and software, it looks like a real oscilloscope.

        The software architecture of this system consists of firmware running on EFM8UB1 STK and an application running on a computer. The GUI application running on the computer was developed using python 2.7, pyside2, Qt5, and the USBxpress library.

        The hardware consists of a computer host and an EFM8UB1EK device. The EFM8UB1EK is connected to the computer with a USB cable. You can use EFM8UB1 to sample the ADC voltage value and, send the collected data to the host via USB. The block is illustrated below.

         

        2 Preparation

        2.1 Install Python 2.7 32-bit

        Most of library made by Silicon Labs was developed with Python 2.7 32-bit. Please download and install Python 2.7 32-bit. Here is the download link: https://www.python.org/downloads/release/python-2715/

        2.2 Install Pyside2 and Qt

        Official release wheels of Qt for Python can be installed regularly via pip:

        pip install pyside2
        

        Pre-release (snapshot) wheels containing the latest code changes are available at http://download.qt.io/snapshots/ci/pyside/

        For example you can install the latest 5.11 snapshot wheel using:

        pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.11/latest/ pyside2 --trusted-host download.qt.io
        

        See more info from http://wiki.qt.io/Qt_for_Python/GettingStarted.

        2.3 Firmware Programming

        The compiled firmware is located in the directory Bin/. Program the Hex file to EFM8 Universal Bee Starter Kit (SLSTK2000A) to make it as an oscilloscope device.

        Connection

        Connect the EFM8UB1EK device and a computer with a USB cable.

        2.4 Execute GUI application

        Download the software/ to your local device and run the application with the command below.

        python.exe main.py
        

        3 Overview GUI

        The application will start with a login widget as shown below. The component 1 is a device combobox that shows the connected EFM8UB1EK device, and the component 2 is a pushbutton.

         

        The device shown in the combobox will be open, and the application will jump to a main widget when the pushbutton is pressed.

         

        District 1 is a canvas which can be used to display the waveform. When the cursor is in this district, the time and ADC value of cursor position will be shown.

        District 2 is the display district. The buttons in this district are the zoom in pushbutton, the zoom out pushbutton, the enable ADC pushbutton, and the single trigger button from left to right.

        District 3 is used to control 3 LED on the EFM8UB1EK device.

        District 4 is used to enable channels. There are two channels available: the routed to the GPIO pin1.7 and the GPIO pin1.2 respectively.

        District 5 is the frequency district. The sample frequency will be set to the value shown in the combobox when the set pushbutton is pushed.

        The current information will be shown in district 6.

        4 Start sampling

        Once you have all the required environments and equipment, you can start sampling by following the steps.

        • Connect the device and host
        • Execute the GUI application
        • Choose the required device in combobox and press the enter button
        • Check the required channel
        • Choose the appropriate frequency and then press the set button
        • Push the enable ADC button in district 2

        After that, the waveform will now display in district 1.

        5 Software development and functional development

        In order to facilitate continued function expansion, a flexible protocol was developed. Every operation is an item of command which consists of preamble byte, command byte, value length and value. The preamble byte is a fixed value 0xAA, the command byte shows the specific operation, and the third byte followed by a value is the length of the value. The table shown below lists the command that have been taken. If you want to develop a new command, you can start with 0x60.

         

        6 Conclusion

        The oscilloscope simulation system is used to sample analog voltage and show it as waveform. It provides two channels to sample the voltage signal, supports zoom out and zoom in, and can display voltage and time information on the mouse cursor point, making it look like a real oscilloscope. It is an important tool for measuring analog voltages for engineers.

        7 Source Code

        The source code of the GUI tool and firmware is attached for reference.

      • Zigbee to Modbus TCP/IP Gateway

        gettogupta | 07/195/2018 | 03:43 PM

         

        Zigbee to Modbus Gateway

        Fact #1 : Industrial IoT is one of the biggest slice of the global IoT pie.

        Fact #2 : Zigbee is a popular industrial communication wireless standard

        Fact #3 :  Modbus is an indispensable part of industrial automation.

        Our technical team realized this opportunity and came up with this Zigbee to Modbus TCP/IP gateway, that can act as an interface between a industrial Zigbee network and a Modbus TCP/IP or even a general TCP/IP network and hence the internet at large. 

        Naturally, when it came to selecting a Zigbee module we decided to go with the Telegesis ETRX357-LRS module, for a host of reasons. For the TCP/IP end we used the Xpico module by Lantronix. Because the Xpico comes in a general TCP/IP stack version and also a Industrial Modbus TCP/IP stack version. 

        To make the product more versatile we decided to add a ARM Cortex M4 MCU for some custom firmware and device management. To make the product truly easy to use and deploy on field we added a PoE+ (IEEE 802.3at) power option. 

        Look forward to comments and suggestions from experts here on potential use cases and opportunities with the product. 

      • IoT Party Button

        Mark Mulrooney | 02/33/2018 | 05:58 PM

        The following is a project write-up from a recent hackathon that took place with the Silicon Labs MCU and Micrium Application Engineering teams. The members of this team were Mark Mulrooney, Michael Dean, Alan Sy and Joe Stine.

         

        Project Summary:

        The goal of this project was to create an IoT enabled Party Button that would allow a user to press a button and trigger a number of party lights all to turn on at the same time. This was accomplished using a combination of Silicon Labs EFM32GG11 Starter Kits, Silicon Labs EFR32MG12 Starter Kits, Silicon Labs Smart Outlets, Silicon Labs Si8751-KIT Isolators, Dream Cheeky Big Red Button and a lot of party lights/disco balls. Using this hardware, a signal was send from the Big Red Button to an MQTT broker which then propagated to out to Giant Gecko kits that listening for a signal. Some of the GG11s had the isolator connected directly to the board and would toggle their specific party light and other GG11s were connected over serial to a Mighty Gecko kit. The Mighty Gecko would send a ZCL on/off message over Zigbee to other Mighty Geckos or the Silicon Labs Smart Outlet to control the other party lights.

         

        Project Background:

        Since our team typically works on the EFM32 platform or with software other than Micrium OS, our main goals of this project were to become familiar with the EFR32 chips/tools and to use Micrium OS to add internet connectivity to a LAN IoT ecosystem such as a Zigbee network. As we found out, the project did prove to be a good exercise in both the EFR32 and Micrium OS.

        The project can be divided up into three main sections: MQTT, Zigbee and Isolation. An advantage of this was since the project was somewhat complicated and involved a lot of moving parts, it allowed our team members to work on different parts of the project without holding up another part of the team. The following sections describe the different parts of the project and how they operated.

         

        MQTT:

        MQTT Diagram

        The IoT Party Button project used MQTT as the communication protocol between the Big Red Button and the GG11 nodes. MQTT is a lightweight publish-subscribe IoT protocol that sits on-top of TCP. For our project we used the Mosquitto broker as our MQTT broker for all of the clients to connect to. The Mosquitto broker was hosted on an AWS EC2 instance and implemented a simple username/password for some basic security. In a real-world application you would ideally use TLS in conjunction with MQTT to encrypt your connection to an MQTT broker.

        The project used MQTT for control of the trigger for a few reasons. The biggest reason was flexibility. Initially, during the planning of the project we discussed the possibility of plugging the Big Red Button into a Giant Gecko. This would have allowed us to use the Micrium OS USB stack to detect the button press and Micrium OS Net’s MQTT client to publish the button push to the MQTT broker. Since we only had a few days to complete this project we were unsure if there would be enough time to complete this portion, so we set that part aside.

        For testing purposes, we created a simple button simulator in Node.JS that could run on anyone’s computer and publish a message to the MQTT topic for a button press. Since we did not have enough time to complete the USB portion on a GG11, we ended up using a Node.JS script to listen for a button press while the button was plugged into one of our computers. When the Node.JS script detected the button press it sent an MQTT message to the trigger topic.

        Another advantage of using MQTT for control of the trigger is it opened up the ability to have the trigger sent from a number of places. We use Slack as a communication tool in the office, but we also have a helper bot that you can send commands to. It is possible that we could have had the bot send the same MQTT command to the MQTT broker to trigger the IoT party.

        All of the GG11s that were subscribed to the MQTT topic for the button trigger used Micrium OS and the Micrium OS Network MQTT client. Once the Micrium OS portion was set up, the subscribed nodes had one of two functions: either trigger an isolator connected to it or send a serial command to a Mighty Gecko to trigger it’s local network via Zigbee. For simplicity’s sake, we used the same application on all of the GG11s. This allowed us to program them all up without the need for individual code changes.

         

        Zigbee:

        Zigbee diagram

         

        The Giant Gecko kit only has Ethernet, we found it was not practical to use Giant Gecko’s for every node in our project. Instead, it was easier to use one Giant Gecko that had an Ethernet connection and use a Mighty Gecko to send the command out wirelessly to all nodes in its network. It also allowed us to use some of the Silicon Labs Smart Outlets as nodes in our project.

        Zigbee networks typically have three different types of nodes in them: Coordinator, Router and End Device. In our project, the coordinator was connected to the Giant Gecko via serial to receive the on or off command and would then relay that command out to all of the nodes in the network. The coordinator was configured using AppBuilder in Simplicity Studio. AppBuilder allows you to specify what packages should be included and generates the necessary code. Since the Giant Gecko was connected to the Mighty Gecko over serial, we enabled the command line as a simple way for the Giant Gecko to send commands to the Mighty Gecko.

        We took advantage of the Zigbee Cluster Library in this project to simplify the format of the on or off message being sent to the nodes. Also, the Silicon Labs Smart Outlets by default use the ZCL on/off library so we did not have to do any configuration on the outlets. Once the command line and ZCL on/off library was enabled in AppBuilder, it was able to put our project together and we were able to flash our coordinator.

        The rest of the nodes in our project were configured either as a router or end devices. Similar to the coordinator we used AppBuilder to generate a project that listens for ZCL on/off messages, but in this case, we did not need the command line. We did however have to add code to the ZCL on/off hooks to toggle a GPIO which would in-turn, toggle the power switcher which was connected to our party lights.

         

        Power Switching:

        To be energy friendly, we decided our system should control the power of the disco light. Our MCU board is running off DC power, but the disco light is powered by AC from a standard wall outlet. So we needed to control AC power from a DC system. To be safe, we should isolate the AC power from the DC power and use a high power MOSFET to turn on and off the AC power to the disco light. Fortunately, Silicon Labs makes an evaluation kit that does just this.

        The Si8751-KIT contains an evaluation board that takes care of isolating two power systems and allows for a digital input on the low voltage, DC side to control the MOSFET on the high power, AC side. Set up was as simple as configuring a few jumpers on the board, connecting the low power side to the VDD, GND, and a GPIO of the MCU, and then connecting the high-power side to the AC outlet and the disco light.

        We also had another disco light that operated from 12V DC, and fortunately, the SI8751-KIT also has high voltage DC isolation capabilities. So, we used a second Si8751-KIT to isolate the 12V DC from our low voltage DC system on the wireless MCU.

         

        Lessons Learned:

        This project required a fine balance between several different protocols all within the same network. This meant there were a lot of moving parts to deal with so sometimes it was difficult to determine where a problem may be occurring. Over the course of the week our debugging skills became a little more fine-tuned but we definitely had some hiccups at first.

        By far our biggest challenge was working with Zigbee. This was mainly because none of us were familiar with the tools or the development kits. The Zigbee tools, as we found out, have a bit of a learning curve and a few tricks to them. We also got unlucky when the first example project we chose to try didn’t work because of a software problem in a newly released SDK. After determining the issue was with the project we moved on to a known working example, Dynamic Multi-Protocol. Once we started working with that project we quickly realized that we were using an example that had a lot of extra overhead we did not need and was confusing us.

        After our failed experiments with some sample projects we decided to start from scratch and build up our own project in the App Builder. After jumping through a few hoops we were able to get a project configured the way we wanted. We found that starting small and building off that was a much better approach than trying to use a complicated example and trim off the excess features. We also found that complicated projects like Zigbee can have a steep learning curve and we underestimated the amount of time it would take to complete the Zigbee portion. Luckily, we were able to complete the Micrium OS portion on the Giant Gecko rather quickly which gave us extra time to focus on Zigbee.

         

        Next Steps:

        Due to some issues with our Zigbee configuration, our project was not complete at the end of the hackathon week. Our final presentation had the ability to send a message from the Big Red Button to the MQTT broker and down to the EFM32GG11 boards, the ability to send a serial command from the EFM32GG11 to the EFR32MG12 and the ability to switch the isolators from either the EFM32GG11 or EFR32MG12. The one gap in the project was sending the ZCL on/off message correct to all of the nodes in our network. An obvious next step for this project would be to rectify the issues in our Zigbee network configuration.

        Beyond getting the Zigbee network configured correctly, we had a few other improvements that could be implemented. First, the Big Red Button could be connected a EFM32GG11 running Micrium OS USB Host to read the button state and send it via MQTT using Micrium OS Network. The second improvement we talked about was actually hooking up a Slack chat bot to have a command to trigger the party instead of using the Big Red Button.

         

        Conclusion:

        While we were not able to get the project working as intended, it proved to be a very valuable exercise to explore the EFR32MG12 and a fun way to do it.

      • Wireless PC Remote for volume and media control

        BrianL | 02/33/2018 | 04:00 PM

        Recently, our MCU Applications team and our Micrium OS team decided to spend a few days, in teams, on a "Hackathon". This allowed us the opportunity to work on a larger, real-world application, in an effort to gain more insight into our products and uses.

        Our team comprised of Brian Lampkin, Janos Magasrevy, and Yanko Sosa. For our project, we decided to create a PC media controller for wireless volume and media control. This would consist of a wireless USB Dongle, connected to a wireless remote controller to provide media controls such as volume up/down, next track/last track, mute, etc.

        1. Requirements

        1.1 Hardware

        1. A USB ‘Dongle’ to provide wireless connectivity to the controller.

          This required a USB interface MCU to communicate with the host PC and a radio MCU to communicate with the remote. For the USB MCU, we chose an EFM32HG, since it is relatively small, and our application – a simple UART to USB HID command bridge – would require little flash. For our Radio MCU, we chose an EFR32FG12 device, which could cover any proprietary protocol we chose to implement. This would provide our UART to Wireless bridge.
           
        2. A wireless ‘Remote’ to provide the user interface for the media controller.

          We chose another EFR32FG12 radio MCU, to pair with the other on the USB dongle. Since this was to be a battery powered remote, we needed an MCU that could be run in a low duty-cycle, low power mode. To provide the user interface, buttons and a joystick on an expansion board were used.

          The completed remote and dongle hardware, using an EFM32HG STK with a Wireless Expansion Board and EFR32FG12, along with an EFR32FG12 Wireless STK with a Joystick Expansion Board, are shown below:

         

        1.2 Software

        An additional requirement was added – the project must integrate Micrium OS in some manner. We chose to implement this on the EFR32FG12 wireless devices to help manage wireless connectivity and low power features.

        2. System Overview

        The system block diagram is as follows:

         

        Buttons and Joystick input are taken by the remote’s Flex Gecko MCU, and converted into wireless packets that represend media commands. These are transmitted to the dongle’s Flex Gecko, which are then converted into UART transmissions to the dongle’s Happy Gecko MCU. Finally, these are interpreted as HID media control commands, sent to the host PC over USB.

        The joystick expansion board was mapped to the following media control functions:

         

        2.1 Wireless Protocol

        Our project has a very simple wireless communication requirement. When a button is pressed on the remote, this button status must be transmitted from the remote to the dongle’s receiver. Since there are few functions, a single byte payload was used to transmit this data. The remote never needs to receive any information from the dongle, so the dongle can be kept in RX mode, while the dongle can transmit a byte whenever the state of the remote’s buttons changes. This is an extremely simple communication protocol, so we decided to use the lower level Radio Abstraction Interface Layer (RAIL) directly rather than utilizing a stack such as Zigbee or Connect.
         

        Since no stack is used, the protocol is effectively proprietary. 2.4 GHz was chosen for the radio’s communication band, as opposed to a Sub GHz band, as this allows for a smaller antenna, useful for a handheld remote.

        2.2 Energy Concerns

        As a battery powered device, low energy consumption is a huge priority for the remote. However, since the dongle is USB powered, there is little reason to limit the power consumption there. Thus, the dongle can be awake and in RX mode continuously with little drawback when connected to the PC's USB. On the remote side, however, consideration was given into keeping the device in lower energy modes whenever possible. Due to the dongle always being in RX mode, we can effectively keep the remote in a low energy state until a button press is made, triggering a new media function update. In our design, this means that the remote only wakes to transmit a packet, then immediately re-enters sleep mode.

        3 The Dongle

        3.1 USB HID Media Device

        The first step in the project was to create a device that could communicate to the PC as a media controller. We decided to implement a HID device, which allows for driverless communication to a PC host for a limited set of known functions. For this project, we implemented what is called a USB HID “Consumer Control” device. The description for the options available in interface is provided in a table in section 15. "Consumer Page" in the USB HID Usage Tables document available on USB.org. Some of the available commands found in this interface are:

        This interface includes many of the media controls that you would normally use during the use of a media application on a PC (Playing video, music, etc): Play, Pause, Record, etc. In this project, we chose to implement the following commands on our remote:

        1. Play/Pause – ID: 0xCD
        2. Scan Next Track – ID: 0xB5
        3. Scan Previous Track – ID: 0xB6
        4. Mute – ID: 0xE2
        5. Volume Increment – ID: 0xE9
        6. Volume Decrement – ID: 0xEA
        7. Play (Unused) – ID: 0xB0
        8. Stop (Unused) – ID: 0xB7

        We eventually decided not to use the Play and Stop commands, as the Play/Pause command that we found implemented the functionality we desired, and allowed us to reduce the total number of inputs to six, which would map neatly to our expansion board’s two buttons and joystick with four cardinal directions.

        3.1.1 HID Report Descriptor

        To interface with a host using the HID interface, a HID report descriptor, describing the functionality of the device, must be constructed. We used the HID Usage Tables document, which included several examples (Specifically, Appendix A.1 Volume Control contained a useful example on volume +/-), and the HID Descriptor Tool to construct the following HID Descriptor:

        // HID Report Descriptor for Interface 0
        const char hid_reportDesc[39] SL_ATTRIBUTE_ALIGN(4) =
        {
          0x05, 0x0C,       // USAGE_PAGE (Consumer)
          0x09, 0x01,       // USAGE (Consumer Control)
          0xA1, 0x01,       // COLLECTION (Application)
          0x15, 0x00,       //   LOGICAL_MINIMUM (0)
          0x25, 0x01,       //   LOGICAL_MAXIMUM (1)
          0x75, 0x01,       //   REPORT SIZE (1)
          0x95, 0x08,       //   REPORT COUNT (8)
          0x09, 0xCD,       //   USAGE (Play/Pause)
          0x09, 0xB5,       //   USAGE (Scan Next Track)
          0x09, 0xB6,       //   USAGE (Scan Previous Track)
          0x09, 0xE2,       //   USAGE (Mute)
          0x09, 0xE9,       //   USAGE (Volume Increment)
          0x09, 0xEA,       //   USAGE (Volume Decrement)
          0x09, 0xB0,       //   USAGE (Play)
          0x09, 0xB7,       //   USAGE (Stop)
          0x81, 0x02,       //   INPUT (Data,Var,Abs)
          0x75, 0x08,       //   REPORT SIZE (8)
          0x95, 0x01,       //   REPORT COUNT (1)
          0x81, 0x03,       //   INPUT (Cnst,Var,Abs)
          0xC0              // END_COLLECTION
        };
        

        This constructs a HID report with two bytes of data. The first byte implements 8 bit options, one for each of the HID commands. The second is a placeholder byte, unused by our application (but could be used for additional functions in the future).

        As a basis for our EFM32HG USB project, we used the usbhidkbd example, which implements a USB HID Keyboard. The conversion for this was rather simple, as the USB side only required a quick swap from the HID Keyboard descriptor to the new HID Consumer Device descriptor, above. With this change, the EFM32HG device now enumerated on the host PC as a media controller.

        3.1.2 USB to Radio Interface

        The next step in the process was to develop an interface that could communicate between the dongle’s radio MCU and the USB MCU to tell the PC when a media button had been pressed. For this, we implemented a simple UART interface.

        The media control functions are represented by single bits in the HID report's first byte's bitfield, as described below:

        typedef enum {
          PLAY = 0x01,
          SCAN_NEXT = 0x04,
          SCAN_LAST = 0x02,
          MUTE = 0x08,
          VOL_UP = 0x10,
          VOL_DOWN = 0x20,
        }reports_t;
        

        On the dongle side, the radio MCU merely sends one byte of data over UART with the appropriate bit set for the desired media function. This is then transmitted over USB by sending a HID report. When the EFM32HG MCU receives a byte over UART, the report is updated:

        void USART0_RX_IRQHandler(void)
        {
        	USART_IntClear(USART0, USART_IF_RXDATAV);
        	report = USART0->RXDATA;
        }
        

         

        Then, in the main loop, if the report has changed since the last one that was sent to the host, it is sent over USB:

            if (report != lastReport) {
        	  /* Pass keyboard report on to the HID keyboard driver. */
        	  HIDKBD_KeyboardEvent(&report);
        	  lastReport = report;
            }
        

        Note the function names and comments left over from the usbhidkbd example - a result of the limited modifications we had to make to this example to implement the media controller.

        3.2 Dongle Radio Receiver

        The Dongle’s radio receiver was built with an EFR32FG12 Wireless MCU, using RAIL as the radio interface layer. The firmware is extremely simple: a single byte packet is received from the remote device, and this packet is transmitted to the EFM32HG USB device over UART.

        3.2.1 Radio Configuration

        The EFR32FG12’s radio was configured using AppBuilder. We used the default settings for a 2.4 GHz, 1 Mbps PHY, modifying it for single byte packets. No other changes were made to this default profile’s settings.

        3.2.2 Radio to UART Implementation

        Once configured, the radio initialization is simple – the device’s radio is initialized and put into RX mode, while an RX callback is registered to handle the reception of the packet and its transmission over UART. The device then waits forever in a while loop to receive packets. The initialization routines are simply:

          // Configure RAIL callbacks
          RAIL_ConfigEvents(railHandle,
                            RAIL_EVENTS_ALL,
                            (RAIL_EVENT_RX_PACKET_RECEIVED));
        
          RAIL_Idle(railHandle, RAIL_IDLE, true);
          RAIL_StartRx(railHandle, channel, NULL);
          while (1) {
          }
        

         

        In the RX callback, the packet is received, the radio is put back into RX mode, and the packet is transmitted over UART:

        void RAILCb_Generic(RAIL_Handle_t railHandle, RAIL_Events_t events) {
          report_t packet;
          if (events & RAIL_EVENT_RX_PACKET_RECEIVED) {
            RAIL_RxPacketInfo_t packetInfo;
            RAIL_GetRxPacketInfo(railHandle,
                                 RAIL_RX_PACKET_HANDLE_NEWEST, 
                                 &packetInfo);
        
            // Receive the packet's one-byte payload
            packet = *(packetInfo.firstPortionData);
        
            RAIL_Idle(railHandle, RAIL_IDLE, true);
            RAIL_StartRx(railHandle, channel, NULL);
        
            // TX Packet over UART to EFM32HG
            USART_Tx(USART0, (uint8_t) packet);
          }
        }
        

         

        3.3 The Remote

        The remote has two main components – the user interface and the radio, used for transmitting user inputs.

        3.3.1 User Interface

        The user interface of the remote uses a joystick expansion board, which provides two buttons and an analog joystick for inputs. This expansion board is described in section 8 of this document: https://www.silabs.com/documents/login/user-guides/ug122-brd4300a-user-guide.pdf

        The analog joystick has an output of one pin which changes voltages depending on the direction the joystick is pressed in. To interface this joystick with the EFR32FG12, the device’s ADC is used to sample the voltage on the joystick’s output every 25 ms, triggered by the RTCC. This voltage is then converted into a direction in the ADC’s interrupt handler.

        #define ADC_MAX_CODES (0x0FFF)
        #define JOY_NONE_THRESH  (0.93 * ADC_MAX_CODES)
        #define JOY_UP_THRESH    (0.81 * ADC_MAX_CODES)
        #define JOY_RIGHT_THRESH (0.68 * ADC_MAX_CODES)
        #define JOY_LEFT_THRESH  (0.55 * ADC_MAX_CODES)
        #define JOY_DOWN_THRESH  (0)
        void ADC0_IRQHandler(void)
        {
          uint16_t sample;
          ADC_IntClear(ADC0, ADC_IF_SINGLE);
        
          sample = ADC0->SINGLEDATA;
        
          if (sample > JOY_NONE_THRESH) {
            joyState = JOY_NONE;
          } else if (sample > JOY_UP_THRESH) {
            joyState = JOY_UP;
          } else if (sample > JOY_RIGHT_THRESH) {
            joyState = JOY_RIGHT;
          } else if (sample > JOY_LEFT_THRESH) {
            joyState = JOY_LEFT;
          } else {
            joyState = JOY_DOWN;
          }
        }
        

         

        For the pushbuttons, GPIO interrupts were enabled for each pushbutton pin, which update the status of the buttons.

        void BTN_Handler(void)
        {
          bool BTN2, BTN3;
        
          BTN2 = GPIO_PinInGet(BTN2_PORT, BTN2_PIN);
          BTN3 = GPIO_PinInGet(BTN3_PORT, BTN3_PIN);
        
          if (BTN2 == BUTTON_PRESSED) {
            BTN2State = BTN2_PRESSED;
          } else {
            BTN2State = BTN2_RELEASED;
          }
        
          if (BTN3 == BUTTON_PRESSED) {
            BTN3State = BTN3_PRESSED;
          } else {
            BTN3State = BTN3_RELEASED;
          }
        }
        

         

        3.3.1 Radio and Packet Transmission

        The radio on the EFR32FG12 device was configured exactly the same as on the dongle. In fact, the exact same AppBuilder project was used as a basis for both devices. Instead of remaining in RX mode, however, the remote is powered down between ADC measurements and button state changes. If the state of the inputs has changed (i.e. a button has been pressed or released since last sleeping), the Report Handler constructs a new report packet and transmits it. When the packet has been transmitted, the device is permitted to transition back to sleep mode.

        To construct the report packet, the states of each button and the joystick are simply ORed together, since these states are mapped to the respective bit of their function in the HID report bitfield:

        void Report_Handler(void)
        {
          report_t report_current;
          static report_t report_previous = 0;
        
          while (1) {
            report_current = BTN3State | BTN2State | joyState;
            if (report_current != report_previous) {
              report_previous = report_current;
              TX_byte((uint8_t)report_current);
            } else {
              break;
            }
          }
        }
        

         

        3.4 Integration of Micrium OS

        As an additional challenge, we were required to integrate Micrium OS into our project. For this, we decided to integrate this only on our EFR32FG12 devices, since the EFM32HG USB device was limited in flash, and it would not benefit from the addition of an operating system due to the simplicity of the firmware running on the device.

        Adding Micrium OS to the Flex Gecko EFR32FG12

        One of the challenges we faced early in the project was that Micrium OS did not natively support the EFR32FG12 in the sense that the development of a Micrium OS board support package (BSP) was required.

        1. Micrium OS Board Support Package (BSP)

        1. Compiler-specific Startup (Micrium_OS/bsp/siliconlabs/efr32fg12/source/startup/iar/startup_efr32fg12p.s)

          We first created the standard Micrium OS BSP folder structure within the Micrium_OS/bsp/siliconlabs folder using the EFM32GG11 as our reference BSP due to its similarities in the startup code. We then started modifying the compiler-specific startup file for the EFR32FG12. This step was fairly straight forward given the fact that most ARM-Cortex-M devices share the same initialization code, with the obvious difference being the number of interrupt vectors sources amongst the various devices.

          The Micrium OS kernel port relies on two ARM-Cortex-M core interrupt sources, they are the PendSV and the SysTick. In our compiler-specific startup code, we had to include these two sources found in the Micrium OS kernel port with the use of the EXTERN assembly directive:
        1. EXTERN  OS_CPU_PendSVHandler

        EXTERN  OS_CPU_SysTickHandler

        Then we allocated memory for the two handlers with:

        DCD    OS_CPU_PendSVHandler

        DCD    OS_CPU_SysTickHandler

        We now have a Micrium OS compatible compiler-specific startup file.
         

        1. Device-specific Startup (Micrium_OS/bsp/siliconlabs/efr32fg12/source/startup/system_efr32fg12p.c)

          A device-specific startup file was required for the clock initialization. For this, we looked inside the Gecko SDK and found the corresponding startup for the EFR32FG12P (system_efr32fg12p.c). This file was added as-is into the Micrium OS BSP.
           
        2. Micrium OS Tick BSP (Micrium_OS/bsp/siliconlabs/efr32fg12/source/bsp_os.c)

          The Micrium OS Tick BSP file essentially handles the kernel tick initialization in either periodic mode or in dynamic mode depending on the power consumption requirements of the project. We left this file the same as the one found in the EFM32GG11 and ran in periodic mode. As one of the potential improvements later on, we could switch to dynamic tick in order to improve the power consumption of our device.
           
        3. Micrium OS CPU BSP (Micrium_OS/bsp/siliconlabs/efr32fg12/source/bsp_cpu.c)

          The Micrium OS CPU BSP file deals with the setup of timestamp timers that are required by the OS for statistical purposes and other features. This was once again left the same as in the EFM32GG11.
           
        4. Micrium OS Interrupt Sources definitions (Micrium_OS/bsp/siliconlabs/efr32fg12/include/bsp_int.h)

          In this file, the various interrupt sources definitions are specified. Although not necessary for our project, this file is included in bsp_os.c to assign BSP_INT_ID_RTCC as a kernel aware interrupt source when dynamic tick is enabled.
           
        5. Micrium OS generic BSP API (Micrium_OS/bsp/include/bsp.h)

          This is the final piece of the Micrium OS BSP puzzle. In this file, the prototypes for BSP_SystemInit(), BSP_TickInit(), and BSP_PeriphInit() are defined. Some of these functions will later be used in our program main().

         

        2. Micrium OS main.c

         

        1. main()

          In the standard Micrium OS main(), the CPU is initialized with CPU_Init(), followed then by the board initialization via BSP_initDevice() and BSP_initBoard(), both from the Gecko SDK. After the CPU and the board clocks are initialized, the OS follows with OSInit() which initializes the kernel. Once the OS is initialized, our startup task is then created by calling OSTaskCreate() (see section 2b.). Finally, after the startup task has started its execution, the kernel starts by calling OSStart().
           
        2. StartupTask

          In the Startup Task, the kernel tick is initialized using BSP_TickInit() from the Micrium OS BSP. Other services such as the UART are also initialized here. In our case, USART2 is used. It is important to mention that the Startup Task has a 500-millisecond delay inside an infinite loop in order for it to yield CPU time to other tasks when running in a multithreaded environment.

          Since our project utilizes proprietary wireless, the RAIL library is included and therefore initialized in the Startup Task at 2.4GHz.

          In order to demonstrate different kernel services, a RAIL receive (Rx) semaphore object is created in this task.
           
        3. RAIL Rx Task

          Our model consists of two tasks: Startup Task and the RAIL Rx Task.

          In the RAIL Rx Task, the program pends on the RAIL Rx semaphore created in the Startup Task. Once data from the wireless remote is received by our device, an interrupt fires and a callback function dissects the packet and posts the first byte of data to the RAIL Rx semaphore. The RAIL Rx task then transmits the data received via USART2 to the Happy Gecko. The callback function briefly puts the radio in an idle state before waking the receiver once again to obtain the next radio packet.

         

        5. Next Steps

        With the project complete and functional using STKs and pre-made expansion boards, we want to pursue creating custom PCBs for both the remote and dongle. This would require a fair amount of work, laying out two MCUs plus a USB connector on the dongle board, and another MCU in a reasonable hand-held remote form factor for the wireless remote. Additional challenges may arise in laying out the wireless specific portions of the board, especially in regards to antenna design and placement. We hope to accomplish this early this year, and have remotes and dongles constructed for each team member to use. Overall, this has been an interesting and challenging project, and it would be great to see it to completion with a physical, practical media remote designed and built.

        6. Attached Projects

        All firmware projects can be found here: https://www.dropbox.com/s/tt55ky7m7h5hmeq/PC_Media_Remote.zip?dl=0
        This includes firmware to run on the dongle's EFM32HG USB MCU and EFR32FG12 Wireless MCU, and the remote's EFR32FG12 Wireless MCU. These are:

        1. Dongle_EFM32HG - firmware for the dongle's EFM32HG to perform UART to USB HID Media Control

        2. Dongle_EFR32FG12_Micrium - firmware for the dongle's EFR32FG12 wireless receiver, with Micrium OS integration

        3. Dongle_EFR32FG12_simple - firmware for the dongle's EFR32FG12 wireless receiver, before Micrium OS integration (simple while loop)

        4. Remote_EFR32FG12 - firmware for the remote's EFR32FG12 wireless receiver for user input