cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G071CBU6 I2C Bootloader Stops Responding

bhaerel
Associate

Hi,

I have a custom PCB where I am attempting to bootload an STM32G071CBU6 (using an STM32U575).

I am using the bootloader while developing for uploading development builds, so it is being used often. The G0 seems to occasionally, randomly, stop responding and clock stretch indefinitely while the firmware is being written to the MCU. Sometimes this is remedied by resetting the chip and starting the bootloading process over again, sometimes I have to power cycle the whole board, and there have been a couple of instances now where even power cycling would not fix it, and I would have to erase the chip using an STLink.

The problem almost always presents as the host MCU reading back a non-valid ACK byte (according to AN4221) - I've seen 0x4D most recently which does not match 0x79 for ACK, 0x1F for NACK, or 0x76 for BUSY. It is usually the first response when polling for an ACK after writing a block of byte to memory. If the host MCU tries to read again, the G0 will clock stretch indefinitely.

Invalid read byte

bhaerel_0-1731638215680.png

Subsequent read:

bhaerel_1-1731638272805.png

And the G0 will need to be reset to release the I2C lines. We have verified it is the G0 pulling the lines low and not the host MCU by looking at the analog voltage - the U5 seems to have a stronger driver and will pull the lines 50-100mV lower than the G0.

 

Here is the start to the "Write No-Stretch" command right before the above reads:

bhaerel_2-1731638431360.png

The memory address is correct, and the G0 is responding with ACKs appropriately.

It's strange because sometimes it takes an 30+ bootloads before it happens, then can happen 10 times in a row or even be unrecoverable without a programmer (which is the case that worries me, as that would be a disaster for a board in production).

 

The bootloading process that I'm following is as described in AN4221 and AN2606, using no stretch I2C commands:

  1. Reset the STM while holding the BOOT0 line high (after the option byte is set correctly to do so)
  2. Release the BOOT0 pin
  3. Send the GetVersion (0x01) command and read back the version
  4. Read the option bytes using ReadMemory (0x11) at address 0x1FFF7800 to make sure the BOOT0 option is set correctly
  5. Read a memory address where the current firmware version is expected using ReadMemory (0x11) again
  6. Erase the flash using the Erase No Stretch command using 0xFFFF for the special global erase. Wait 20ms and then poll for an ACK.
  7. (This much seems to always succeed, and I've checked the flash using the STLink and it is properly erased at this point)
  8. Write the firmware to flash starting at address 0x8000000 in blocks of 256 bytes. This process is shown in the screenshot above and is as follows:
    1. Send the WriteMemory No Stretch command and poll for ACK
    2. After the ACK, write the start address, checksum and pol for ACK
    3. Write the number of bytes to be written -1
    4. Write the data
    5. Write a checksum for the data
    6. Poll for ACK

 

Is there something that the host MCU may be doing incorrectly to cause this problem? I've uploaded Saleae Logic 2 captures of the start and end of a failed bootloading (just cutting out most of the actual firmware data) if anyone would like to look at the logic trace.

0 REPLIES 0