• Onboarding with the SAMR21 MCU on OSX & Ubuntu

    Wednesday, October 15, 2014

    10/15/2014 – Jia Huang

    I started playing with an Atmel SAMR21 dev kit this weekend.

    Atmel recently released the SAMR21 series. It combines everything good about the SAMD21 series (USB controller, low power cortex M0+ architecture) and the AT86RF233 (802.15.4 wireless radio). 802.15.4 is the standard for low power IoT devices using Zigbee and 6loWPAN (IPV6 for IoT, primarily used for mesh networks).

    So instead of having to use two chips (one for the logic and one for the wireless communications), both silicon wafers are put on one package:

    Besides the main SAMR21 chip, the dev board has on it:

    • Another chip that acts as the embedded debug chip. This allows us to load code and use gdb to debug hardware without having to buy an expensive JTAG debugger. Instead we can just plug the board into a USB port and start hacking.
    • Two antennas. One is a chip antenna, and the other is an external antenna. During development we can switch between the two for different applications.
    • The usual assortment of LEDs & buttons that comes with every dev board.

    If you just want to get the code running, here’s the final github repo with build & deploy instructions on OSX & Ubuntu: https://github.com/jiahuang/samr21-xplained-pro.

    Getting the example code

    As usual, the default example code that the chip manufacturer gives is a bit convoluted. As of Oct 2014, the only example on the SAMR21 Xplained Pro page is this project for doing FCC tests, though Atmel has a few more examples from the actual ATSAMR21G18A page.

    The FCC test example goes through some radio emissions so that the Federal Communications Commission (FCC) can certify that the radio isn’t emitting in frequencies it’s not supposed to. The FCC test example that Atmel gives isn’t a good choice for a starting program since I can’t easily tell if it’s working or not.

    But I went ahead and used the FCC test program anyway because I thought that it might have some pin-specific configs for the Xplained board. Those pin configs would help me identify and get started with the LEDs & buttons, at the very least.

    Making it do something I can see

    My first goal was to get something working on the board. That way I could verify that I had a working programming & debugging environment for more complicated examples. Often I find that simple things like Makefiles aren’t configured properly in example code.

    Blinky lights are the “Hello world” of hardware, so I modified the example FCC tester code to blink the LED on and off instead.

    In order to blink the LED, I had to find the program’s entry point. I had hoped for a main.c file, but the folder structure for Atmel’s test program is:

           Peer2Peer/ # main application
             astudio/ # AVR studio files
             linker/ #linker files used during compilation
             make/ #makefiles for the different boards
         doc/ #pdf files for explaining Atmel’s Light Weight Mesh protocol
         hal/ #the Hardware Abstraction layer. Useful because this application is for multiple boards
         phy/ #the physical layer. This is code specific to the radio.
         service/ # unused
         sys/ #system files, stuff like timers, clock config, and timers.
         tools/ # Also unused. 

    I ended up grepping for a main(void) function, found that it’s in the counterintuitively named fcc_test_dut.c file, and put in some blinky code:

    void delay_s(uint32_t time) {
        for (int i = 0; i  100*time; i++) {
            // this delay is in us 
     int main(void)
      while (1)

    Building the program

    Atmel has nicely included all the makefiles for their various boards so that I can build using GCC.

    >> ls LwMesh_1_2_1/apps/Peer2Peer/make

    The makefile requires the gcc-arm compiler.

    This is the same compiler we use for Tessel, and during Tessel’s development we made a brew tap to install it on our machines. We can use the same brew tap to install the tools needed for compiling the SAMR21 code.

    brew tap tessel/tools
    brew install gcc-arm

    On Ubuntu, get gcc-arm from Terry Guo’s PPA:

    sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded;
    sudo apt-get update;
    sudo apt-get install gcc-arm-none-eabi;

    With these tools, I could now build the makefile: make -f Makefile_XplainedPro_ATSAMR21

    Remember the counterintuitively named fcc_test_dut.c file? Turns out at one point the program files were properly named the application name (as Peer2Peer.c) before being changed to fcc_test_dut.c because the makefile still looks for it:.

    > make -f Makefile_XplainedPro_ATSAMR21
    arm-none-eabi-gcc: error: ../Peer2Peer.c: No such file or directory
    arm-none-eabi-gcc: fatal error: no input files

    The makefile also uses a gmkdir command that should just be a mkdir.

    I ended up modifying the makefile to fix these and the build succeded.

    > make -f Makefile_XplainedPro_ATSAMR21
       text    data     bss     dec     hex filename
       4776       0    1888    6664    1a08 Debug/Peer2Peer.elf
       4776       0    1888    6664    1a08 (TOTALS)

    Configuring OpenOCD

    OpenOCD is an open source chip debugger. It allows me to do “on-chip” debugging, stuff like looking at registers, setting breakpoints, loading code, etc.

    As of the current release (v0.8.0) OpenOCD does not have configurations for the SAMR21 chip, but it’s already in their master branch. In order to get it, rebuild from master. When it releases, v0.9.0 should have these configs by default.

    On OSX:

    brew install openocd --HEAD

    On Ubuntu:

    git clone https://github.com/ntfreak/openocd.git;
    cd openocd;
    sudo make install;

    Now running openocd --version should show something like:

    > openocd --version
    Open On-Chip Debugger 0.9.0-dev-snapshot (2014-10-05-17:42)

    OpenOCD uses .cfg files to set up configs for the type of board that it’s programming/debugging. The config file specifies things like how the chip is programmed, the interface used to do the programming, and the specifications of the MCU.

    In the make folder I added a tools/samR21.cfg file to tell OpenOCD what to do:

    source [find interface/cmsis-dap.cfg]
    # chip name
    set CHIPNAME at91samr21g18
    source [find target/at91samdXX.cfg]
    $CHIPNAME.cpu configure -event gdb-attach {
       echo "halting"

    This tells OpenOCD to use cmsis-dap as its programming interface, and that the chip being programmed is a samr21. Once gdb attaches, I halt the microcontroller to prevent any code from being run. Having a halt as a first step is useful for debugging later if I want to set up breakpoints at the start.

    Loading up the program

    By then I had:

    • the built binary (Peer2Peer.elf)
    • the OpenOCD config file (samR21.cfg)

    Now I could run GDB on the dev kit with OpenOCD:

    arm-none-eabi-gdb Debug/Peer2Peer.elf -ex 'target remote | openocd -c "gdb_port pipe;" -f tools/samR21.cfg'

    Once GDB attached, I ran the load command to load up the elf into flash.

    The load command loads up the .elf file I specified earlier in the arm-none-eabi-gdb command.

    After this is loaded, the board is put in a halted state again so I could attach breakpoints if I wanted. In order to run the code, I had to issue the “continue” command (c for short).

    And it blinks!

    The modified example code is up on github.

    Next up, putting two of these things together and getting them talking over 6loWPAN!

    #jia huang #tessel #samr21 #zigbee #iot #6lowpan #microcontroller

August 2018

January 2018

July 2017

February 2017

November 2016

October 2016

September 2016

August 2016

July 2016

June 2016

April 2016

March 2016

February 2016

November 2015

September 2015

August 2015

July 2015

June 2015

May 2015

March 2015

February 2015

January 2015

December 2014

November 2014

October 2014

September 2014

August 2014

July 2014

June 2014

May 2014

April 2014

March 2014

February 2014

January 2014

December 2013

November 2013

October 2013

September 2013

August 2013

July 2013