2025-10-23 8:22 PM - last edited on 2025-10-27 2:54 AM by FBL
Hi everyone,
I’m working with a custom made STM32F446ZET6 board that otherwise functions perfectly (all peripherals, flash programming, etc. work fine). The only thing that doesn’t is the ROM bootloader. I can’t get USB DFU or UART boot to respond no matter what I do.
BOOT0 = 1 (3.3 V) at reset
NRST pulled high, no reset loops
VDDUSB = 3.3 V, decoupled with 100 nF
HSE = Abracon ABLS-8 MHz-12 pF, started with 18 pF load caps and lowered to 10 pF as I saw in a post here this might be the cause
PA9 connected directly to VBUS (5 V)
PA11/PA12 wired to USB-FS D−/D+ (verified routing and continuity)
Board runs normal firmware from Flash with no issues
BOOT0=1, reset → USB never enumerates
Tried UART boot (PA10 RX, PA9 TX, 115200 8E1) → no ACK, completely silent.
Verified with ST-Link under reset:
RDP = 0xAA (no protection)
MEMRMP = 0x0, VTOR = 0x0 → seems like it’s still mapping main Flash, not System Memory.
Jumped to 0x1FFF0000 manually via GDB/OpenOCD:
Program counter at 0x1FFF503C, D+ line goes high, so bootloader code definitely runs.
But USB still doesn’t enumerate.
D+ rises high after the jump (so FS pull-up activates), but host never recognizes the device.
Everything else on the board, including USB device mode under firmware (Marlin/ Klipper) works fine.
What could cause the internal System Memory bootloader not to fully start USB DFU or UART?
Is there any condition (clock, pin, option byte, etc.) that can block the ROM bootloader on F4 from initializing peripherals?
Has anyone seen a case where the bootloader starts (D+ goes high) but host never enumerates?
Any other hardware requirement besides VBUS > 4 V on PA9 and VDDUSB = 3.3 V that could prevent enumeration?
Any insights would be appreciated. I can share schematics or test logs if needed.
Thanks,
Solved! Go to Solution.
2025-10-24 1:04 AM
How is the BOOT1 pin (PB2) configured?
It needs to low to enter the DFU bootloader mode.
2025-10-24 1:04 AM
How is the BOOT1 pin (PB2) configured?
It needs to low to enter the DFU bootloader mode.
2025-10-24 3:31 AM
hello @samprince
I tested Nucleo F446ZE development board (MB1137) by first setting the BOOT0 pin to a high level (3.3 V) and then performing a system reset(reset using the reset button). After the reset, I connected the USB cable to the CN3 connector (USB PORT) and plugged it into my PC.
Under these conditions, the board was detected in DFU mode by STM32CubeProgrammer, and the USB bootloader operated as expected without issues.
Additionally, I verified that the BOOT1 pin is either left floating or tied to ground, which is essential to ensure that the system memory is selected as the boot area when BOOT0 is set high.
This configuration ensures that the MCU boots from the internal system memory (ROM bootloader) rather than from user flash or SRAM.
2025-10-24 6:02 AM - edited 2025-10-24 6:04 AM
You're missing something. Recheck your wiring again. Verify USB cable is not a power-only cable.
Are other bootloader interfaces all quiet? No UART coming into the chip somehow from a different chip or peripheral? Bootloader will answer the first supported interface it sees.
2025-10-24 3:43 PM
Thanks everyone for the replies. I’ve double-checked everything mentioned. BOOT0 is pulled high to 3.3 V and PB2, while i don't have it pulled down, it sits at zero, not floating, I confirmed it by probing during reset. With that setup, resetting the board and connecting either USB or UART1 produces no response at all. The chip just boots silently. I currently have no peripherals attached to the chip (removed all motor drivers, sensors, etc and nothing on uart, spi, or i2c, only just leds and mosfets)
Using CubeIDE and OpenOCD/GDB, I was able to manually force the MCU into the System Memory region by loading SP, PC, and xPSR from 0x1FFF0000. When I do this, the program counter moves into 0x1FFF50xx as expected and USB D+ finally goes high, which tells me the ROM bootloader code is executing and the FS pull-up is being asserted. However, the host still doesn’t enumerate the device, nothing new appears over USB, and CubeProgrammer doesn’t detect DFU. UART1 boot also remains completely silent (no 0x79 ACK at 115200 8E1). Outside of BOOT0 mode the chip works completely fine, USB device firmware enumerates normally, all peripherals function as expected, so the hardware itself is fine.
I’m starting to think something specific is preventing the ROM from fully initializing USB. Could it be related to the VBUS sensing on PA9? I’m feeding it 5 V, should that be lower or indirect? Or maybe the HSE startup time is too slow for the ROM, even though it runs fine in with Marlin and Klipper (8 MHz crystal with 10 pF load caps). I also wonder if there are any timing or voltage conditions that could make the ROM loader assert D+ but stop before enumeration.
At this point, it’s clear the chip isn’t entering ROM mode automatically when BOOT0 is high, it only works when forced manually through GDB, and even then enumeration never completes. Any insight on what could prevent the System Memory bootloader from taking over properly would be really appreciated.
2025-10-24 7:16 PM
PA9 input is not needed by the USB DFU bootloader and I would be wary of putting 5V on there.
If power supervisor isn't handling PDR_ON correctly, that is a problem.
Chip always boots to bootloader on power on if BOOT0=1 and BOOT1=0 at power on.
Could use a USB analyzer or wireshark to see if any packets are being sent. D+ going high means the STM32 did its job (also suggests it's in the bootloader). Up to the computer to try and enumerate. If that fails, device manager will show an error. If you're getting nothing, that's suspect. Power-only cable will do that. Could also be your computer refusing to enumerate.
Even if there is a problem with USB, UART should still answer.
Also, your PA11/PA12 are swapped. PA11 is USB_DM and PA12 is USB_DP. Brings into question how USB is working at all.
2025-10-24 9:00 PM
Thanks for the clarification TDK. I wasn’t aware that the DFU bootloader doesn’t actually depend on PA9 for VBUS sensing. That’s good to know, but I’ve now tried all possible states for PA9 (5 V direct, voltage divider, 3 V, and left unconnected) and none of them changed the outcome. D+ still goes high only when I force the ROM execution manually, but the host never enumerates the device.
Regarding PDR_ON, on my board it’s tied directly to 3.3 V with no capacitor. The power rails and sequencing are otherwise stable, and the MCU runs perfectly fine in normal operation, so I don’t suspect a general power issue, though I’ll add a small cap there in the next revision.
As for the swapped PA11/PA12, yes good eye, I made a mistake in the schematic drawing, so on the board they’re physically crossed to accommodate for my *** up, so the wiring to the USB connector is correct.
I’ll take your advice about checking USB activity. I’ll monitor whether any packets are sent right after D+ goes high. So far, there’s absolutely no enumeration on the host side, which suggests the enumeration sequence never even starts. UART is also completely silent. I’m using a CH340 adapter, and while the adapter itself enumerates fine as a USB-serial device, there’s no response from the STM32 on TX/RX. I’ll try running a serial analyzer on that connection to confirm whether any bytes are coming from the MCU at all.
2025-10-25 4:08 PM
Update:
I ran a full GDB diagnostic while forcing the STM32F446ZET6 into System Memory (ROM bootloader). Below are the register reads captured right after stepping into 0x1FFF503C:
(gdb) x/w 0x40023800 # RCC->CR
0x40023800: 29059
(gdb) x/w 0x40023808 # RCC->CFGR
0x40023808: 0
(gdb) x/w 0x40023804 # RCC->PLLCFGR
0x40023804: 603992080
(gdb) x/w 0x50000038 # OTG_FS_GCCFG
0x50000038: 0
(gdb) x/w 0x50000C00 # OTG_FS_PCGCCTL
0x50000c00: 0
(gdb) x/w 0x50000018 # OTG_FS_GAHBCFG
0x50000018: 0
(gdb) x/w 0x5000001C # OTG_FS_GUSBCFG
0x5000001c: 0
(gdb) x/w 0x50000804 # OTG_FS_DCFG
0x50000804: 0
(gdb) x/w 0x50000000 # OTG_FS_GOTGCTL
0x50000000: 0
(gdb) x/w 0x50000008 # OTG_FS_GRSTCTL
0x50000008: 0
(gdb) x/w 0x40023834 # RCC->AHB2ENR
0x40023834: 0From these results, it’s clear the ROM never enables the USB clock or core. HSE is completely off. HSERDY = 0, HSEON = 0 and the system clock source remains HSI (RCC->CFGR = 0x0).
So even though the MCU runs code from System Memory (PC = 0x1FFF503C), there’s no sign of USB initialization.
Interestingly, every single time I step into the ROM, the D+ line goes high, showing that the FS pull-up is being asserted. But as mentioned before, the host never sees a USB reset or enumeration event.
This matches the register dump: USB isn’t being clocked, likely because the ROM timed out waiting for HSE startup. What confuses me is that UART boot also doesn’t respond (I checked with a serial analyzer, its completely dead) even though USART1 should work on HSI. Could it be that the bootloader attempts USB first, fails because HSE never stabilizes, and then never falls back to UART?
Does this point to the HSE as the issue? I’d like to know what others think before re-spinning my board.
For reference, I’m using an Abracon ABLS-8.000 MHz-12 pF crystal with now 10 pF load caps. The HSE runs perfectly in Marlin and Klipper, so it seems the ROM’s startup timeout is much shorter than application code tolerates.
If this is indeed the culprit, I’d appreciate any recommendations for a faster-starting or more robust crystal that reliably works for USB DFU on STM32F4 for my next revision.
2025-10-27 5:16 PM - edited 2025-10-27 5:17 PM
Credit to @mjuels for pointing me at PB2. On my board it wasn’t enough for PB2 to “sit at 0 V” or be left floating; it MUST be hard-pulled to GND at reset, So I added a 10 kΩ pulldown on PB2. Did a true power-on reset, and the part booted straight into System Memory (ROM). DFU now enumerates normally, and UART boot also responds. And as @TDK mentioned, VBUS sensing is not necessary.
The take away is that, for anyone hitting this: you must strap PB2=LOW permanently with a resistor (floating low is not enough); use BOOT0 to select ROM when needed. This avoids accidentally landing in SRAM boot (BOOT0=1, BOOT1=1) and makes DFU reliable.
thanks again everyone for your valuable input
2025-10-27 6:41 PM
Another update about UART: Turns out the UART bootloader issue was a double whammy.
After fixing PB2, UART still wouldn’t respond, even though the ROM was clearly running. The breakthrough came when I noticed that probing PA9 suddenly made it work. the ACK appeared only while the probe was connected. I'm assuming the probe’s small capacitance was stabilizing the line. So I added a 1 nF cap that permanently fixed it. After that, the UART bootloader started replying correctly to 0x7F with 0x79 (ACK).
So, in short -> PB2 must be tied low, and PA9 may need a tiny capacitor to ground. That fixed both DFU and UART boot modes