Starting up with the Nordic NRF52 BLE chip

The nRF52 based chips are the latest version of the popular Bluetooth chip from Nordic that has an ARM Cortex based processor and Bluetooth communications support.
Major differences from the previous nRF51 version includes:

  1. Based on ARM Cortex M4F instead of ARM M0.
  2. Support for the latest Bluetooth 5 specification
  3. On chip NFC support for device bounding and probably something else

The following post centralizes the information that I gathered to start using the demo board that I bought based on the nRF52832 chip.

The eBay,Aliexpress nRF52832 based board:
I’ve bought my nRF52832 based board from AliExpress for around 13€. An higher price than the ESP32 which has both WifI and also blueetooth, but since I really needed to start using the nRF5X base chips I’ve bought what is called “NRF52832 Mini Development Board Gold Core board Wireless Bluetooth Transceiver Module”…

This board build is based on a two boards joined together: one daughter board holding the nRf52832 chip, and another, larger board, exposing the pins, JTAG/SWD connector, power regulator, two leds and two switches. As a bonus the main board was designed for something else and so all the pins silk screen are just plain wrong, but at least the power pins and the SWD pins are correctly identified.

For mapping out correctly the nRF pins to the out pins we need to see the board schematics vs the daughter board pins.

This board schematics are here at this link: NRF52832 Module Test Board V1.0.

And the daughter board pinout is here:

Checking the schematics vs the daughter board pin out we can see that on the pdf schematics file our nRF chip is located where would/should be a CC2640_RGZ module (!…). For example on that module the DIO0 pin corresponds to P25 pin, the DIO1 pin to P26, and so on. We also can check that by, probably sheer luck, the power pins and SWD pins TCLK-SWCLK and TDIO-SWDIO are just right… and so they just reused the main board to hold the nRF52.

Checking out the board and the schematic we can see also that we have a switch on nRF52 pin P04 and two red leds at P30 and P31. The leds can be disconnected by removing the soldering on the nearby solder bridges. The other pins seem free.

As a final note, at least the board that I’ve received, comes with the BLE peripheral Nordic UART example loaded as the running firmware.

More info:Taida Century Gold Core NRF52 board

Programming the board
The board can be programmed at least by two ways:

  1. Openocd On chip debugger – But a set of patchs are needed to support the nRF52
  2. Black Magic Probe – Running on a cheap stm32F103C8T6 board – Blue pill

Both ways allow to successfully program the board and debug the running code.

To avoid making this a very long post I’ve split it into further posts how to build the tools necessary to program the nRF52 chip.

  1. Setting up Openocd for programming the Nordic nRF52832 chip
  2. Building a Black Magic Probe using the “blue pill” STM32F103C8T6 based board

Setting up Openocd for programming the Nordic nRF52832 chip

The following post organizes a set of information gathered from around the web to allow the use openocd utility to also program/access the nRF52 based chips.

Openocd must be patched to be used against the nRF52832 chip. Most of the required information is on this pcbreflux post.

Retriving the sources and patchs
At least, at the current date, on Arch Linux, Openocd version is 0.10. We will keep this version and install side by side the patched version of Openocd that supports the NRF52 chip.

First let’s retrieve the code and patchs:

[pcortex@pcortex:opt]$ git clone git:// openocd-code
Cloning into 'openocd-code'...
remote: Counting objects: 55979, done.
remote: Compressing objects: 100% (20335/20335), done.
remote: Total 55979 (delta 46033), reused 43114 (delta 35495)
Receiving objects: 100% (55979/55979), 12.54 MiB | 2.88 MiB/s, done.
Resolving deltas: 100% (46033/46033), done.
[pcortex@pcortex:opt]$ cd openocd-code
[pcortex@pcortex:openocd-code|master]$ git pull refs/changes/15/3215/2
remote: Counting objects: 1482, done
remote: Finding sources: 100% (11/11)
remote: Total 11 (delta 0), reused 2 (delta 0)
Unpacking objects: 100% (11/11), done.
 * branch              refs/changes/15/3215/2 -> FETCH_HEAD
