hathach / tinyusb

An open source cross-platform USB stack for embedded system
https://www.tinyusb.org
MIT License
4.67k stars 997 forks source link

HID host issues with RetroFlag Classic USB Gamepad #2163

Open Daft-Freak opened 11 months ago

Daft-Freak commented 11 months ago

Operating System

Linux

Board

Raspberry Pi Pico

Firmware

examples/host/cdc_msc_hid

(With an extra printf to tuh_hid_report_received_cb to confirm that I was getting no reports)

What happened ?

This device is a bit weird in that it enumerates as a Nintendo Switch controller, then resets itself and enumerates as a generic xinput or HID controller.

With TinyUSB it fails in various different ways depending on the log level and other factors (timing issues?). Though I consistently fail to get any reports.

It also seems to fail entirely if you don't connect the controller after resetting the pico (and disconnect before).

(Additional logs: https://gist.github.com/Daft-Freak/fd7ba764e5f300caf474bede74966ba8)

How to reproduce ?

  1. Make sure controller is not connected.
  2. Build/install cdc_msc_hid
  3. Connect controller (holding Y the first time to make sure it's not in xinput mode)
  4. Get no HID reports, maybe get an assert failure or a hang

Debug Log as txt file (LOG/CFG_TUSB_DEBUG=2)

CFG_TUSB_DEBUG=2.txt

Screenshots

No response

I have checked existing issues, dicussion and documentation

RobertDaleSmith commented 10 months ago

I can confirm this issue on the RetroFlag SNES controller and various 8Bitdo controllers that all seem to exhibit the same boot behavior of cycling through different modes.

I first noticed this issue in the 8BitDo Wireless Adapter 2's latest firmware updates. Then more recently the 8BitDo Ultimate C wired controller and the 8BitDo NEOGEO controller both crash TinyUSB.

When I turn on full logs I can see it hits a *** PANIC *** error stating Invalid speed right before it locks up.

I have burned a good week trying to figure out what is going south within TinyUSB but I am at a loss. The more logs I have added seemed to change the behavior so I'm guessing a possible race condition is occurring but can't nail it down. With the 8BitDo Wireless Adapter 2, I was able to get it to work randomly if I reset the pico board at a specific moment during enumeration.

The common theme I see with these devices is that on boot up they cycle through appearing as various different simulated device modes (Switch, Xinput, Dinput). My guess is that this a method for auto mode setting that vendors are using. For example, if Nintendo Switch mode gets a response from the host console, then the USB device knows its connected to a Switch host device and continues to operate in that mode.

At this point I am willing to send controllers to @hathach or anyone that knows more about the guts of TinyUSB than I do.

Confirmed List of USB Devices with Issue:

RobertDaleSmith commented 10 months ago

For example, my VM software (Parallels) detecting the various device modes after plugging in the 8BItdo Wireless Adapter 2. https://github.com/hathach/tinyusb/assets/2039258/ab33a305-1cc7-4c0d-a7c8-91a466fb06ad

Also maybe related to issue #2176 since the USB controller is virtually connecting and disconnecting different device types quickly?

Daft-Freak commented 7 months ago

Seems #2310 has fixed one of the possible failures here, possibly replaced with more "invalid speed" panics. Otherwise seems the same.

hathach commented 7 months ago

@RobertDaleSmith this kind of race is hard to troubleshoot without actual hardware. If you can send an hardware in question to me, I will try to take a look. However, there is no guarantee on the ETA at all, and I do live in Vietnam. If you are OK with that, please drop me an email, I will send you the shipping info.

Daft-Freak commented 7 months ago

Any hints on where to look for someone with the hardware and too much free time?

RobertDaleSmith commented 7 months ago

@RobertDaleSmith this kind of race is hard to troubleshoot without actual hardware. If you can send an hardware in question to me, I will try to take a look. However, there is no guarantee on the ETA at all, and I do live in Vietnam. If you are OK with that, please drop me an email, I will send you the shipping info.

I got you. And no rush. I appreciate you even offering. robert [at] robert dale smith [dot] com

remy commented 2 months ago

FWIW I'm seeing the exact same issues. I've been testing with a pico and 8bitdo wireless adapter and when it's connected during boot, though tuh_hid_mount_cb is called, subsequently, tuh_hid_report_received_cb is never called.

If I boot without the adapter connected, tuh_hid_report_received_cb does get called, though only dpad change triggers - pressing any other button doesn't seem to trigger the callback (though if I hold a button, such as "START" and then press the dpad, I can see the button depressed in the report).

I'm also seeing the mount/unmount cycle until it settles - though at that point, it typically then doesn't fire the report callback.

I do have the adapter on v1.33 8bitdo firmware, so I'm going to also try to play around with that.

remy commented 2 months ago

Typically found a workaround…sort of… the very next moment. Not sure how far this is useful, but works for my 8bitdo wireless adapter.

If I put the adapter in to "sega genesis mini" mode, I'm getting all the buttons: dpad left + dpad up + select.

This is the hid report (which is slightly different to the usual ones I've seen on the adapter):

05 01 09 04 A1 01 A1 02 75 08 95 05 15 00 26 FF 
00 35 00 46 FF 00 09 30 09 30 09 30 09 30 09 31 
81 02 75 04 95 01 25 07 46 3B 10 65 14 09 00 81 
42 65 00 75 01 95 0A 25 01 45 01 05 09 19 01 29 
0A 81 02 06 00 FF 75 01 95 0A 25 01 45 01 09 01 
81 02 C0 A1 02 75 08 95 08 46 FF 00 26 FF 00 09 
02 91 02 C0 C0 

But I'm still stuck with the problem that if the adapter is connected during boot, it just doesn't register.