Reimplementing CW STM32F serial programmer

Not sure this is the right forum for this question, but I’ve been stuck on this for weeks. Tried ST community forums and others without answer.

I know CW has had some development on this since the CW v4.x didn’t work reliably as opposed to v5.x STM32F serial programmer. (Source for it is here: chipwhisperer/software/chipwhisperer/hardware/naeusb/programmer_stm32fserial.py at develop · newaetech/chipwhisperer · GitHub )

Objective: to be able to program STM32F chips via UART in bootloader mode (and do other bootloader operations) from outside. This is documented in https://www.st.com/resource/en/application_note/cd00167594.pdf and https://www.st.com/resource/en/application_note/cd00264342.pdf

The issue: when I try either the procedure from STM32 documentation or the CW STM32 code, it somehow doesn’t work in my script (I use external USB-serial connection, not the one through CW). I get only one command executed: the “Get” command, others don’t work. It works no matter how many times I execute it. CW 5.x STM32 programmer that is run by CW Nano or CW Lite works now without problems.

How the STM32 serial protocol should work in short:

  1. set BOOT0 pin to 1, reset STM32 (the pattern depends on specific STMFx, but in general works like that)
  2. send 0x7F via UART, this selects the UART STM32 bootloader which allows the programming (tricky thing here - STM32 tries to guess the baudrate, there is no fixed one, CW 5.x uses 115200)
  3. send 2 byte commands via UART, e.g. “0x00 0xFF” for Get, “0x02 0xFD” for “Get ID”, “0x31 0xCE” for “Write memory”
  4. every command, including the first 0x7F should be followed by 0x79 (ACK) or 0x1F (NACK), sometimes more times
  5. STM32 docs say, that you should send a XOR checksum byte after every command

The difference between CW STM32 programmer and my script (#!/usr/bin/env python3import serialimport timeimport itertoolsimport o - Pastebin.com): CW STM32 programmer doesn’t send the XOR checksum, yet somehow works, but I can’t send even one command without it.

Snapshot from logic analyzer:

CW STM programmer (channel 0 is TX, channel 1 is RX; just the initial 0x7F to select UART in bootloader is missing from picture):

- both commands shown have 0x79 ACK as result.

Result from my script (channel 1 is TX, channel 0 is RX), first command “0x00 0xFF” works, the “0x02 0xFD” command breaks no matter what, with XOR checksum or not:

I decided to go with the CW’s STM32 programmer since it looks like much less work (unfortunately this precludes use of PhyWhisperer). Though for some reason it gives exceptions while waiting for the second ACK for some commands, no matter what timeout is set.

This is strange since extended erase command has 22 ms between two ACKs and an other command has also 22 ms between two ACKs, yet erase works always OK and the other command with the same time between to ACKs throws timeout when waiting for the second ACK in STM32Serial._wait_for_ask.