Burning Zero bootloader with Beaglebone as SWD programmer

 

OpenOCD has support for bitbanging the jtag or swd protocol over gpio’s. So if you have a board that can run OpenOCD and on which you have access to gpio’s, you can use that as a jtag or swd programmer. The following describes how to use a beaglebone for this purpose but any board with 3V3 gpio’s (e.g. raspberry pie) will do…

bb-m0-z

I followed these instructions to set up the beaglebone. I opted for the debian file system.

Following list of things to install before building OpenOCD will probably save you from having to iteratively install packages untill OpenOCD builds. Of coarse the exact list will change if the initial content of the debian file system changes:

apt-get install autoconf libtool make pkg-config 

Get the OpenOCD sources:

git clone git://git.code.sf.net/p/openocd/code openocd-code

Build openOCD:

cd openocd-code
./bootstrap
./configure --enable-sysfsgpio
make 
make install

openocd is now installed in /usr/local/bin and the scripts it uses are in /usr/local/share/openocd/scripts.

We need an extra config file to describe the beaglebone programmer. I added it here: /usr/local/share/openocd/scripts/interface/bb.cfg. The choice of the gpio’s is up to you, I picked gpio 38 (i.e. gpio1[6], pin header P8_03) and 39 (i.e. gpio1[7], pin header P8_04) as swd_io and swd_sck respectively, so bb.cfg looks like this:

#
# Config for beaglebone interface
#
# This is best used with a fast enough buffer but also
# is suitable for direct connection if the target voltage
# matches bone's 3.3V
#
# Do not forget the GND connection.
#

interface sysfsgpio

# minimal swd setup
sysfsgpio_swdio_num     38
sysfsgpio_swclk_num     39

# (Did not manage to make srst work:)
# sysfsgpio_srst_num      45

Store dot-cc’s bootloader (samd21_sam_ba.bin) in a directory of your choice on the beaglebone.

In that dir, create a openocd.cfg file. OpenOCD will read this file to know what it has to do, and how. In our case the file instructs OpenOCD to use the beaglebone as interface (programmer) and tells it we’re programming a samd21 chip.

source [find interface/bb.cfg]
transport select swd

set CHIPNAME at91samd21g18
source [find target/at91samdXX.cfg]

# did not yet manage to make a working setup using srst
#reset_config srst_only
reset_config  srst_nogate

adapter_nsrst_delay 100
adapter_nsrst_assert_width 100

init
targets
reset halt

If you invoke openocd in this directory, you should see following output.

# openocd
Open On-Chip Debugger 0.10.0-dev-00040-gd52070c (2015-10-11-18:21)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
SysfsGPIO num: swdio = 38
SysfsGPIO num: swclk = 39
SysfsGPIO num: srst = 45
adapter speed: 500 kHz
adapter_nsrst_delay: 100
cortex_m reset_config sysresetreq
none separate
adapter_nsrst_delay: 100
adapter_nsrst_assert_width: 100
Info : SysfsGPIO JTAG/SWD bitbang driver
Info : SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)
Info : This adapter doesn't support configurable speed
Info : SWD IDCODE 0x0bc11477
Info : at91samd21g18.cpu: hardware has 4 breakpoints, 2 watchpoints
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* at91samd21g18.cpu  cortex_m   little at91samd21g18.cpu  running
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x21000000 pc: 0x000028f4 msp: 0x20002c00

OpenOCD is now constantly polling the device and it is ready to accept new instructions from us via telnet or gdb. You could log into openocd using telnet from your pc (or from the bone) and inspect memory, run code, start debugging…

If on the other hand you are just interested in burning the bootloader, you could add following line at the end of openocd.cfg and start openocd again.

at91samd bootloader 0; program samd21_sam_ba.bin verify reset; shutdown

OpenOCD should now produce following extra report about the flashing operation.

** Programming Started **
auto erase enabled
Info : SAMD MCU: SAMD21G18A (256KB Flash, 32KB RAM)
wrote 16384 bytes from file samd21_sam_ba.bin in 4.120137s (3.883 KiB/s)
** Programming Finished **
** Verify Started **
verified 6328 bytes in 0.575388s (10.740 KiB/s)
** Verified OK **
** Resetting Target **
shutdown command invoked

The M0 is now ready to receive sketches from the dot-cc IDE.
Remark: if you previously made the modification to the dot-cc lnker script from my previous post, don’t forget to undo this change.

