qmk / qmk_firmware

Open-source keyboard firmware for Atmel AVR and Arm USB families
https://qmk.fm
GNU General Public License v2.0
18.09k stars 38.89k forks source link

[Bug] RP2040 keyboard can't work on Thinkpad T420, T440 #19593

Open moyi4681 opened 1 year ago

moyi4681 commented 1 year ago

Describe the Bug

hardware:pico raspberry firmware: handwired/onekey/rp2040 reboot or boot from shutdown ,can't recognize the keyboard.

Keyboard Used

handwiared/onekey/rp2040

Link to product page (if applicable)

No response

Operating System

windows11

qmk doctor Output

QMK Doctor is checking your environment.
Ψ CLI version: 1.1.0
Ψ QMK home: /home/dztech/桌面/1_9/qmk_firmware
Ψ Detected Linux.
Ψ Git branch: master
Ψ Repo version: 0.19.6
⚠ Git has unstashed/uncommitted changes.
⚠ The official repository does not seem to be configured as git remote "upstream".
Ψ All dependencies are installed.
Ψ Found arm-none-eabi-gcc version 9.2.1
Ψ Found avr-gcc version 5.4.0
Ψ Found avrdude version 6.3-20171130
Ψ Found dfu-util version 0.9
Ψ Found dfu-programmer version 0.6.1
Ψ Submodules are up to date.
Ψ Submodule status:
Ψ - lib/chibios: 2022-09-18 10:01:17 +0000 --  (0e9d558b5)
Ψ - lib/chibios-contrib: 2022-10-03 18:09:41 +0200 --  (bb8356fb)
Ψ - lib/googletest: 2021-06-11 06:37:43 -0700 --  (e2239ee6)
Ψ - lib/lufa: 2022-08-26 12:09:55 +1000 --  (549b97320)
Ψ - lib/pico-sdk: 2022-09-19 18:02:44 +0200 --  (8d56ea3)
Ψ - lib/printf: 2022-06-29 23:59:58 +0300 --  (c2e3b4e)
Ψ - lib/vusb: 2022-06-13 09:18:17 +1000 --  (819dbc1)
Ψ QMK is ready to go, but minor problems were found

Is AutoHotKey / Karabiner installed

Other keyboard-related software installed

No response

Additional Context

No response

moyi4681 commented 1 year ago

also tested with other rp2040 keyboard, same issue,also can't recognize on BIOS mode

Jpe230 commented 1 year ago

Exactly what I'm experiencing but with newers ThinkPads (E14 and E15), the keyboards work fine with my Desktop PC (Intel + Asus MoBo), my Macs (Intel or M1) and my personal laptops from other vendors.

KarlK90 commented 1 year ago

I guess I have to bring out my USB analyzer once more.

Jpe230 commented 1 year ago

Worth mentioning that I have tried enabling and disabling NO_USB_STARTUP_CHECK, the board works fine when hotplugging once a OS is running but the moment it enters to the bios or boot menu the board hangs, only way to fix it is by physically resetting the board, trying to reboot the board with a keycode doesn't work.

With my MacBooks, the keyboard momentarily hangs (the RGB and OLED animations stop) but once macOS has booted it works just fine.

pylbrecht commented 1 year ago

I'm having this exact issue with my Scylla with a Splinky v3.

Tested with a onekey firmware on a T480 (Arch Linux) and a P14s G2 (Windows 11). On both not detected on boot. No issue on Mac: it is detected after boot.

ntzm commented 1 year ago

I also experience this on a Thinkpad X1 9th gen

sunaku commented 1 year ago

I have the same problem on a Thinkpad T14 Gen 2 (AMD) laptop. See also https://github.com/qmk/qmk_firmware/issues/18511#issuecomment-1480701851

sarunas-stasaitis commented 1 year ago

Same problem on Tkinkpad L16 Gen2 (AMD)

angaz commented 1 year ago

IDK how useful this will be, but I have a Keychron K1 which has exactly the same kind of problem as my Pi Pico. It's also got an ARM MCU: SN32F248BF. I am using the https://github.com/SonixQMK/qmk_firmware fork on the K1, but since the problem is the same, I guess it's got nothing to do with the fork.

It is seemingly unrecognized by my Thinkpad until I reconnect the power. An interesting difference is that it seems the K1 goes into some kind of reset loop with the backlight flashing and nothing works until I reset the power.

YCF commented 1 year ago

Same problem on Thinkpad t480s.

george-norton commented 1 year ago

A while ago @KarlK90 talked me through collecting some info from a Pico hooked up to GDB through the SWD interface, but the results are buried on a discord server. Here are the results:

