qmk/qmk_firmware

[Bug] RP2040: Firmware fails to boot reliably when USB is powered before PC OS startup

Open

#25.362 aperta il 13 giu 2025

Vedi su GitHub
 (5 commenti) (0 reazioni) (0 assegnatari)C (43.867 fork)batch import
bughelp wanted

Metriche repository

Star
 (20.368 star)
Metriche merge PR
 (Merge medio 20g 9h) (27 PR mergiate in 30 g)

Descrizione

Describe the Bug

🐞 Bug Report: Intermittent Cold Boot Failure on RP2040 (Custom PCB)

Summary

When the keyboard is connected before the PC finishes booting, the firmware sometimes fails to enter the main loop, seemingly restarting repeatedly or halting entirely.
This happens intermittently and leads to the keyboard being non-functional.


✅ Normal Boot Behavior

Firmware proceeds through:

int main(void) {
    platform_setup();
    protocol_setup();
    keyboard_setup();

    protocol_pre_init();
    keyboard_init();
    protocol_post_init(); // ✅ Success

    while (true) {
        ...
    }
}
  • LED turns on briefly and then turns off
  • Keyboard works as expected

❌ Cold Boot Failure

  • keyboard_init() completes successfully
  • Failure occurs during or right after protocol_post_init()
  • Symptoms:
    • LED turns on and remains lit for ~5 seconds, then turns off
    • Keyboard becomes unresponsive
    • Appears to restart or get stuck in early init

GDB Observations

❌ Failing Boot

pc = 0xfffffffe
lr = 0xfffffff1
x/8i $pc → movs r0, r0
x/4xw 0x0 → 0x000000eb

✅ Normal Boot

pc = 0x100062c8
lr = 0x100002f7
x/8i $pc → wfi loop
x/4xw 0x0 → 0x100000eb

Conditions to Reproduce

  • Connect the RP2040-based keyboard to USB before the PC has fully booted
  • USB power is applied early (before OS initialization)
  • If connected after the OS has fully booted, this issue does not occur

Mitigation Attempts

Setting the following startup delay helped significantly:

#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 174 // 8192 / 47 = max 174
  • Cold boot failure rate dropped from ~30% to ~2%

Hardware Notes

  • Custom PCB based on RP2040
  • Circuit is almost identical to Raspberry Pi Pico
  • Crystal oscillator and power circuit confirmed stable

Detection Method

  • LED is turned on during keyboard_post_init_kb()
  • LED is turned off via housekeeping_task_user() after 500ms delay
  • In failure cases, LED stays on longer → helps detect that main loop was not reached

🔗 Source Code and Schematic

All related source code and hardware schematics are available in the following repository:

This directory includes:

  • QMK keymap and keyboard definitions
  • Firmware implementation files such as rules.mk, config.h, keyboard.c
  • Custom RP2040-based PCB schematic

Notes

  • protocol_post_init() calls host_set_driver(vusb_driver()) and waits 50ms
  • May be affected by VBUS/data signal timing during early PC boot stages
  • In failure cases, it seems the firmware resets and re-enters main() again
  • But in rare cases, the firmware halts with pc=0xfffffffe

Request

Please help confirm:

  • Whether this behavior is expected during cold boot with early USB power
  • If this needs to be handled more gracefully in QMK
  • Any recommended method to delay or retry protocol_post_init() safely

Thank you!

Keyboard Used

No response

Link to product page (if applicable)

No response

Operating System

No response

qmk doctor Output

Is AutoHotKey / Karabiner installed

  • AutoHotKey (Windows)
  • Karabiner (macOS)

Other keyboard-related software installed

No response

Additional Context

No response

Guida contributor