In case you want to restore the dot-org bootloader, use this line as last line in openocd.cfg instead:

at91samd bootloader 0; program Bootloader_D21_M0_150515.hex verify reset; shutdown
Advertisements

16 thoughts on “Burning Zero bootloader with Beaglebone as SWD programmer

  1. A.Feichtner

    Thank you for this great tutorial. I followed you’re instructions but was using a bananapi pro board running archlinux.
    I used physical pins 37 (bcm gpio 26) and 38 (bcm gpio 20). Interface script looks like this:
    #[snip]
    interface sysfsgpio
    # minimal swd setup
    sysfsgpio_swdio_num 26
    sysfsgpio_swclk_num 20
    #[end]

    Reply
  2. C. Cross

    Hi Peter,

    Thanks as well for these instructions; it gives me hope that I won’t need to lay down an Atmel embedded debugger to flash the bootloader from my BBB.

    I’m having some issues, however, in that I have followed your guide precisely, but I’m not able to successfully “examine” the board from OpenOCD, so all subsequent functions fail as well. My setup is nearly identical to yours, the only difference being that I am using a Beaglebone Black instead of the original Beaglebone. I have tried several different pins, but to no avail. Is there something in your setup that I might be missing, such as manually handling the chip reset lines from the BBB, since OpenOCD doesn’t seem to be able to? I also did a comparison between the output from an atmel ice programmer (successful) and my unsuccessful bitbanging with a logic analyzer, and the output looks completely different. I also tried running openocd with nice –20 and just about everything killed on the BBB, no difference.

    Any guidance on what might be the issue? If needed, I can send my logic analyzer captures or other information.

    Much appreciated,
    Charles

    Reply
  3. petervho Post author

    On the BBB, many of the pins on header P8 are already used by the BBB board itself for the eMMC or the lcd (hdmi). Carefully select the gpio’s for openocd. If you would pick such a conflict pin, you will probably damage your BBB. So carefully read the section “BeagleBoneBlack Cape Compatibility” in the user manual. On header P8: pin 7 (gpio 66) as swdio and pin 8 (gpio 67) as swclk are OK. I gave it a quick try with these pins on BBB, and it worked.

    Reply
    1. C. Cross

      Hmm. I tried those exact pins, making sure no other drivers were using them, and my logic analyzer output looks a bit more sane now, but I’m still seeing the same openocd errors. Here are all of the details:

      uname -a: Linux openrov 4.1.8-ti-r18 #1 SMP PREEMPT Sat Sep 26 02:16:14 UTC 2015 armv7l GNU/Linux
      bb.cfg – Same as yours, except pins 66 and 67
      openocd.cfg – Same

      Logic Analyzer output: http://i.imgur.com/Jml6Til.png
      OpenOCD output: https://drive.google.com/a/openrov.com/file/d/0B4H3ENbMbJSPRDlDMWlHek5GTnc/view?usp=sharing
      Pingroup and Pins output: https://drive.google.com/a/openrov.com/file/d/0B4H3ENbMbJSPVU02d2d1eXZKY3M/view?usp=sharing

      I’ve tried on both an Arduino Zero Pro and a custom SAMD21 board, both of which are able to be programmed successfully using the ICE programmer. In both cases, the boards were properly powered and grounded.

      A bit stumped at this point; any more ideas? Thanks again for your help!

      Reply
  4. petervho Post author

    I did a git pull in my OpenOCD repo in order to have the most recent version. Guess what, I now have the same problem: the very first swd transaction fails like this:
    Debug: 243 152 bitbang.c:449 bitbang_swd_read_reg(): JUNK DP read reg 0 = ffffffff
    .
    Odd enough the problem persists if I go revert to my previous version using git reset –hard dfc6658. …

    Forget what I wrote above: it was a manipulation error: the M0’s USB cable was not connected, so I was trying without the target powered.

    I have now the same version as yours (git commit dfc6658), and it works fine on BBB.

    So the difference must be the target. You probably already triple checked wiring and power… Just spawning some ideas: for the Pro: I wonder whether the edbg chip nicely tristates the swd signals when it is or should be idle? (For my M0, it is simple: the swd headers are connected only to the samd). Do you have another target to test with? a due (never tried that myself though…)? incidently an stm32f4 discovery board? (those are easy to disconnect from their on board programmer…)

    Reply
  5. petervho Post author

    In case you want to try with an arduino due as target (this would rule out something is driving the swd pins against the bbb), I have checked that this works with the bbb setup.
    Here is an openocd.cfg that flashes a blink sketch (compiled with the ide) to the arduino due:

    source [find interface/bbb.cfg]
    transport select swd
    
    set CHIPNAME at91sam3X8E
    
    source [find target/at91sam3XXX.cfg]
    set _FLASHNAME $_CHIPNAME.flash
    flash bank $_FLASHNAME at91sam3 0x0080000 0 1 1 $_TARGETNAME
    
    #reset_config srst_only
    reset_config  srst_nogate
    adapter_nsrst_delay 100
    adapter_nsrst_assert_width 100
    
    init
    targets
    reset halt
    program Blink.ino.bin verify reset exit 0x0080000
    
    Reply
    1. C. Cross

      Good news, I was able to successfully flash the SAMD21 from pins 66 and 67 on my BBB by rolling back to d52070c like you mentioned. I’ve been touching base with Paul Fertser, who originally wrote the SWD GPIO interface, on the OpenOCD IRC and plan to provide him with a bisect when I get some free time and figure out where things went south. Your help has been invaluable in working through this, so thanks much! Will post an update here when normal functionality is restored, or we get to the bottom of what might be wrong with configuration changes, if the issue lies there.

      Reply
      1. C. Cross

        Also, my working configuration:

        bbb.cfg
        ——————–
        interface sysfsgpio
        sysfsgpio_swdio_num 66
        sysfsgpio_swclk_num 67

        openocd.cfg
        ——————–
        source [find interface/bbb.cfg]
        transport select swd
        source [find board/atmel_samd21_xplained_pro.cfg]

        reset_config srst_nogate
        adapter_nsrst_delay 100
        adapter_nsrst_assert_width 100

        init
        targets
        reset halt
        program samba.hex
        reset

  6. petervho Post author

    Good to hear it works. However I don’t think there is a regression: programming failed with the newer version because I made a manipulation error: the target was not powered. That is why it persisted when I reverted. I have edited my reply above. Sorry for the confusion. I think in your setup, something works intermittently and that coincidently it started to work after reverting. Could that be the case?

    Reply
    1. supaidakisu

      You were correct in that it was an intermittent issue, haha. Turns out I had a floating Reset pin, which worked some days and didn’t work other days. Learned this when I ported all of the flashing scripts to the Raspi2 and it exhibited some of the same issues, even with its bcm2385gpio driver. Got both working with the master branch now!

      Reply
  7. Pingback: Programming Microcontrollers using OpenOCD on a Raspberry Pi – Your Smart IOT

  8. SivaSubrahmanyam Nallamalli

    I am getting fallowing error after using openocd as per mentioned configuration. target board was nrf51822 chip with arm-cortex m0.
    Error: Could not initialize the debug port
    TargetName Type Endian TapName State
    — —————— ———- —— —————— ————
    0* nrf51.cpu cortex_m little nrf51.cpu unknown
    Error: Could not initialize the debug port

    interface/bb.cfg.
    interface sysfsgpio
    # minimal swd setup
    sysfsgpio_swdio_num 49
    sysfsgpio_swclk_num 117
    # (Did not manage to make srst work:)

    openocd.cfg
    # This is for BEAGLE BOARD running GPIO as an SWD to a Nordic Semiconductor nRF51 chip
    source [find interface/bb.cfg]
    transport select swd

    #set CHIPNAME nrf51822
    source [find target/nrf51.cfg]

    #reset_config srst_only
    reset_config srst_nogate

    adapter_nsrst_delay 100
    adapter_nsrst_assert_width 100

    init
    targets
    reset
    halt

    Reply
    1. Christopher Arena

      I came across the “soft_reset_halt” command. Where you might use “reset halt” try that. I was able to reset and halt my target, allowing the loading to work.

      Chris

      Reply
    2. petervho Post author

      In your script, ‘reset halt’ is one command so it should be on one line.

      I mean time I bought an nrf51822 dev board as I want to try out the m0 based nrf myself. So far I just tried a blink example. I could flash it by adding following lines to the openocd.cfg:
      flash write_image erase main.hex
      verify_image main.hex
      reset run
      shutdown

      Reply
  9. Christopher Arena

    What about nrst? why isn’t that working in the sysfs gpio? I’m having that problem. The clock and data are working but I need the reset to be able to debug.
    In my logic pro output, it looks like the reset signal is in input mode at about 2.4 Vdc. If I manipulate that bit myself, I can reset the target.
    Thanks!
    Chris

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s