Skip to main content
Visitor II
April 22, 2020
Solved

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

  • April 22, 2020
  • 2 replies
  • 3051 views

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.

    This topic has been closed for replies.
    Best answer by TDK

    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.

    2 replies

    TDKAnswer
    Super User
    April 22, 2020

    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.

    chibiAuthor
    Visitor II
    April 23, 2020

    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!

    chibiAuthor
    Visitor II
    April 24, 2020

    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?

    Super User
    April 25, 2020

    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

    chibiAuthor
    Visitor II
    April 26, 2020

    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.