Flashing nRF51 with OpenOCD on Raspberry Pi

On our project we're using a Raspberry Pi 3 compute module with custom hardware and 2x nRF51 SoC running HCI from Zephyr.

We'll be delivering more than 150 of those devices, that means more than 300 nRF51 and flashing each one of them manually is boring and time consuming. So when I figured I could use OpenOCD directly on the Raspberry Pi I've started planning to have SWDIO and SWDCLK wired directly to the GPIO so on 1st boot the Pi could flash the bluetooth firmware.

But of course it's not working. That would be too easy.

I compiled without issues OpenOCD directly on the Pi following those tutorials HERE and HERE.

Connecting a ST-Link/V2 on the Raspberry Pi USB port it all work as it should. Connects to the nRF51, erase, flash, run.

Now using directly the Pi GPIO, I've connected 3V3, GND from the Pi-CM3-Dev Kit to the nRF51 and SWD to GPIO 24 and 25. There's no connection for SRST or TRST on the module.

I'm using openocd.cfg as follows

source [find interface/raspberrypi2-native.cfg]
bcm2835gpio_swd_nums 25 24
transport select swd

# target
source [find target/nrf51.cfg]

init
targets

I've tried adding several reset_config parameters on this config such as srst_only, srst_nogate and none as from the tutorials, but nothing changed the resul. Open calling sudo openocd -f ocd.cfg I always get the following error:

Error: Could not initialize the debug port

Open On-Chip Debugger 0.10.0+dev-00111-gca9dcc8 (2017-04-24-15:30)
Licensed under GNU GPL v2
For bug reports, read
    openocd.org/.../bugs.html
BCM2835 GPIO nums: swclk = 25, swdio = 24
cortex_m reset_config sysresetreq
adapter speed: 1000 kHz
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)
Info : clock speed 1001 kHz
Info : SWD DPIDR 0x00150634
Error: Could not initialize the debug port
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* nrf51.cpu          cortex_m   little nrf51.cpu          unknown

I'm under the assumption that raspberrypi2-native.cfg is compatible with Raspberry Pi 3 but we've just ordered a raspberrypi2 to the office to test on it as well.

Is there anything I'm doing wrong here? Did someone experience that before? The only thing I found was a thread on sourceforge for the OpenOCD project, but it was from 2015 and all code patches suggested there is already included on the latest release.

Maybe someone can suggest another software to accomplish the same thing.

  • The pointer to fix this was from the question I posted on StackOverflow: stackoverflow.com/.../906362

    The main point was to adjust it to the right speed coefficient for the PI 3. That means, for other PIs you'll have to adjust coeffs and peripheral base, as per table:

     # Raspi2 and Raspi3 peripheral_base address
     bcm2835gpio_peripheral_base 0x3F000000
     
     # Raspi1 peripheral_base address
     bcm2835gpio_peripheral_base 0x20000000
     
     # Raspi3 BCM2837 (1200Mhz): 
     bcm2835gpio_speed_coeffs 194938 48
     
     # Raspi2 BCM2836 (900Mhz):
     bcm2835gpio_speed_coeffs 146203 36
     
     # Raspi1 BCM2835: (700Mhz)
     bcm2835gpio_speed_coeffs 113714 28
    

    We have several OpenOCD cfg script files (to execute flash, erase, reset or check status on the nRF51 connected on pins 20,21 and on pins 30, 31). Below is one of the scripts:

     # pi interface
     interface bcm2835gpio
     bcm2835gpio_peripheral_base 0x3F000000
     bcm2835gpio_swd_nums 20 21
     bcm2835gpio_speed_coeffs 194938 48
     bcm2835gpio_srst_num 18
     reset_config srst_only srst_push_pull
     
     # transport
     transport select swd
     
     # target
     set WORKAREASIZE 0
     set CHIPNAME nrf51822
     source [find target/nrf51.cfg]
     reset_config srst_only srst_nogate
     adapter_nsrst_delay 100
     adapter_nsrst_assert_width 100
     
     # execution
     init
     targets
     halt
     nrf51 mass_erase
     flash write_image <full_file_path>.hex 0
     reset halt
     targets
     verify_image <full_file_path>.hex 0
     reset run
     targets
     exit