qmk/qmk_firmware

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

Open

#25.362 aberto em 13 de jun. de 2025

Ver no GitHub
 (5 comments) (0 reactions) (0 assignees)C (43.867 forks)batch import
bughelp wanted

Métricas do repositório

Stars
 (20.368 stars)
Métricas de merge de PR
 (Mesclagem média 20d 9h) (27 fundiu PRs em 30d)

Description

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

Guia do colaborador