cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F031K6 Bootloader Write Memory Command Failure (No ACK or NACK)

chibi
Associate II

Hi,

I'm trying to utilise the built-in UART bootloader in the STM32F031K6 to perform firmware update. I've read the AN3155 and AN2606 documentation but unfortunately, I'm out of luck so far when trying to write the firmware via the bootloader to the target MCU's internal flash.

What I've got working so far:

  • I can communicate successfully over the UART interface to the bootloader
  • The GET command response indicates the bootloader protocol version is 3.1 and the following commands are supported:
    • 0x01 (Get Version & Read Protection Status)
    • 0x02 (Get ID)
    • 0x31 (Write Memory)
    • 0x73 (Write Unprotect)
    • 0x92 (Readout Unprotect)
  • The GET ID command response indicates the PID is 0x401

The following is not working for me:

  1. I send the "write memory" command and checksum, e.g. 0x31, 0xCE
  2. I receive the ACK, e.g. 0x79
  3. I send the 4 byte start address and checksum, e.g. 0x08, 0x00, 0x00, 0x00, 0x08
  4. I expected to receive either an ACK or a NACK but no response from the bootloader

Some observations:

  • Immediately following the above set of steps, I send the "Get ID" command + checksum. It fails and I receive two NACKs (i.e. 0x1F)
  • In the AN3155 document, it mentions the following:

"When a Read Memory command or Write Memory command is issued with an unsupported memory address and a correct address checksum (i.e. address 0x6000 0000), the command is aborted by the bootloader device, but the NACK (0x1F) is not sent to the host. As a result, the next two bytes (that is, the number of bytes to be read/written and its checksum) are considered as a new command and its checksum"

My questions:

  1. The start address and checksum I'm using, is it invalid (but it looks okay to me)?
  2. The list of supported commands seems weird, why is the GET command (i.e. 0x00) missing?
  3. The device PID is also odd, I cannot find it in the AN2606 document. In fact, according to chapter "64 Device-dependent bootloader parameters", page 326, the PID for STM32F03xx4/6 should be 0x444

Maybe I'm missing something obvious? All help and suggestions will be gratefully received.

Thanks to all in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

Seems like you're doing the correct thing.

Maybe your clock is a bit out of tolerance. The effect of this will only show up when you send a bunch of bytes together. Have you checked things on a logic analyzer or scope trace?

Sounds like something might be eating bytes, possibly as a result of framing errors. Certainly should have quite a few more supported commands in that list. Definitely check the clock.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

6 REPLIES 6
TDK
Guru

Seems like you're doing the correct thing.

Maybe your clock is a bit out of tolerance. The effect of this will only show up when you send a bunch of bytes together. Have you checked things on a logic analyzer or scope trace?

Sounds like something might be eating bytes, possibly as a result of framing errors. Certainly should have quite a few more supported commands in that list. Definitely check the clock.

If you feel a post has answered your question, please click "Accept as Solution".
chibi
Associate II

Hi,

Thanks very much for your quick response!

At the moment, I don't have access to any useful test tools that would help because of the current situation with self-isolation.

However, your suggestions lead me to double check my UART settings and my parity setting was incorrect. I have updated this to EVEN parity, as per the AN3155 document. It is now working much better!

For anyone curious, I am now seeing the following:

  • The GET command response indicates the bootloader protocol version is 3.1 and the following commands are supported:
    • 0x00 (Get)
    • 0x01 (Get Version & Read Protection Status)
    • 0x02 (Get ID)
    • 0x11 (Read Memory)
    • 0x21 (Go)
    • 0x31 (Write Memory)
    • 0x44 (Extended Erase)
    • 0x63 (Write Protect)
    • 0x73 (Write Unprotect)
    • 0x82 (Readout Protect)
    • 0x92 (Readout Unprotect)
  • The GET ID command response indicates the PID is 0x444

Stay safe and many thanks for your help and support!

Not quite there yet.....

The UART communication appears to be working and all the memory writes are correctly ACK'ed by the bootloader. However, when I dump the flash contents from the MCU, the retrieved bytes does not match those from the original firmware image.

Is it necessary to perform an erase first before writing?

For anyone else who might be having problems with the integrity of the data written by the bootloader.

I managed to get my issue resolved by pausing 2 milliseconds between each byte transmission.

Without the small delay, the firmware programmed by the bootloader never matched the original firmware image. There were only some matching bytes scattered throughout the flash.

Just to answer my own question - no, it is not necessary to erase the flash prior to writing.

What do you use as "master"?

I wonder, how could have been any command at all recognized and answered with the incorrect parity...

2ms between each *byte*? This must be excruciatingly slow! I'd this how the example programmer works?

JW

I'm not sure what "master" is but I transfer the firmware from a different MCU connected to the ST MCU via UART.

The required firmware can be provided to the host MCU via USB, UART, BLE, or external storage.

Regarding the timing, I agree with what you are saying: how could it work at all? But I'm afraid I don't know for sure without monitoring the UART line with a scope or logic analyzer (as per TDK's suggestion). Unfortunately, I don't have access to either tools at this point in time.

The download speed is not an issue for me but the integrity of the written data is of utmost importance. But even with that said, it doesn't take very long to download the maximum 32KB worth of firmware data. Of course, the time taken will also depend on the selected BAUD rate - which in my case is 19200.

Please note that the delay is only done for the "write memory" bootloader command - all the other commands (including read memory) works correctly.