(gdb) p/x $lr
$1 = 0x100002cb
(gdb) p/x $lr&(1<<2)
$2 = 0x0
(gdb) p/a *(uint32_t[8] *)$msp
$3 = {0x2000263c <USBD1>, 0x1, 0xc4007a, 0x20002648 <USBD1+12>, 0x4001c000, 0x1000aa59 <usbDisableEndpointsI+98>, 0x1000c1f6 <usb_lld_disable_endpoints+18>, 0x41000015}

700    void usb_lld_disable_endpoints(USBDriver *usbp) {
   0x1000c1e4 <+0>:    push    {r4, r5, r6, lr}

701      /* Ignore zero */
702      for (uint8_t ep = 1; ep <= USB_ENDOPOINTS_NUMBER; ep++) {
   0x1000c1e6 <+2>:    movs    r1, #1
   0x1000c1e8 <+4>:    b.n    0x1000c232 <usb_lld_disable_endpoints+78>

703        usbp->epc[ep]->in_state->active = false;
   0x1000c1ea <+6>:    adds    r3, r1, #2
   0x1000c1ec <+8>:    lsls    r3, r3, #2
   0x1000c1ee <+10>:    adds    r3, r0, r3
   0x1000c1f0 <+12>:    ldr    r2, [r3, #4]
   0x1000c1f2 <+14>:    ldr    r2, [r2, #20]
   0x1000c1f4 <+16>:    movs    r5, #0
   **0x1000c1f6 <+18>:    strb    r5, [r2, #20]**

704        usbp->epc[ep]->in_state->stalled = false;
   0x1000c1f8 <+20>:    ldr    r2, [r3, #4]
   0x1000c1fa <+22>:    ldr    r2, [r2, #20]
   0x1000c1fc <+24>:    strb    r5, [r2, #21]

info reg
r0             0x2000263c    536880700
r1             0x1    1
r2             0xc4007a    12845178
r3             0x20002648    536880712
r4             0x10    16
r5             0x0    0
r6             0xfffffffd    4294967293
r7             0x20040b88    537136008
r8             0xffffffff    4294967295
r9             0x1    1
r10            0xffffffff    4294967295
r11            0xffffffff    4294967295
r12            0x4001c000    1073856512
sp             0x20040388    0x20040388
lr             0x100002cb    268436171
pc             0x100002ca    0x100002ca <_unhandled_exception>
cpsr           0x41000003    1090519043

p USBD1
$2 = {state = USB_ACTIVE, config = 0x1000e6e8 <usbcfg>, transmitting = 0, receiving = 0, epc = {0x1000eb54 <ep0config>, 0x0 <repeats 15 times>}, in_params = {
    0x0 <repeats 15 times>}, out_params = {0x0 <repeats 15 times>}, ep0state = USB_EP0_STP_WAITING, ep0next = 0x0, ep0n = 0, ep0endcb = 0x0, setup = "\000\t\001\000\000\000\000", 
  status = 0, address = 1 '\001', configuration = 1 '\001', saved_state = USB_READY, noffset = 256}

So it looks to me like the epc array is not initialized, only EP0 is present. But usb_lld_disable_endpoints is looping over the Endpoints starting at 1 and it takes an exception setting endpoint 1's active flag to false.

thomasbaart commented 1 year ago

One customer reported having the same issue while using a Liatris microcontroller, which is also on RP2040. I have no diagnostics on it yet as I'm unable to reproduce it myself (don't have the requisite hardware nor tools), so I'm just adding this data point.

KarlK90 commented 1 year ago

Alright, the reason for this hardfault (thanks @george-norton!) is pretty clear. And I've posted a fix in this PR https://github.com/ChibiOS/ChibiOS-Contrib/pull/375 along with an explanation. Please test if this fixes your problems.

KarlK90 commented 1 year ago

QMK already picked up these changes in the develop branch, so testing is even easier. Just switch/rebase/pull to this branch and update the submodules qmk git-submodule and a fresh compile has the latest fixes.

angaz commented 1 year ago

@KarlK90 I can confirm, my keyboard works now in the BIOS. Seems like it's working now as expected. Thanks! Would you be able to update us when it gets merged into master? How would I follow that?

george-norton commented 1 year ago

@KarlK90 I stuck a build on my Kyria with KB2040`s and I am seeing a little oddness, but I am not sure it is related. Overall, the behavior seems better.

Previously when booting the laptop the OLED would begin redrawing then then just hang as the keyboard took a fault.

Now the keyboard does not hang, the OLED draws correctly, the OLED state updates as expected when pressing modifier keys, but I cannot use the keyboard to enter my bitlocker password or access the BIOS. It doesn't seem to receive any keypresses, resetting/replugging the keyboard also doesn't fix it. Once windows is booted, they keyboard works normally. This might be some weirdness due to the lack of VBUS detection (I am using SPLIT_USB_DETECT).

KarlK90 commented 1 year ago

@KarlK90 I can confirm, my keyboard works now in the BIOS. Seems like it's working now as expected. Thanks! Would you be able to update us when it gets merged into master? How would I follow that?

Next breaking changes merge from develop to master is on 27th of August. QMK usually announces this on the official Discord and the OLKB reddit. Other information can be found here https://github.com/qmk/qmk_firmware/blob/master/docs/breaking_changes.md

KarlK90 commented 1 year ago

@george-norton that is at least some progress. It might be that bitlocker isn't compatible with nkro if you have forced this to be active. For split detection I also recommend switching to the watchdog implementation for connection detection, either by defining SPLIT_WATCHDOG_ENABLE in config.h or setting split.transport.watchdog to true in your info.json

pylbrecht commented 1 year ago

QMK already picked up these changes in the develop branch, so testing is even easier. Just switch/rebase/pull to this branch and update the submodules qmk git-submodule and a fresh compile has the latest fixes.

Can confirm that this fixes the issue on my Thinkpad X1 Carbon. Thanks a ton @KarlK90!

Vivero commented 12 months ago

QMK already picked up these changes in the develop branch, so testing is even easier. Just switch/rebase/pull to this branch and update the submodules qmk git-submodule and a fresh compile has the latest fixes.

Thanks so much for this, also confirming here that this fixes the issue with my ThinkPad P14s. I have a KBDFans TET keyboard that wouldn't work on bootup (at the bitlocker screen), and would also become unresponsive after waking the laptop from sleep.

kwmlodozeniec commented 8 months ago

Same issue with ThinkPad P15 Gen 1 running Linux. After reboot or sleep I need to reset the board for it to work.

juru1234 commented 6 months ago

Same issue with ThinkPad P15 Gen 1 running Linux. After reboot or sleep I need to reset the board for it to work.

Same here with ThinkPad T15 and a with a Lenovo ThinkCentre M720 Tiny. Tried the develop branch but it doesn't fix the problem for me.

qhga commented 5 months ago

I got the same / a similar issue with my own handwired build. I previously used elite-c controllers for my build but made a new revision with a rp2040 based controller (Pro Micro RP2040). I do not use SPLIT_USB_DETECT but rather EE_HANDS with the respective flashing commands make snappy/rev3_5:default:uf2-split-left (and right). The keyboard works fine when connected to my computer after it has already booted into GNU/Linux (NixOS). I can conneced and disconnect it as many times without any problems. The problem only happens with the following steps:

  1. I shutdown my computer
  2. The keyboard stays connected via USB-A to USB-C Cable (USB power delivery is not enabled)
  3. I power up my computer with the keyboard connected

Now the keyboard behaves the same as if I would connect it to a power bank or USB charger. The OLED displays on both halves render the logo as if they were the "secondary" half (Logo displayed centered).

Similarly, this happens with my Lenovo T480 laptop.

Additionally, when I unplug the keyboard and reconnect it, sometimes it does not work and the main half seems to boot nothing (OLED does not display anything, second half shows logo centered, input via keyboard is not possible). If I repeat the unplug and reconnect, everything starts to work as intended.

When I unplug/reconnect the keyboard, it starts working and I can use it to get into the BIOS, navigate the BIOS or the bootloader and use it as normal after a successful boot.

This also does not happen on reboots (with the reboot command under linux). At least during my testing.

The older revision with the elite-c does not have this issue. I tested the same scenarios with both connected simultaneously and the elite-c version worked as expected.

Any help would be very appreciated. I can provide further information. Show the schematics. Hop onto a discord/mumble/jitsi call, etc. @KarlK90?

Thanks in advance.

johannesneyer commented 5 months ago

I do not use SPLIT_USB_DETECT but rather EE_HANDS with the respective flashing commands make snappy/rev3_5:default:uf2-split-left (and right). The keyboard works fine when connected to my computer after it has already booted into GNU/Linux (NixOS). I can conneced and disconnect it as many times without any problems. The problem only happens with the following steps:

1. I shutdown my computer

2. The keyboard stays connected via USB-A to USB-C Cable (USB power delivery is **not** enabled)

3. I power up my computer with the keyboard connected

I have the exact same issue with my RP2040-zero based custom split. It seems to be related to split keyboards as this problem is fixed when I set split.enabled to false in my info.json (but then only one half works of course...).

lesshonor commented 5 months ago

I do not use SPLIT_USB_DETECT

Yes, you do:

Because it is common that ARM boards lack VBUS detection, SPLIT_USB_DETECT is automatically defined on ARM targets (technically when ChibiOS is targetted).

RP2040 is an ARM target.

To hopefully clarify, SPLIT_USB_DETECT and EE_HANDS are not alternatives to one another. The former is used to determine which half is plugged into the host—this is the "master" half—and the latter is used to determine which half is left—a.k.a. handedness.

The symptoms you describe with the OLEDs indicate your keyboard cannot figure out which half is master, which may be solvable in firmware by setting SPLIT_WATCHDOG_ENABLE and/or increasing SPLIT_USB_TIMEOUT.

Another option would be to modify the hardware so you can set a VBUS pin. The easiest way to accomplish this would be to replace your Sparkfun dev boards with alternatives which already incorporate this feature, i.e. those which utilize the Community Edition pinout.

Long story short: neither of your problems with splits are related to the hardfault uncovered by this issue (and subsequently patched).

qhga commented 5 months ago

I do not use SPLIT_USB_DETECT

Yes, you do:

Because it is common that ARM boards lack VBUS detection, SPLIT_USB_DETECT is automatically defined on ARM targets (technically when ChibiOS is targetted).

RP2040 is an ARM target.

To hopefully clarify, SPLIT_USB_DETECT and EE_HANDS are not alternatives to one another. The former is used to determine which half is plugged into the host—this is the "master" half—and the latter is used to determine which half is left—a.k.a. handedness.

The symptoms you describe with the OLEDs indicate your keyboard cannot figure out which half is master, which may be solvable in firmware by setting SPLIT_WATCHDOG_ENABLE and/or increasing SPLIT_USB_TIMEOUT.

Another option would be to modify the hardware so you can set a VBUS pin. The easiest way to accomplish this would be to replace your Sparkfun dev boards with alternatives which already incorporate this feature, i.e. those which utilize the Community Edition pinout.

Long story short: neither of your problems with splits are related to the hardfault uncovered by this issue (and subsequently patched).

Thanks for the quick reply. After reading some issues I thought I "disable" it by using #undef SPLIT_USB_DETECT to make sure this is not the culprit, but this seems to be not the case. I'll read through the docs you provided and report back.

The next build will be with two of the liatris boards I got. If this resolves the issue, even better.

qhga commented 5 months ago

The symptoms you describe with the OLEDs indicate your keyboard cannot figure out which half is master, which may be solvable in firmware by setting SPLIT_WATCHDOG_ENABLE and/or increasing SPLIT_USB_TIMEOUT.

I can confirm that the SPLIT_WATCHDOG_ENABLE option worked like a charm! Thanks again for the super quick answer!!!

Note: For future readers, make sure to flash the firmware with the watchdog option onto both halves. Otherwise it won't work correctly, till it is running on both halves. (So make sure to have a reset option for both individual halves)

johannesneyer commented 5 months ago

Oh great, SPLIT_WATCHDOG_ENABLE works. I have been plugging my keyboard out and back in again for about a year now...

kwmlodozeniec commented 5 months ago

I use SPLIT_WATCHDOG_ENABLE and still get the issue of the keyboard needing a reset after laptop wakes up from sleep.

juru1234 commented 5 months ago

My solution was switching to KMK instead of using QMK. But I hope this will be fixed soon.

KarlK90 commented 5 months ago

I use SPLIT_WATCHDOG_ENABLE and still get the issue of the keyboard needing a reset after laptop wakes up from sleep.

@kwmlodozeniec @juru1234

If you are not using the current develop branch, please try it out as PR https://github.com/qmk/qmk_firmware/pull/21656 was merged and revamps the USB handling of ARM based boards - intended to fix issues with resume from suspend among others.

KarlK90 commented 5 months ago

@juru1234 @kwmlodozeniec pinging again as I'm not sure if pings added in edits are propagated.

kwmlodozeniec commented 5 months ago

@KarlK90 I have since switched to using Vial, which also has this issue, and no longer have a lenovo laptop to even test it out.

juru1234 commented 4 months ago

@KarlK90 I tried it again with the current master (I think your patches are merged now) and the problem still exists on my ThinkPad T15 Gen2. I'm not able to to enter my LUKS password when booting. I have to unplug the keyboard and plug it in again to enter the password. I would love to switch back from KMK to QMK.....

KarlK90 commented 4 months ago

@juru1234 Do you happen to use a split keyboard? If so please try enabling the split watchdog feature (don't forget to flash both sides).

juru1234 commented 4 months ago

@KarlK90 Yes, I'm using a Corne v3 Split Keyboard with RP2040. I use the default layout and defined SPLIT_WATCHDOG_ENABLE in keyboards/crkbd/keymaps/default/config.h. Flashed it on both sides and I still have the same problem with a T460 with Windows and a T15 with Linux. Never had any other USB issues with Lenovo hardware and KMK works...