cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F722RE SPI bootloader weirdness (ack, mass erase)

timecop1818
Associate II

I've got a design with a STM32F405RE bootloading onboard STM32F722RE via SPI1.

I've implemented SPI bootloader host (mostly same as serial with addition of adding extra 5A frame and dummy reads in a couple places) and individually verified commands like GetVersion, ReadMemory, WriteMemory, EraseMemory etc as working.

However, EraseMemory followed by WriteMemory does not work.

This is referencing AN4286 throughout this post.

Two questions regarding this:

1) Get ACK Procedure (Figure 2 in AN) has the following:

send dummy / receive data, checking if received data is ack or nack, however, there's a loop back to beginning where you keep sending/receiving data and waiting for correct byte. I am seeing this behavior here as well, and it takes about 10-15 ack reads before ACK is returned. I understand that's what the flowchart says so I'm assuming this is OK. Right?

2) Here is where it gets weird. I've implemented EraseMemory as mass erase (Figure 18, left-side flow), by sending 0xff 0xff 0x00 and then waiting for ack.

0693W00000YAm5PQAT.pnghere's the traffic flow over SPI:

SPI 5a->a5 < frame
SPI 44->a5 < cmd + crc
SPI bb->a5 < cmd + crc
SPI 00->a5 ... SPI 00->a5 < wait for ack
SPI 00->79 < ack
SPI 79->a5 < confirm ack
SPI ff->a5 < data frame for mass erase
SPI ff->a5 < data frame for mass erase
SPI 00->a5 < data frame for mass erase (crc)
SPI 00->a5 ... SPI 00->a5 < wait for ack
SPI 00->79 < ack
SPI 79->a5 < confirm ack

the SPI 00->a5 ... SPI 00->a5 bits are repeated transfers of 0x00 -> reads of 0xa5 until ack is finally returned.

According to this, the mass erase should now commence, right? I've peeked at the datasheet and max mass erase time is 6.9 sec. I tried waiting that duration before using WriteMemory, but that didn't work either. WriteMemory will fail waiting for ack after sending 1st command frame.

What DOES work is simply resetting the STM32F722 between mass erase and writing, like, reset (entering bootloader), erase, reset again, write memory, reset -> works.

12 REPLIES 12
MWB_CHa
ST Employee

Hi @timecop1818​ 

What was presented here are just quick workarounds to allow unblock the situation. These are not part of any standard procedure for the Bootloader.

In summary you have now 3 workarounds:

  1. Wait till end of Flash erase (~9seconds) before sending the ACK frame
  2. Wait 680ms before sending the ACK frame as indicated in my previous message
  3. Wait for NACK that indicates readiness of device to receive new commands

The root cause is still under investigation, but as I explained before: the last ACK is lost because of latency on the Flash due to the code being executed from Flash while Flash is stalled during erase and DMA free running on SPI buffers (DMA interrupt not managed till end of Flash stall).

This is not the full explanation of course, we need to understand why the stall is causing loss of an instruction and why it occurs only on STM32F7 device.

If workaround 1 is suitable for you (waiting 9 seconds) then you don't need the other points.

Of course, once problem is fully understood and workarounds defined, this will be documented in AN2606 in the STM32F7 section.

timecop1818
Associate II

Hi,

  1. Wait 680ms before sending the ACK frame as indicated in my previous message

That's the thing. I did that (in same place where I now inserted 9s delay) and that did NOT work.

It returns ack, my code moves on since it thinks mass erase is done now, and the write_memory stuff fails. The only way that worked was replacing that 680ms delay with 9 seconds delay.

And looking at your suggested workaround, you are checking for NOT ack returns, which is why I was confused how it's supposed to work.

MWB_CHa
ST Employee

Hi @timecop1818​ 

I now have the confirmation of the issue root cause and its scope.

Root cause:

The issue root cause is that Flash is stalled due to the mass erase operation (execution of instructions from flash is stopped till end of erase operation), while SPI DMA is still running in circular mode and sending the content of its buffers.

The content of the buffers being inconsistent and not updated by the code which is stalled, it sends incorrect ACKs to the host.

This issue exists on all products older than STM32L4, but visible only when erase operation duration is long enough for the host to get wrong data from SPI DMA buffers. (not visible when erase operation is short).

Workaround:

As explained above, 3 workarounds are possible:

  1. Wait for a duration indicated in the datasheet corresponding to the full erase operation (ie. 9seconds in the STM32F7 case)
  2. Adding delay before sending the ACK frame
  3. Poll for ACK till host receives no ACKs which indicates that Flash stall has been ended and now SPI DMA buffers content is up to date.

Fixes:

This issue was actually spotted and fixed starting from STM32L4 and on all newer devices.

SPI DMA buffers content is cleared before starting the erase operation, which prevents it from sending inconsistent ACKs to the host while Flash is stalled.

Documentation:

The issue was not documented up to now. It will be described in AN4286 along with full list of impacted STM32 devices (basically: STM32F4, STM32F7, STM32H7) and the workarounds description. Document update is planned shortly.

As per your answer that workaround 2 didn't work in your setup, I think that you might be inserting the delay in the wrong place? If you could share the section of the code with us, we may spot the issue.

I hope this provides you with all the information you need regarding this issue ?

Please let me know shall you need further details/information.