Electronics Design AU
STM32TestingCommunicationsSolved

STM32 USB not detected by Windows after jumping to bootloader mode

3 min read2 replies
Original Question

Asked by stale_biscuit_03 ·

Working on a custom STM32F411 board, trying to jump into the built-in USB DFU bootloader from application code instead of holding BOOT0 on power-up. I'm doing the usual: disable interrupts, deinit any peripherals I've touched, set the stack pointer to the value at 0x1FFF0000, then jump to the reset vector at 0x1FFF0004.

It resets fine — no crash, no hang — but Windows Device Manager never shows a new DFU device. Same board works perfectly if I hold BOOT0 high and power-cycle manually, DfuSe sees it instantly. So the bootloader itself is clearly fine, it's something about the jump from application code specifically.

Tried a different USB cable and a different PC already, same result both times.

From the knowledge baseHow Do You Use the STM32 DFU Bootloader to Flash Firmware?

2 Replies

soggy_waffle42
Accepted Answer

Classic symptom, and it's almost never the jump code itself — it's leftover peripheral state. The system bootloader assumes it's starting from a clean reset, but a software jump doesn't reset peripheral registers, NVIC state, or clock configuration the way a real power-on or NRST reset does.

Two things to check, in order:

  1. Clock configuration. If you'd already cranked the PLL up for your application (anything other than the default HSI), the bootloader's USB stack may be running off a clock configuration it never expects. Reset RCC back to its default state before jumping — RCC->CR, RCC->CFGR, etc. — not just disabling peripherals.
  2. SysTick and any active interrupts. Make sure SysTick is disabled and all NVIC interrupt enables are cleared before the jump. A leftover SysTick interrupt firing into a vector table that hasn't been remapped yet will silently wedge the USB stack before it ever enumerates.

ST's AN2606 covers the exact boot mode entry conditions if you want the reference, but in practice "reset RCC to defaults, disable SysTick, clear NVIC, then jump" fixes this 90% of the time. If it's still not enumerating after that, scope D+/D- right after the jump — if you don't see anything at all, the jump itself isn't reaching the bootloader's USB init. For a broader explanation of how embedded bootloaders work and how they decide whether to enter update mode, our bootloader overview is a useful starting point.

Separate but related: if you ever see this same board reset on its own with no jump involved, don't assume it's the same bug — go read the reset-cause flag first, our breakdown of why STM32 boards reset unexpectedly covers exactly which register to check.

whateverlol88

Adding a verification step since "it resets fine" can be misleading here — a clean reset and a bootloader that's actually alive are two different things to confirm separately:

  1. After the jump, check the reset cause register is what you expect (it won't show a real reset cause if you jumped without using NVIC_SystemReset(), which is itself useful information).
  2. Confirm with a logic analyzer or scope that D+ goes high within the expected window — that's the bootloader signalling device-present, independent of whether Windows ever shows it.
  3. Only after both of those check out should you treat a missing Device Manager entry as a USB enumeration problem rather than a "did we actually reach the bootloader" problem.

In my experience this kind of bug report is usually two bugs stacked — the jump partially works, then enumeration fails for the separate reason already covered above. Worth ruling each one out independently rather than assuming it's a single root cause.

Related Discussions