2023-11-06 01:46 AM - edited 2023-11-06 06:00 AM
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.
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
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
2024-11-12 07:33 AM
Thanks for putting me on the right track again!