This content is not yet available over encrypted connections.

Friday, September 23, 2016

nRF52832: first steps with ST-Link V2 and openocd

The motivation

Let's try one of the best low power bluetooth and nfc SoCs on the market.

The ordering
First we need a development board and a programmer.

So we search some sources for nRF52832 development boards:
(all pricerates today 2016.09.23)

digikey: ~39$ (not including tax and shipping, programmer included)
mouser: ~39$ (not including tax and shipping, programmer included)
aliexpress: ~20$ (including shipping, for me no tax and custom dues, no sensors, no programmer)

Now we search for a programmer:

digikey: ~90$ (not including tax and shipping)
mouser: ~90$ (not including tax and shipping)
aliexpress: ~2$ (including shipping)

Sorry my development budget is small. So give aliexpress a try. 3 weeks later (cheap shipping included) we have a development suite ready.

aliexpress nRF52832 board

nRF52832-QFAA SoC ARM Cortex M4

ST-Link V2 Programmer (genuine? work!)

The Hardware

The seller give no instruction for the board so we have to use some inspection and a continuity tester to follow the traces with help from nordics nRF52832-QFAA reference layout. So we find the Pins for SWDIO and SWCLK -> SWCLK goes to TCK and SWDIO goes to TMS and we use 3.3V and GND.

ST-Link V2 and nRF52832 wired up

The Software

- ST-Link V2 

I use ubuntu 16.04 so the ST-Link V2 don't PnP out of the box, we need some more packages:

    sudo apt-get install git
    sudo apt-get install autoconf
    sudo apt-get install libusb-1.0-0-dev

Then we build the drivers for the ST-Link V2 from source:

   git clone stlink.git
   cd stlink.git/

Then we copy the driver and udev rules:

    sudo cp st-* /usr/bin
    find . -name "*.rules"
    sudo cp ./etc/udev/rules.d/49-stlinkv2.rules /etc/udev/rules.d

And activate the udev rules:

    sudo udevadm control --reload-rules
    sudo udevadm trigger

Let's check:


        Bus 001 Device 021: ID 0483:3748 STMicroelectronics ST-LINK/V2


[0] usb 1-7: new full-speed USB device number 21 using xhci_hcd
[0] usb 1-7: New USB device found, idVendor=0483, idProduct=3748
[0] usb 1-7: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[0] usb 1-7: Product: STM32 STLink
[0] usb 1-7: Manufacturer: STMicroelectronics
[0] usb 1-7: SerialNumber: 6

- openocd

Now we need openocd to use the programmer to flash our nRF52832 firmware:

    git clone git:// openocd-code

And we need some patches for the nRF52832 (more info on and

git pull refs/changes/15/3215/2

Then i added to openocd-code/src/flash/nor/nrf52.c in line 133 to fit my nRF52832 hardware:

        .hwid        = 0x00C7,
        .variant    = "QFN48",
        .build_code    = "B00",
        .flash_size_kb    = 512,

Let's build and install openocd:

    cd openocd-code/
    sudo make install

An openocd config-file (i.e. openocd_nrf52.cfg) can look like this:

 #nRF52832 Target
source [find interface/stlink-v2.cfg]

transport select hla_swd

source [find target/nrf52.cfg]

And test our board:

     openocd -d2 -f openocd_nrf52.cfg

Open On-Chip Debugger 0.10.0-dev-00322-g406f4d1-dirty (2016-09-23-11:47)
Licensed under GNU GPL v2
For bug reports, read
debug_level: 2
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 10000 kHz
Info : Unable to match requested speed 10000 kHz, using 4000 kHz
Info : Unable to match requested speed 10000 kHz, using 4000 kHz
Info : clock speed 4000 kHz
Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.273018
Info : nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints

Connect with telnet and cleanup our chip (get rid of all test stuff):

     telnet localhost 4444

Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> reset halt
nrf52.cpu: target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000b58 msp: 0x20010000
> nrf52 mass_erase
> reset
> exit
Connection closed by foreign host.

- GNU ARM Compiler

Next step get the GNU ARM Compiler to build our firmware:

Download ready packages from
I use this linux version gcc-arm-none-eabi-5_3-2016q1-20160330-linux.tar.bz2

Unpack with

     tar xvjf gcc-arm-none-eabi-5_3-2016q1-20160330-linux.tar.bz2

- Nordic SDK 12.0.0

 Download the package from

    actual release
    and unpack:


The Firmware

Let's start with blinky (all sourcecode available in :

On our nRF52832 development board there are  two useable LEDs. After some tracing we discover they are on GPIO pin 30 and GPIO pin 31.

So our C - program can look like this:

#include <stdlib.h>
#include "nrf_delay.h"
#include "nrf_gpio.h"

const uint32_t led_pin1 = 31;

 * @brief Function for application main entry.
int main(void) {

    // setup
    // Configure LED-pin as outputs and clear.

    // loop
    // Toggle LED.
    while (true) {
        nrf_delay_ms(1000);   // 0.5 Hz

Now we need one Makefile:


# compilation flags for gdb

CFLAGS  += -O0 -g
CFLAGS += -DNRF52832

LDSCRIPT = $(TEMPLATEROOT)/blank_nrf52832_QFAA.ld

# object files

OBJS =  system_nrf52.o main.o

# include common make file

include $(TEMPLATEROOT)/Makefile.common

For Makefile.common see

And our linker-file (blank_nrf52832_QFAA.ld):

GROUP(-lgcc -lc -lnosys)

  FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000
  RAM (rwx) :  ORIGIN = 0x20000000, LENGTH = 0x10000

  .fs_data :
    PROVIDE(__start_fs_data = .);
    PROVIDE(__stop_fs_data = .);
  } > RAM

INCLUDE "nrf5x_common.ld"

Build the firmware blinky.hex:


'/home/pcbreflux/nordic/gcc-arm-none-eabi-5_3-2016q1/bin/arm-none-eabi-gcc' -Xlinker -Map=_build/ -mthumb -mabi=aapcs -L/home/pcbreflux/nordic/nRF5_SDK_12.0.0/components/toolchain/gcc -T../blank_nrf52832_QFAA.ld -mcpu=cortex-m4 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -o _build/blinky.out _build/system_nrf52.o _build/main.o _build/gcc_startup_nrf52.o
'/home/pcbreflux/nordic/gcc-arm-none-eabi-5_3-2016q1/bin/arm-none-eabi-objcopy' -O binary _build/blinky.out                   _build/blinky.bin                  
'/home/pcbreflux/nordic/gcc-arm-none-eabi-5_3-2016q1/bin/arm-none-eabi-objcopy' -O ihex _build/blinky.out                   _build/blinky.hex

and flash blinky.hex to our nRF52832 development board:

       make flash


** Programming Started **
auto erase enabled
Info : nRF51822-QFN48(build code: B00) 512kB Flash
Warn : using fast async flash loader. This is currently supported
Warn : only with ST-Link and CMSIS-DAP. If you have issues, add
Warn : "set WORKAREASIZE 0" before sourcing nrf52.cfg to disable it
nrf52.cpu: target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000001e msp: 0x20010000
wrote 4096 bytes from file _build/blinky.hex in 0.207181s (19.307 KiB/s)
** Programming Finished **
** Verify Started **
nrf52.cpu: target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000002e msp: 0x20010000
verified 3120 bytes in 0.041079s (74.171 KiB/s)
** Verified OK **

The nRF51822-QFN48 is just a mislead in our openocd patch (see nrf52.c at line 404).


Practical demonstration can be found on youtube

1 comment:

  1. This comment has been removed by the author.