Skip to content

fix(usb): add suspend-timeout fallback for boards without VBUS detect#3375

Open
paoloantinori wants to merge 1 commit into
zmkfirmware:mainfrom
paoloantinori:fix/usb-suspend-disconnect
Open

fix(usb): add suspend-timeout fallback for boards without VBUS detect#3375
paoloantinori wants to merge 1 commit into
zmkfirmware:mainfrom
paoloantinori:fix/usb-suspend-disconnect

Conversation

@paoloantinori

Copy link
Copy Markdown

Issue

Closes #3374

Problem

On boards without VBUS detection (e.g. nRF52840-based Corne-ish Zen), unplugging the USB cable causes the USB peripheral to report USB_DC_SUSPEND instead of USB_DC_DISCONNECTED. ZMK maps USB_DC_SUSPEND to ZMK_USB_CONN_HID, so the endpoint stays on USB and never falls back to BLE. The display keeps showing the USB icon indefinitely.

This is related to #841 (USB power-only cable detected as host), which was fixed by PR #2458. That fix addressed power-without-data cables; this one covers cable-removed-entirely.

Solution

Add CONFIG_ZMK_USB_SUSPEND_DISCONNECT_TIMEOUT_MS (int, default 0 = disabled). When non-zero, a one-shot k_timer is started on USB_DC_SUSPEND. If no USB_DC_RESUME arrives before the timer expires, the status is overridden to USB_DC_DISCONNECTED, which triggers the normal BLE endpoint fallback.

Default is 0 so existing boards are unaffected. Boards that lack VBUS detection can opt in by setting a non-zero timeout in their Kconfig.defconfig.

The Corne-ish Zen enables this with a 2-second timeout.

Testing

Tested on real Corne-ish Zen hardware:

  • Plug USB -> display shows USB icon
  • Unplug USB -> display switches to BT icon within ~2 seconds
  • Plug USB back in -> display returns to USB icon

The keyboard config used for testing is at https://github.com/paoloantinori/zmk-config-zen-2

Trade-offs

Without VBUS detection there is no way to distinguish cable unplug from host suspend in software. After the timeout, both cases fall back to BLE. For a wireless keyboard this is reasonable behavior -- the user may want to type on another device while the host is suspended.

Checklist

  • Clean commit history
  • Copyright + License headers preserved (no new files)
  • Pre-commit checks pass (clang-format, gitlint, prettier)

On boards without VBUS detection (e.g. nRF52840-based Corne-ish Zen),
unplugging the USB cable causes the USB peripheral to report
USB_DC_SUSPEND instead of USB_DC_DISCONNECTED. ZMK maps SUSPEND to
ZMK_USB_CONN_HID, so the endpoint stays on USB and never falls back
to BLE.

Add CONFIG_ZMK_USB_SUSPEND_DISCONNECT_TIMEOUT_MS (default 0,
disabled). When non-zero, a one-shot k_timer is started on
USB_DC_SUSPEND; if the bus has not resumed when the timer expires the
status is overridden to USB_DC_DISCONNECTED, which triggers the normal
endpoint switch to BLE.

Enable the workaround for the Corne-ish Zen with a 2-second timeout.

Closes zmkfirmware#3374

Tested on Corne-ish Zen hardware:
- Plug USB -> display shows USB icon
- Unplug USB -> display switches to BT icon within ~2 seconds
- Plug USB back in -> display returns to USB icon

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@paoloantinori paoloantinori requested a review from a team as a code owner June 3, 2026 16:20
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.

BUG: USB icon stuck after cable disconnect on boards without VBUS detection

1 participant