Getting Started with the Thingy:52 and GCC/GDB

The Thingy:52 IoT Sensor Kit is a fancy development board that combines the nRF52832 SoC, a handful of sensors and user interface components, and a rechargeable battery. Although the Thingy is available for sale in the usual places, Nordic has also given away quite a few of them at various technical seminars and trade shows. As a result, I've collected a few Thingies in my scratch-and-dent drawer and have spent a bit of time repurposing them for personal projects. Of course there's a lot that you can do with them via BLE without writing any firmware but they are also delightfully hackable. The purpose of this post is to collect some Thingy resources into one place to make it easier for you to get started using GCC/GDB to hack the Thingy.

Thingy Hardware

There is a nice overview of the Thingy here on Nordic's Infocenter. If you dig into this you can find schematics and hardware information. Underneath the rubber shell of the Thingy there are several headers that allow access to some interesting pins: a TWI bus that is shared with the Thingy's low-power accelerometer, three GPIOs that can be used as analog or digital pins, four digital-only GPIOs (on a port expander), and four N-MOS transistors. Note that the VDD power rail is turned off and on by the Thingy's firmware so anything that is powered by it will experience a delay between the Thingy powering up and VDD being turned on.

A micro USB port is located on the side of the Thingy and is used for charging the battery. Adjacent to the USB port there is a power switch and a programming header. Note that the power switch disconnects the battery so the Thingy must be turned on before it will charge via USB. A debug probe is required for programming and debugging the Thingy. Most Nordic development kits have a Segger J-Link debug probe built into them so grabbing one of these is the easiest way to get started if you don't already have a standalone J-Link. For example, the nRF52 DK has a Debug output connector that accepts a 10-pin programming cable.

A good way to test that your debug connection is working is to make a backup of the stock Thingy firmware in case you need to restore it later. This can be done easily using nrfjprog:

nrfjprog --readcode --readuicr thingy_backup.hex

Building the Firmware

The reference firmware for the Thingy is hosted on github. Note that there are two branches: the master branch is BLE-only and based on SDK13 while the ANT branch is BLE and ANT and based on SDK12.1. Start by following the instructions for setting up the prerequisites that are detailed on the github page. The setup scripts fetch some other github code and do some patching. Note that you must create a developer account on the InvenSense website before it will allow you to download the proprietary motion driver (Embedded MotionDriver 6.12). Instructions for building the firmware using Keil or GCC are located here and are pretty straightforward.

The Makefiles in the github projects are a bit basic so I created versions that include features such as debug builds, release builds, and the ability to launch GDB. Note that there are two branches: master and ANT. Also note that I had to modify the linker scripts to allow for building a debug version of the bootloader so it's important to copy all of the files for the project -- not just the Makefile. Available targets can be listed like this:

make help
Makefile:324: Define JLINK_MON_DEBUG_DIR to enable Monitor Mode Debugging.
The following targets are available:
    (default)              - Compile with debug flags
    release                - Compile with release flags
    all                    - Compile debug and release targets
    clean                  - Remove object and dependency directories
    gdb [SN=1234]          - Perform debug compile and then launch gdb
    gdb_rtt [SN=1234]      - Call gdb target and then open RTT Client
    flash_sd [SN=1234]     - Flash the SoftDevice
    flash_debug [SN=1234]  - Flash the debug build
    flash_release [SN=1234]- Flash the release build

First Steps

The first change that I'd recommend making is to enable logging by setting NRF_LOG_ENABLED to 1 in "../config/sdk_config.h". You should then able to launch a Segger RTT console:

make gdb_rtt

to see log messages. Asserting control over the Thingy's LEDs makes a tempting second change. The hard work is done by the Thingy's GPIO expander so setting a constant RGB color mix is pretty easy. First, add a function declaration to "Nordic-Thingy52-FW/include/modules/m_ui.h":

/**@brief Function for setting the constant RGB value of an LED.
 * @param[in]   r   Red intensity (0 to 255).
 * @param[in]   g   Green intensity (0 to 255).
 * @param[in]   b   Blue intensity (0 to 255).
 * @retval NRF_SUCCESS      Operation was successful.
 * @retval Other codes from the underlying drivers.
uint32_t m_ui_led_constant_set(uint8_t r, uint8_t g, uint8_t b);

Then add the function definition to "Nordic-Thingy52-FW/source/modules/m_ui.c":

uint32_t m_ui_led_constant_set(uint8_t r, uint8_t g, uint8_t b)
    drv_ext_light_rgb_intensity_t color;

    if((0 == r) && (0 == g) && (0 == b))
        return drv_ext_light_off(DRV_EXT_RGB_LED_LIGHTWELL);

    color.r = r;
    color.g = g;
    color.b = b;
    NRF_LOG_INFO("Mode: Color: %x, %x, %x, \r\n", r, g, b);

    return drv_ext_light_rgb_intensity_set(DRV_EXT_RGB_LED_LIGHTWELL, &color);

Finally, set the LED to a pleasant orange color at the bottom of the main function in "Nordic-Thingy52-FW/project/pca20020_s132/main.c":

err_code = m_ui_led_constant_set(2, 1, 0);

The debug version of the firmware should compile correctly using:


Remember that the Thingy ships with a secure bootloader and this bootloader is not going to think that your modified firmware is valid. For now, we can remove the bootloader because it is of no use for us unless we know the Thingy's private firmware signing key (we don't). Removing the bootloader also requires removing the bootloader's address from the chip's UICR so a full chip erase must be used:
nrfjprog --recover

Then we can replace the SoftDevice and flash the new firmware:
make flash_sd && make flash_debug

And now the Thingy LED should be glowing orange. Happy hacking!

Extra Credit

The most fun that I've had hacking the Thingy so far was using the ANT branch of the firmware to talk to a Garmin CIQ app. It's not too hard to get started and could be worth the effort if you have a Garmin CIQ device that you want to learn to program.