SWD with OpenOCD and a Bus Blaster
SWD with OpenOCD and a Bus Blaster
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
Approach #1: KT-link
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.
Flashing the KT-link buffer
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 ┊
$ 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.
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.