cancel
Showing results for 
Search instead for 
Did you mean: 

JTAG / SWD (Nucleo?) over SPI code example

Aleksejs_S
Associate II

Hello,

I got a radio MCU which connects to cloud and can receive binaries from database. And I got a STM32 that controls some stuff, including other MCUs. In production this means a lot of headers and programming time for all of them, no way to update remotely, and even if the code is thoroughly tested - glitches are still possible.

So I want to connect things in a chain, so that if something apart from the radio crashes - radio MCU could re-flash the whole system. This of course could be done with UART when using bootloaders, but this again means you have to pre-program bootloaders on MCUs, and there's still a very slim chance it might fail.

So I need an example of how one MCU can flash another via JTAG or SWD (preferably), and then verify the result. From there I could get it to work on Arduino / STM / AVR / radio ARM. What I really want is a proof of concept simple test example to show it works with the peripheral (bit banging is always possible, but surely there is a smarter way to do it using existing MCU resources), before I go ahead and order prototype boards.

In general this should not be black magic, we've all got some Nucleo boards, which are a great example that programming STM32 with STM32 is possible. On my NucleoF722ZE, the STM32F103CBT6 does the programming. It should receive packets via USB, then program the main MCU via either JTAG or SWD. It has a pair of jumpers - CN4, when closed - the jumper connects T_JTCK with SWCLK, and T_JTMS with SWDIO, and programs the big MCU via SWD interface.

sch.png

When I look at how these signals are wired, I see this:
PB14 (SPI2_MISO) - T_JTMS - SWDIO
PB13 (SPI2_SCK) - T_JTCK - SWCLK
PB12 (SPI2_NSS) via resistor - T_JTMS - SWDIO

It leads me to think that SWD is done somehow with SPI2 in half-duplex master mode. I've seen people mentioning SPI for JTAG more than once, but I haven't found a good example.

If STM has the code for Nucleo STM32F103CBT6 programmer freely available - that would be everything I need to proceed with my project. But I can't find it.

 

What I have found so far:

JTAG bit-banging example: https://github.com/openwch/usb-jtag-spi/tree/main/src/OpenOCD/USB20JTAG

Free DAP, also bit-banging: https://github.com/ataradov/free-dap/blob/master/dap.c

Arduino SWD programmer, bit-banging: https://github.com/dimitar-kunchev/arduino-swd-programmer-samd/tree/master

LibSWD, opensource project to make SWD more available: https://github.com/cederom/LibSWD/tree/master

There are Black Magic probe source codes: https://github.com/blackmagic-debug/blackmagic

Wiki page on ST-link with some links to firmware reverse-engineering: https://stm32world.com/wiki/ST-Link

There's a lot of references to OpenOCD, but it's a ton of information, and at this point I don't even see if it's useful for me:
https://openocd.org/doc/html/index.html

https://learn.adafruit.com/programming-microcontrollers-using-openocd-on-raspberry-pi/wiring-and-test

There is a topic on Hackaday, which is about the hardware and firmware of STlink: https://hackaday.io/project/179054-custom-st-link-v20-v21-v30/details

At this point I'm just shocked that programmer firmware is something that people need to hack, instead of ST just providing a source code so people can use it with their ICs.

SWD tutorial page: https://robo.fish/wiki/index.php?title=SWD

ST-link open source project: https://github.com/stlink-org/stlink

There is also an adaptation of libSWD for ESP32 which in fact uses SPI, and this might be the most relevant resource: https://github.com/PaulFreund/libSWD-esp32


So it's not like there is no information on the topic. Almost all the code I found seems to bit-bang the data. I find it hard to believe that both JTAG and SWD on all STM32-based programmers are wired to SPI peripheral by pure coincidence :D Especially after that last repo for ESP32, which reads it via SPI.

Or maybe I'm just blind and don't see something right in front of me, and someone will be able to point it out :D

It looks like the best approach is to adopt Paul Freund's project to some Arduino board and check out if it works fine. In the meantime, if anyone knows of original STM32 STlink source, or SWD example, or Arduino/STM32/AVR source that uses SPI to do SWD, to upload the flash to STM32 and check if it uploaded correctly - please drop a comment.

I hope if this does not get resolved, at least the stuff I collected here might be of use.

UPD. 1

Another project, using SWD over SPI with Raspberry PI: https://github.com/lupyuen/pi-swd-spi

And it has a cool spreadsheet with commands and bits: https://docs.google.com/spreadsheets/d/12oXe1MTTEZVIbdmFXsOgOXVFHCQnYVvIw6fRpIQZybg/edit#gid=0

UPD. 2

A very interesting blog post explaining how to do SWD over SPI: https://www.pcbway.com/blog/technology/OpenOCD_on_Raspberry_Pi__Better_with_SWD_on_SPI.html

An Arduino example for monitoring SWD line (might be useful to test or verify something): https://levelup.gitconnected.com/listen-up-how-to-monitor-uart-i2c-swd-and-spi-with-arduino-9d8ef25da308

 

10 REPLIES 10

Thanks for putting me on the right track again!