tinyusb: Adafruit Feather M0 Express - A request for the USB device descriptor failed.

Describe the bug

Adafruit Feather M0 Express fails to enumerate and initialize as a valid USB device when a (potentially*) misbehaving other USB device is also plugged in concurrently to the same external hub. This issue opened in this repo after a long and winding tweet thread ended with @tannewt suggesting I open an issue here.

(*) I have no proof that the other device (a fomu in this case) is actually misbehaving, although @smunaut did make a comment about having seen “people taking quite a few non-compliant shortcuts with USB implementations” and admittedly the fomu is not an ordinary device. 😉

Both the fomu and Feather M0 are completely happy and operational when not plugged into the same external hub.

Set up (please complete the following information):

  • OS: Windows 10 1909 [Version 10.0.18363.657]

  • Board: Adafruit Feature M0 Express

  • Firmware Code: TBD

  • Board: fomu with Fomu DFU Bootloader v1.8.7

  • Firmware Code: TBD

To Reproduce

Steps to reproduce the behavior:

  1. Plug a fomu - hacker version into an Amazon Basics USB hub. Note is a fully functional fomu, that has no apparent problems of its own.

  2. (optional) Being so tiny, perhaps even forget that the fomu is plugged into the other side of the hub. This adds so much fun to the mystery. I initially thought the problem was hub-specific, until I later noticed the fomu tucked into place on the other side. I later confirmed this problem also occurs on a completely different hub, such as the ICZI USB 3.0

  3. Plug in the Adafruit M0. into the same USB hub.

  4. Note that Windows complains that:

           USB Device Not Recognized
           The last USB device you connected
           to this computer malfunctioned, and
           Windows does not recognize it 
  1. It should be noted that other USB devices, such as a mouse and Saleae logic analyzer capturing at full speed are otherwise operational and fully functional when following these steps and plugged into the same hub.

Expected behavior

I would have expected the Feather M0 to work properly, even if the fomu was misbehaving*

Screenshots

The fomu in place: image

Device Manager:

image

Wireshark: image

Additional context

I started down this path with the desire to get my ULX3S working with Circuit Python. I have a (not yet published) blog with those details, but in the meantime I have some files that may be helpful.

I also have a pair of USB breakout boards to capture the initialization with my Saleae logic analyzer, per a suggestion from @smunaut if anyone would like to look.

cc: @PaulStoffregen

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 18 (7 by maintainers)

Most upvoted comments

As I mentioned on twitter, that fomu bitstream version has a known bug where it doesn’t check the address field of USB packets and just responds to all of them. That bug is fixed in newer version of the bitstream.

That is known to cause issues for other devices on the same hub and AFAIK there is nothing the other devices can do about it if some other device answers requests that are not meant for them …

Another possible (blind guess) explanation could involve a race condition involving the time each device takes to begin its response, especially if the hub has a single transaction translator. When connected to a hub, low and full speed devices don’t communicate directly with the host. They talk to the the hub’s TT, which slowly retransmits the split-start packet it received from the host at 480 Mbit/sec, then waits for a device to slowly respond, which the host later reads at 480 speed with split-complete. If 2 devices respond, very likely the 1st to begin its response triggers logic inside the TT to receive only from that port.

While a mouse is almost certainly a low speed device, it is probably made from dedicated hardware which has no software overhead involved in its response time.

High speed 480 Mbit/sec devices are handled without a TT. A special chirp sequence during the reset time is used to detect whether high speed is connected on that port. High speed communication is routed only to downstream ports which responded to the chirp, avoiding any conflict with full and low speed devices which are serviced by the transaction translator(s) on the ports which didn’t chirp.