Skip to content

feat: preflight the Windows DFU driver before entering DFU mode - #95

Open
boringethan wants to merge 1 commit into
nextfrom
feature/94-dfu-driver-preflight
Open

feat: preflight the Windows DFU driver before entering DFU mode#95
boringethan wants to merge 1 commit into
nextfrom
feature/94-dfu-driver-preflight

Conversation

@boringethan

Copy link
Copy Markdown
Contributor

Refs #94

Why

A field machine failed sensor updates for days with the SDK's "could not tell whether this device has the bootloader installed" halt. Root cause: no WinUSB driver bound to the STM32 DFU device (USB 0483:DF11). The failure only surfaces after the device is already stranded in DFU, and nothing pointed at the driver.

What

Windows records the driver bound to every 0483:DF11 instance it has ever seen under HKLM\SYSTEM\CurrentControlSet\Enum\USB\VID_0483&PID_DF11, and the binding persists across re-enumerations. New dfu_driver.py classifies those bindings, and the two spots about to enter DFU — startConsoleFirmwareUpdate (all console/sensor firmware flashes, release + local) and _start_bootloader_thread (both bootloader installs) — now refuse up front with an actionable "install WinUSB via Zadig" message through the existing error signals when the machine positively cannot flash.

Deliberate scoping:

  • Blocks only on a positively unusable binding — a driverless instance (Device Manager code 28, the field case) or a service dfu-util can't drive (e.g. ST's STTub30).
  • Never-seen passes: a machine with no recorded DFU instance has nothing to verify, and blocking there would break every first flash on a fresh bench PC.
  • Any single usable binding (WinUSB/libusbK/libusb0) clears the machine — the matching INF is in the driver store and future instances bind to it.
  • The check never raises; any registry read failure falls through to today's behavior.
  • No QML changes — errors surface through the existing update-error paths.

Verification

  • 76 app tests pass (9 new in tests/test_dfu_driver.py covering all classification branches).
  • Live on the bench PC: 7 recorded 0483:DF11 instances, all WinUSB, preflight passes — matching the fact that this machine flashes successfully.
  • flake8: no new findings (10 pre-existing in motion_connector.py, unchanged).

🤖 Generated with Claude Code

…94)

A field machine failed sensor updates for days with the SDK's "could not
tell whether this device has the bootloader installed" halt; the cause was
no WinUSB driver bound to the DFU device (0483:DF11), which only surfaced
after the device was already stranded in DFU.

Windows records the driver bound to every DFU device instance it has seen
under HKLM\SYSTEM\CurrentControlSet\Enum\USB\VID_0483&PID_DF11, and the
binding persists across re-enumerations — so the app now checks it at the
two spots that are about to enter DFU (startConsoleFirmwareUpdate and
_start_bootloader_thread) and refuses with an "install WinUSB via Zadig"
message through the existing error signals instead.

Blocks only on a positively unusable binding (driverless instance, or a
service dfu-util can't drive such as ST's STTub30). A machine that has
never enumerated a DFU device has no registry key and passes, so first
flashes on fresh bench PCs are not affected; any single WinUSB/libusbK/
libusb0 binding clears the machine. The check never raises and any
registry failure falls through to the old behavior.

Verified live: this bench PC reports 7 recorded instances, all WinUSB,
preflight passes. 76 app tests pass including 9 new ones.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant