adafruit / adafruit/Adafruit_TinyUSB_Arduino

[Bug] Continuous Bus Resets when enumerating as HID Keyboard on RP2040 with specific devices

Open
#574 0 comments 0 reactions 0 assignees View on GitHub
Bug
Dominant language
C
Stars
654
Forks
183
PR merge metrics
No merged PRs in 30d

Description

### Operating System

Others

### Arduino IDE version

Arduino 2.3.4

### Board

Waveshare RP2040 zero

### ArduinoCore version

Rasberry Pico 5.0.0

### TinyUSB Library version

3.7.2

### Sketch as ATTACHED TXT

#define CFG_TUSB_DEBUG 2

#include "Adafruit_TinyUSB.h"

uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD()
};

Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report),
HID_ITF_PROTOCOL_KEYBOARD, 2, false);

void setup() {

TinyUSBDevice.setID(0x04D9, 0x0024);
TinyUSBDevice.addInterface(usb_hid);
TinyUSBDevice.begin();
usb_hid.begin();

unsigned long start = millis();
while (!TinyUSBDevice.mounted() && millis() - start < 8000) {
yield();
}

Serial1.begin(115200);
Serial1.println(TinyUSBDevice.mounted() ? "MOUNTED" : "TIMEOUT");
}

void loop() {

}

### Compiled Log as ATTACHED TXT

[log github.txt](https://github.com/user-attachments/files/26647355/log.github.txt)

### What happened ?

When using Adafruit_USBD_HID configured as a Boot Protocol Keyboard on RP2040, the device enters an infinite Bus Reset loop when connected to certain USB hosts. The device rarely completes enumeration and TinyUSBDevice.mounted() almost never returns true.
The issue occurs with the Sound Devices PixE5 but not with the Sound Devices PIX240, which is another recorder from the same manufacturer. The device also works fine when connected to a standard PC.

### How to reproduce ?

1 - Configure Adafruit_USBD_HID as a keyboard with Boot Protocol:

Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 10, false);

2 - Connect RP2040 to a Sound Devices PixE5 via USB
3 - Observe Serial logs

----------------

**Expected behavior**
Device enumerates successfully, tud_mount_cb() is called, TinyUSBDevice.mounted() returns true.

**Actual behavior**
Infinite Bus Reset loop, enumeration almost never completes. Occasionally (~1 out of 10 attempts) the device does enumerate successfully, suggesting a timing or race condition rather than a hard incompatibility:

USBD init on controller 0, speed = Full
USBD Bus Reset : Full Speed
USBD Bus Reset : Full Speed
USBD Bus Reset : Full Speed
USBD Bus Reset : Full Speed
...
No GET_DESCRIPTOR request is ever processed.

**What I have already tried**

Reducing CFG_TUD_ENDPOINT0_SIZE from 64 to 8 → no effect
Simplifying the HID report descriptor to a minimal boot keyboard → no effect
The device works perfectly when connected to a Windows/macOS PC
The device works perfectly when connected to a Sound Devices PIX240 (same manufacturer, older model)

**Reproducibility**
This bug is difficult to reproduce without access to a Sound Devices PixE5. This is a professional piece of equipment used in film and television production. I am happy to run any diagnostic code or provide additional logs if needed !

The fact that enumeration occasionally succeeds suggests a timing or race condition during the enumeration phase, possibly related to how the RP2040 handles the first GET_DESCRIPTOR request after a Bus Reset.
A USB analyzer log is available if needed.

### Debug Log as ATTACHED TXT

_No response_

### Screenshots

Here are the TinyUSBLog (#define CFG_TUSB_DEBUG 2) : Image

### I have checked existing issues, pr, discussion and documentation

- [x] I confirm I have checked existing issues, pr, discussion and documentation.

Contributor guide

No contributing guide indexed for this repository

Research direction

Begin with the supplied HID keyboard sketch and CFG_TUSB_DEBUG 2 log; trace enumeration around TinyUSBDevice.begin(), usb_hid.begin(), tud_mount_cb(), and the first GET_DESCRIPTOR after bus reset. Reproduce against a PixE5 if available and use the existing log or USB analyzer data; done means enumeration completes, tud_mount_cb() runs, and TinyUSBDevice.mounted() returns true.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, cpp
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.