Skip to main content
Visitor II
July 2, 2021
Question

STM32H743 DFU Entry doesn't work unless BOOT0 held high at power-on

  • July 2, 2021
  • 9 replies
  • 3009 views

I'm having trouble entering the DFU bootloader on my H743 (rev V).

power on (with BOOT0 high) -> USB DFU functions as expected

power on (with BOOT0 low) -> application functions as expected

reset (with BOOT0 low) -> application functions as expected

reset (with BOOT0 high) -> DFU bootloader doesn't work

jump from application to DFU -> DFU bootloader doesn't work

I've tested this behavior both on a custom board (H743ZI rev V), and on a Nucleo-H743ZI2 with the same results. If I break in to the debugger in either of the not-working scenarios, I can see the program counter is in the bootloader's code somewhere, so it *is* jumping in, but USB doesn't work.

Jumping from application to bootloader works fine with the same application running on various F4 and F7 devices, but doesn't work on the H7.

 What's going on? Why can't I enter the bootloader except at power-on?

    This topic has been closed for replies.

    9 replies

    Super User
    July 10, 2021

    > reset (with BOOT0 high) -> DFU bootloader doesn't work

    This works fine on my H743ZI2 nucleo board. I suspect something else is going on.

    MKenn.1Author
    Visitor II
    July 11, 2021

    > This works fine on my H743ZI2 nucleo board. I suspect something else is going on.

    Really? Pushing the reset button with a wire from BOOT0 -> 3.3v resets in to the bootloader? How could that work *sometimes*?

    Super User
    July 11, 2021

    Yes, really. Could be a poor connection from the wire, such that it doesn't pull the pin up. Could be a bad USB cable. Could be the PC ignores the device due to what it previously did on the port.

    MKenn.1Author
    Visitor II
    July 13, 2021

    I can pretty much rule all those out. I know it's actually entering the bootloader (wire/button works fine), since I can break in in the debugger and see it running.

    0693W00000BdZlEQAV.pngLikewise, I'm sure the cable is fine because USB works fine while running the application (ie, not bootloader). PC isn't ignoring it due to something previous, because I can power on the device, reset to DFU, then connect USB, and the behavior is the same. dmesg shows no new USB device.

    Super User
    July 13, 2021

    I don't know what the problem is, but it does work on my H743ZI2 board without issue on Win10. It doesn't appear to be a hardware issue. My guess is something funny going on on the PC side. If you have another machine, I would test on there. OS is probably relevant here.

    MKenn.1Author
    Visitor II
    July 14, 2021

    I've tried on 3 different PCs, two Windows and one Linux.

    I did a bit of reverse engineering with Ghidra + GDB, and there's a function with a big loop that checks, in sequence:

    • FD-CAN
    • I2C1-3
    • SPI1-4
    • Check if something is happening on the RX bit in GPIOB - USART1 alternate mapping (if so, switch the alternate function mapping for USART1 to PB14/15)
    • USART1-3
    • Check if a struct in RAM contains a particular value (USB :))

    (curiously, this doesn't match the order of checks in AN2606 :o)

    In the USB OTG interrupt, that same struct in RAM is set to contain the "cable present" value. But that condition is never happening, so USB isn't getting initialized for whatever reason.

    MKenn.1Author
    Visitor II
    July 15, 2021

    Some fun facts:

    • The H7 bootloader is implemented using ST HAL (functions and structs match exactly), but the older F4/F7 bootloaders are not.
    • This H7 bootloader was probably compiled with optimization either disabled, or maybe at -Og, which seems like an oversight. Even trivial single-instruction functions didn't get inlined.
    Super User
    July 15, 2021
    Makes sense as F4/F7 predate HAL.
    It’s interesting that ST itself is using HAL. I guess that’s a good thing overall?
    Thanks for sharing.
    MKenn.1Author
    Visitor II
    July 20, 2021

    The plot thickens! I disabled USB in our application, so now it can't talk to the PC, but it's still fully alive. Created a thread that just waits a few seconds, then reboots to DFU (one of the things that didn't work before). Reset-to-DFU now works just fine. What the heck ST? A system reset is supposed to reset the system as if you'd powered it on, right? How is state spilling around a reset?

    Super User
    July 20, 2021
    In your jump to DFU, try resetting the usb peripheral with the RCC reset bit, waiting 500ms, then doing the jump. The PC could be ignoring it due to the device changing behavior, or thinking it’s still the old device.
    MKenn.1Author
    Visitor II
    July 20, 2021

    This test was done on an H743ZI2 Nucleo with the st-link USB connected, let the reset-to-DFU happen, then connect the other USB connector after the reset. PC never sees the device until the system ROM is running.

    MKenn.1Author
    Visitor II
    July 20, 2021

    The plot thickens again. Something is clearly leaking across a reset, because I now have a solution to the problem that's pretty weird. Setting the relevant bits in AHB1RSTR doesn't help, still doesn't work. However, before the reset, clearing the USB peripheral enable bits in AHB1ENR DOES make it work after the reset. No delay or anything, just turn off the power, leave our breadcrumb, then hit NVIC_SystemReset().

    This is all of the change required to make it work: https://github.com/rusefi/rusefi/pull/2999/files