Skip to content

Board: yunjia nrf51822

Hauke Petersen edited this page Aug 5, 2014 · 27 revisions

NOTE: the code for this board is not merged into master yet!

Overview

The NRF51822 module by Yunjia Technology is a minimalistic but very low-priced module utilizing Nordics NRF51822QFAA SoC. The SoC features 16Kb of RAM, 256Kb of flash ROM and comes on top of the usual micro-controller peripherals with a 2.4GHz radio that supports both Nordics proprietary ShockBurst as well as Bluetooth Low Energy (BLE).

The board is available for example on ebay or at aliexpress for something around 8-10 USD.

Hardware

yunjia-nrf51822

MCU NRF51822QFAA
Family ARM Cortex-M0
Vendor Nordic Semiconductor
RAM 16Kb
Flash 256Kb
Frequency 16MHz
FPU no
Timers 3 (2x 16-bit, 1x 32-bit [TIMER0])
ADCs 1x 10-bit (8 channels)
UARTs 1
SPIs 2
I2Cs 2
Vcc 1.8V - 3.6V
Datasheet Datasheet
Reference Manual Reference Manual

Flashing and Debugging

The Yunjia NRF51822 module comes without any on-board programming and flashing capabilities. It supports however to be programmed using of-the-shelf programmers as Segger's JLink or STM's STLink.

A very simple and affordable way to program and debug the Yunjia module is to the integrated ST-Link/V2 programmer of any STM32Fx-discovery board. The needed steps are described in the following sections. If you want to use a stand-alone ST-Link adapter, you just simply have to alter the wiring to fit for your programmer, the software part is identical.

Hardware

First of all make sure the your ST-Link device is detected and can be accessed properly. In Linux you might have to adept your udev rules accordingly, have a look at the 'Setting up udev rules' section in this README file if you need help.

Second you need to enable the stand-alone ST-Link mode of the discovery board by removing the two CN2 jumpers, found somewhere in the upper right part of the board. This disconnects the ST-Link programmer from the micro-controller part of the port and enables direct access through the pin-header CN3, also labled SWD.

The Yunjia NRF51822 module supports the Serial Wire Debug (SWD) interface. To access the device the following four lines need to be connected with the STM32x-discovery board:

                 Yunjia module    STM32Fx-discovery
common ground:       GND <-----------> GND
supply voltage:      VDD <-----------> 3V
SWD clock:           SWD <-----------> SWCLK (CN3, pin2)
SWD data I/O:      SWDIO <-----------> SWDIO (CN3, pin4)

The following image shows the wiring for an STM32F0-discovery board (although not the most beautiful...):

Connecting the Yunjia module to an STM32F0-discovery board

Software

Debugging and programming the Yunjia module works well with OpenOCD. Using OpenOCD has however some pitfalls, so some preparation is needed:

  1. You have to use a fairly recent version of OpenOCD (the upstream version 0.9.0-dev works fine)
  2. You have to patch one of OpenOCDs script files due to a bug in OpenOCD: For this you have to comment out lines 21-24 from /usr/local/share/openocd/scripts/target/swj-dp.tcl or wherever you OpenOCD installation resides. The patched file should look like this:
$ cat /usr/local/share/openocd/scripts/target/swj-dp.tcl
# ARM Debug Interface V5 (ADI_V5) utility
# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since
# SW-DP and JTAG-DP targets don't need to switch based
# on which transport is active.
#
# declare a JTAG or SWD Debug Access Point (DAP)
# based on the transport in use with this session.
# You can't access JTAG ops when SWD is active, etc.

# params are currently what "jtag newtap" uses
# because OpenOCD internals are still strongly biased
# to JTAG ....  but for SWD, "irlen" etc are ignored,
# and the internals work differently

# for now, ignore non-JTAG and non-SWD transports
# (e.g. initial flash programming via SPI or UART)

# split out "chip" and "tag" so we can someday handle
# them more uniformly irlen too...)

#if [catch {transport select}] {
# echo "Info : session transport was not selected, defaulting to JTAG"
# transport select jtag
#}

proc swj_newdap {chip tag args} {
 if {[using_jtag]} { eval jtag newtap $chip $tag $args }
 if {[using_swd]} { eval swd newdap $chip $tag $args }
 if {[string equal [transport select] "cmsis-dap"]} { eval cmsis-dap newdap $chip $tag $args }
}

This should be it, now you are all set to go!

Programming the Device

To program the Yunjia NRF51822 module, just go to your RIOT application and type:

make flash

and voila, the new firmware should be flashed onto your device.

Reset the Device

As the Yunjia module does not provide a reset button, RIOT includes a target to reset the board. To do that, just type

make reset

and your board will reboot.

Debugging the Device

The debugging setup comprises of two parts: a GDB server and a GDB client. To usual workflow is to start the GDB server first and then connect to it with some kind of front-end (e.g. command line, IDE, ...).

To start the GDB server, just type

make debug-server

This will start a local GDB server on port 3333.

If you are fine with working with the GDB command line client, you can start debugging your device by just typing

make debug

in a second terminal window. This will automatically connect to your previously opened GDB server and will also load your corresponding .elf file.

Program the device manually

For OpenOCD to work correctly, you need the following configuration file (which you can also find in RIOTDIR/boards/yunjia-nrf51822/dist/openocd.cfg:

 $ cat RIOTDIR/boards/yunjia-nrf51822/openocd.cfg
# nRF51822 Target
source [find interface/stlink-v2.cfg]
 
set WORKAREASIZE 0x4000
source [find target/nrf51_stlink.tcl]

# use hardware reset, connect under reset
#reset_config srst_only srst_nogate

You can now program your device by doing the following:

  1. start openocd with: openocd -d3 -f RIOTDIR/boards/yunjia-nrf51822/dist/openocd.cfg
  2. open a new terminal an connect with telnet: telnet 127.0.0.1 4444
  3. do the following steps to flash (only use bank #0 starting from address 0):
> flash banks
#0 : nrf51.flash (nrf51) at 0x00000000, size 0x00040000, buswidth 1, chipwidth 1
#1 : nrf51.uicr (nrf51) at 0x10001000, size 0x000000fc, buswidth 1, chipwidth 1

> halt
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x61000000 pc: 0x00000e1a msp: 0x20001b2c

> flash write_image erase PATH-TO-YOUR-BINARY/YOUR-BINARY.bin 0
wrote xxx bytes from file PATH-TO-YOUR-BINARY/YOUR-BINARY.bin in xx.yys (x.yyy KiB/s)

> reset

Debugging manually

First you have to start OpenOCD as described in the section above.

Then enter the following in a new terminal:

$ arm-none-eabi-gdb -tui "<your binary ELF>"

(gdb) target remote localhost:3333
Remote debugging using localhost:3333
0x000119ce in ?? ()

(gdb) load
Loading section .text, size 0x2284 lma 0x16000
Loading section .ARM.exidx, size 0x8 lma 0x18284
Loading section .data, size 0x458 lma 0x1828c
Loading section .jcr, size 0x4 lma 0x186e4
Transfer rate: x KB/sec, xxxx bytes/write.

(gdb) monitor reset halt
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0xc1000000 pc: 0x000006d0 msp: 0x000007c0

(gdb) break main
Breakpoint 3 at 0x123123: file ../main.c, line xx.

(gdb) continue
Continuing.
Clone this wiki locally