Auto-merging src/flash/nor/drivers.c
CONFLICT (content): Merge conflict in src/flash/nor/drivers.c
Auto-merging src/flash/nor/
CONFLICT (content): Merge conflict in src/flash/nor/
Automatic merge failed; fix conflicts and then commit the result.
[pcortex@pcortex:openocd-code|master *+|MERGING]$ 

After this we have two conflicting files that have changes that we must deal manually.

The src/flash/nor/drivers.c merge conflict is easy to solve. The conflict error is due to clash between empty sections and some added code lines. The end result file is here.

The takes more work to merge, but it is available -> here <- with the merges done.

Then, for specifically support the nRF52832 chip which has 512Kb of flash we need to change the openocd-code/src/flash/nor/nrf52.c currently on line 133, by adding the chip information:

static const struct nrf52_device_spec nrf52_known_devices_table[] = {
		.hwid   = 0x0053,
		.variant  = "QFAA",
		.build_code = "AA",
		.flash_size_kb  = 512,
                .hwid        = 0x00C7,
                .variant    = "QFN48",
                .build_code    = "B00",
                .flash_size_kb    = 512,


We just need now to compile:

    cd /opt/openocd-code/

In my case I just didn’t executed the last sudo make install since I want to have two versions of Openocd side by side.

We should have now at /opt/openocd-code/src the openocd binary with the patchs:

[pcortex@pcortex:src|master *+|MERGING]$ ./openocd -v
Open On-Chip Debugger 0.10.0+dev-00146-g1025be36-dirty (2017-06-04-10:06)
Licensed under GNU GPL v2
For bug reports, read

Connecting to the nRF52832 using ST-Link

We can now use this version to connect to the nRF52 chip.
A sample openocd config file can be as follows:


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

transport select hla_swd

source [find target/nrf52.cfg]

But since I did not run the sudo make install command the tcl files from the Arch Linux package are different from the patched version, so it is important that the patched version also uses the patched/new files:

./openocd -s /opt/openocd-code/tcl -f nRF52832.cfg

The expected output:

Open On-Chip Debugger 0.10.0+dev-00146-g1025be36-dirty (2017-06-04-10:06)
Licensed under GNU GPL v2
For bug reports, read
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 v21 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.261252
Info : nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints

We should be able now to run the nrf52 command:

telnet localhost 4444
Trying ::1...
Connection failed: Connection refused
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> nrf52
  nrf52 mass_erase
  nrf52.cpu arm
    nrf52.cpu arm core_state ['arm'|'thumb']

And programming:

> program /opt/nRF5_SDK_12.3.0_d7731ad/examples/ble_peripheral/ble_app_uart/hex/ble_app_uart_pca10028_s130.hex verify
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x000006d0 msp: 0x000007c0
** Programming Started **
auto erase enabled
nRF51822-QFN48(build code: B00) 512kB Flash
Padding image section 0 with 2112 bytes
Padding image section 1 with 32 bytes
using fast async flash loader. This is currently supported
only with ST-Link and CMSIS-DAP. If you have issues, add
"set WORKAREASIZE 0" before sourcing nrf52.cfg to disable it
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000001e msp: 0x000007c0
wrote 126976 bytes from file /opt/nRF5_SDK_12.3.0_d7731ad/examples/ble_peripheral/ble_app_uart/hex/ble_app_uart_pca10028_s130.hex in 3.972911s (31.211 KiB/s)
** Programming Finished **
** Verify Started **
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000002e msp: 0x000007c0
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000002e msp: 0x000007c0
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000002e msp: 0x000007c0
verified 121752 bytes in 1.346008s (88.334 KiB/s)
** Verified OK **
> reset run

Remember, if programming fails, with the program command, check if the correct path is provided for openocd through the -s switch.