SWD with OpenOCD and a Bus Blaster

| tagged with
  • swd
  • jtag
  • openocd
  • arm

For a while now OpenOCD has had some support for Serial Wire Debug (SWD). SWD is an alternative to the JTAG wire protocol used largely on ARM microcontrollers and has the advantage of requiring only two I/O pins (data and clock), power, and ground (as opposed two JTAG’s four data pins, two resets, power, and ground).

Unfortunately, the documentation surrounding OpenOCD’s SWD implementation is a bit sparse. This afternoon I finally grew frustrated with the mess of wires required by JTAG and forged ahead into OpenOCD’s SWD support.

The target in this case in my solar battery charger which has an STM32L151 microcontroller. The adapter is a Bus Blaster v3. Testing was done with OpenOCD bd0409aa938875ea5a8d8235f8996116be171b69.

One nice property of the Bus Blaster is it has a CPLD which performs the role of a reconfigurable buffer. While the device comes flashed with the not-SWD-capable JTAGkey buffer, it’s trivial to flash this device with an SWD-capable buffer instead. KT-link is one such buffer configuration.

The first step was to flash the Bus Blaster’s CPLD with a KT-link buffer. While Dangerous Prototypes’s repository only contains sources for Bus Blaster v2, Ben Harris has a convenient implementation for the v3 hardware complete with SVF bitcode. Flashing the buffer is easily accomplished with OpenOCD, as previously documented,

$ git clone https://github.com/bharrisau/busblaster.git
$ cd busblaster/synthesis
$ openocd -f board/dp_busblaster_v3.cfg -c "adapter_khz 1000; init; svf system.svf; shutdown"

Setting up OpenOCD

The ever-helpful PaulFertser offered this soon-to-be-merged patch adding a Bus Blaster-with-KT-link configuration to OpenOCD-proper. With it, configuration is trivial,

$ cat >openocd-swd.cfg <<EOF
source dp_busblaster_kt-link.cfg
transport select swd
source [find target/stm32l.cfg]
EOF

Now just connect things as follows,

     adapter         ┊            target
                     ┊
     TCK ──────────────────────── SWCK
                     ┊
     TMS ──────────────────────── SWDAT
                     ┊

And voila,

$ openocd -f openocd-swd.cfg 
Open On-Chip Debugger 0.9.0-dev-00141-g11db2c2 (2014-08-23-14:32)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : FTDI SWD mode enabled
none separate
adapter speed: 300 kHz
adapter_nsrst_delay: 100
cortex_m reset_config sysresetreq
Info : clock speed 300 kHz
Info : SWD IDCODE 0x2ba01477
Info : stm32l.cpu: hardware has 6 breakpoints, 4 watchpoints

Approach #2: Resistor hack

If you have an FTDI-based adapter other than the Bus Blaster or would rather not reflash your Bus Blaster’s buffer it is also possible to emulate an SWD-capable buffer with a current limiting resistor and a bit of wire. [swd-resistor-hack.cfg] in the OpenOCD repository describes the connections necessary for SWD with an FTDI-based adapter like the Bus Blaster,

     adapter                   ┊       target
                               ┊
     TCK ───────────────────────────── SWCK
                               ┊
     TDO ────────────────┬──────────── SWDAT
                         │     ┊
     TDI ─────/\/\/\/────┘     ┊
              220 ohm          ┊

Now it’s simply a matter of a little configuration,

$ cat >openocd-swd-hack.cfg <<EOF
source dp_busblaster.cfg
source [find interface/ftdi/swd-resistor-hack.cfg]
transport select swd
source [find target/stm32l.cfg]
EOF

To reiterate, this can be done with any FTDI-based JTAG adapter, including the Bus Blaster with any buffer configuration.

Gotchas

While I’ve found that the SWD interface is actually more reliable that JTAG with my hardware (likely a reflection of my poor wiring), there are still a few rough edges in OpenOCD’s SWD implementation. Most notably, if the target loses power OpenOCD’s polling procedure will fail to reestablish communications. This is because the target’s debug port comes up in JTAG mode and OpenOCD makes no attempt to move it back to SWD.

  • the MC HCK project’s programmer has a nice SWD implementation written in Ruby which supports both the Bus Pirate and the Bus Blaster