Skip to content

Comments

Fix USB VCP lockup on disconnect (issue #11348)#11351

Open
daijoubu wants to merge 6 commits intoiNavFlight:maintenance-9.xfrom
daijoubu:fix-usb-vcp-blocking
Open

Fix USB VCP lockup on disconnect (issue #11348)#11351
daijoubu wants to merge 6 commits intoiNavFlight:maintenance-9.xfrom
daijoubu:fix-usb-vcp-blocking

Conversation

@daijoubu
Copy link
Contributor

@daijoubu daijoubu commented Feb 21, 2026

Summary

Fixes #11348 - Flight controller freeze on USB disconnect while MSP is active.

6 crashes reported by user on MATEK F405 Wing V2 when disconnecting Configurator with LOG_DEBUG enabled.

Root Cause

USB VCP disconnection was not detected properly, causing:

  • Infinite loops waiting for TX buffer to drain
  • MSP logging to dead port
  • Complete FC freeze (watchdog recovery ~5s)

Changes

  • STM32F4: Fix USB VCP lockup on disconnect
  • STM32F7/H7: Fix USB VCP lockup on disconnect
  • Fix CDC_Send_FreeBytes buffer calculation (STM32F4)
  • Add DTR tracking for connection detection
  • Add suspend detection as disconnect fallback
  • Fix DTR tracking default - assume connected initially

Testing

Tested on SPEEDYBEEF405WING (STM32F4) - rapid USB connect/disconnect no longer causes freeze.

Files Changed

  • src/main/drivers/serial.c - FIX 1: serialIsConnected() return statement
  • src/main/drivers/serial_usb_vcp.c - DTR tracking
  • src/main/vcp_hal/usbd_cdc_interface.c - STM32F7/H7 fixes
  • src/main/vcpf4/usbd_cdc_vcp.c - STM32F4 fixes
  • src/main/vcpf4/usbd_usr.c - suspend detection

daijoubu and others added 6 commits February 20, 2026 21:45
Two issues fixed:

1. serial.c: serialIsConnected() was not returning the result from
   the vtable isConnected call, always returning true regardless of
   actual connection state.

2. vcpf4/usbd_cdc_vcp.c: VCP_DataTx() had infinite loops waiting for
   TX state and buffer space. If USB was disconnected, these loops
   would never exit, locking up the flight controller.

   Added 50ms timeout to both blocking loops. On timeout, returns
   USBD_FAIL and CDC_Send_DATA returns 0 to indicate failure.

Tested on SPEEDYBEEF405WING - FC continues operating normally after
USB disconnect instead of locking up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Same fix as STM32F4: added 50ms timeout to blocking loops in
CDC_Send_DATA() that wait for TX state and buffer space.

On timeout, returns partial byte count (or 0) instead of blocking
forever when USB is disconnected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous implementation incorrectly subtracted RX buffer usage
from TX buffer size. Fixed to properly calculate free space in the
outbound (APP_Rx) circular buffer using the correct pointer math.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Register callback for CDC control line state changes to track when
the host has actually opened the COM port (DTR signal). This provides
more reliable connection detection than just checking USB enumeration
state.

usbVcpIsConnected() now returns true only when:
- USB is connected (hardware)
- USB is configured (enumerated)
- Host has opened COM port (DTR high)

This helps prevent writes to USB when no host application is listening,
which can cause buffer buildup and delays.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On boards without VBUS sensing, USB hardware disconnect may not be
detected. Treat USB suspend event as a disconnect to prevent blocking
on writes when cable is unplugged.

When suspend occurs, set bDeviceState = UNCONNECTED so that
usbIsConnected() returns false and writes are skipped.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Default cdcPortOpened to true so MSP works immediately on connection.
DTR state will be updated when host explicitly sets/clears it.

Previous default of false broke MSP on tools that don't assert DTR.

Co-Authored-By: Claude Opus 4.6 <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