GameCube controller adapter USB HID data dump?

arpruss

Member
OP
Newcomer
Joined
Jan 24, 2022
Messages
14
Trophies
0
Age
49
XP
34
Country
United States
I've made stm32duino-based USB adapters for various controllers in the past (e.g., search Instructables under "arpruss"), and I was wondering if anyone would be able to help me by posting a dump of the HID descriptors for a Switch GameCube USB adapter. One can obtain these with win-hid-dump on Windows or usbhid-dump on Linux. I searched the web and couldn't find any dumps for these. Thanks!
 
  • Like
Reactions: elmaa

thesjaakspoiler

Well-Known Member
Member
Joined
Nov 20, 2018
Messages
601
Trophies
0
Age
122
XP
793
Country
Afghanistan
I dumped the HID on a MacBook with mac-hid-dump (https://github.com/todbot/mac-hid-dump)
If I plug in the black connector I get this data :
057E 0337: Nintendo - WUP-028
DESCRIPTOR:
05 05 09 00 a1 01 85 11 19 00 2a ff 00 15 00 26
ff 00 75 08 95 05 91 00 c0 a1 01 85 21 19 00 2a
ff 00 15 00 26 ff 00 75 08 95 25 81 00 c0 a1 01
85 12 19 00 2a ff 00 15 00 26 ff 00 75 08 95 01
91 00 c0 a1 01 85 22 19 00 2a ff 00 15 00 26 ff
00 75 08 95 19 81 00 c0 a1 01 85 13 19 00 2a ff
00 15 00 26 ff 00 75 08 95 01 91 00 c0 a1 01 85
23 19 00 2a ff 00 15 00 26 ff 00 75 08 95 02 81
00 c0 a1 01 85 14 19 00 2a ff 00 15 00 26 ff 00
75 08 95 01 91 00 c0 a1 01 85 24 19 00 2a ff 00
15 00 26 ff 00 75 08 95 02 81 00 c0 a1 01 85 15
19 00 2a ff 00 15 00 26 ff 00 75 08 95 01 91 00
c0 a1 01 85 25 19 00 2a ff 00 15 00 26 ff 00 75
08 95 02 81 00 c0
(214 bytes)

If I plug in the grey usb connector, I get nothing so I presume that is just for getting some additional power to the adapter.
Some article say it is for 'rumble only'.

If you need the data in another form or from another tool, please let me know.
 

arpruss

Member
OP
Newcomer
Joined
Jan 24, 2022
Messages
14
Trophies
0
Age
49
XP
34
Country
United States
Thanks!

This sure is a weird HID report descriptor. Doesn't look like any game controller I've ever seen. Just a bunch of 8-bit items. Nothing obvious about what any of it means.

0x05, 0x05, // Usage Page (Game Ctrls) 0x09, 0x00, // Usage (Undefined) 0xA1, 0x01, // Collection (Application) 0x85, 0x11, // Report ID (17) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x05, // Report Count (5) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x21, // Report ID (33) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x25, // Report Count (37) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x12, // Report ID (18) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x22, // Report ID (34) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x19, // Report Count (25) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x13, // Report ID (19) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x23, // Report ID (35) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x02, // Report Count (2) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x14, // Report ID (20) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x24, // Report ID (36) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x02, // Report Count (2) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x15, // Report ID (21) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x25, // Report ID (37) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x02, // Report Count (2) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection // 214 bytes
 

thesjaakspoiler

Well-Known Member
Member
Joined
Nov 20, 2018
Messages
601
Trophies
0
Age
122
XP
793
Country
Afghanistan

arpruss

Member
OP
Newcomer
Joined
Jan 24, 2022
Messages
14
Trophies
0
Age
49
XP
34
Country
United States
OK, I got it. It took longer than I hoped because the usb adapter needs to have both a TX and an RX endpoint--the rumble data is sent to the RX endpoint rather than over the control endpoint--and my USB library generated HID devices with only a TX endpoint. I added a quick and dirty tweak to the library to suppor ttwo endpoints, and now I have working proof-of-concept code for a BluePill microcontroller with Arduino that is recognized by the Switch. The proof of concept code is in github . com / arpruss / switchgamecubeusbadapter
 

thesjaakspoiler

Well-Known Member
Member
Joined
Nov 20, 2018
Messages
601
Trophies
0
Age
122
XP
793
Country
Afghanistan
I presume you used that Bluepill/ board because of the USB connectivity?
I have some chinese Arduino Nano boards around but they don't have usb connectivity out of the box.
If you make some progress, maybe create a new post with your project here.
I saw you have a ton of intersting projects already on the Instructable site.
 

arpruss

Member
OP
Newcomer
Joined
Jan 24, 2022
Messages
14
Trophies
0
Age
49
XP
34
Country
United States
I presume you used that Bluepill/ board because of the USB connectivity?
I have some chinese Arduino Nano boards around but they don't have usb connectivity out of the box.
If you make some progress, maybe create a new post with your project here.
I saw you have a ton of intersting projects already on the Instructable site.

I use the BluePill both because of USB connectivity, and because it's super cheap ($2-3) and very familiar to me.
 

The Real Jdbye

*is birb*
Member
Joined
Mar 17, 2010
Messages
21,900
Trophies
3
Location
Space
XP
11,062
Country
Norway
Thanks!

This sure is a weird HID report descriptor. Doesn't look like any game controller I've ever seen. Just a bunch of 8-bit items. Nothing obvious about what any of it means.

0x05, 0x05, // Usage Page (Game Ctrls) 0x09, 0x00, // Usage (Undefined) 0xA1, 0x01, // Collection (Application) 0x85, 0x11, // Report ID (17) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x05, // Report Count (5) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x21, // Report ID (33) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x25, // Report Count (37) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x12, // Report ID (18) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x22, // Report ID (34) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x19, // Report Count (25) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x13, // Report ID (19) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x23, // Report ID (35) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x02, // Report Count (2) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x14, // Report ID (20) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x24, // Report ID (36) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x02, // Report Count (2) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x15, // Report ID (21) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection 0xA1, 0x01, // Collection (Application) 0x85, 0x25, // Report ID (37) 0x19, 0x00, // Usage Minimum (Undefined) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x02, // Report Count (2) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection // 214 bytes
It works as a standard HID controller. But it needs a special command sent to it to enable the functionality otherwise button inputs aren't registered. That's what I've heard, anyway.
Edit: Maybe it would help to look at how Nintendont implements it? Since that has full support.
 
Last edited by The Real Jdbye,

arpruss

Member
OP
Newcomer
Joined
Jan 24, 2022
Messages
14
Trophies
0
Age
49
XP
34
Country
United States
1. I now have a working GameCube to Switch adapter. The GameCube plug connections are listed at the top of the updated switchgamecube.ino in my github repository. The components needed are (a) BluePill board, (b) GameCube controller socket (1-4 of them, depending on how many you want) and (c) 1K resistor (1-4 of them, depending on how many GameCube controllers you want). Rumble is still not implemented, but it shouldn't be very hard once I figure out the data format.

2. A funny thing: The GameCube controller data goes into HID report 33, and it's ALMOST in the same format in which the GameCube controller produces it, except that the buttons (other than ABXY) are in a different order.

3. I had some calibration problems initially. I had to switch my controller to slot 2, and then back to slot 1, and the calibration problem disappeared. I don't know why.

4. Am I right in thinking that there is no way of generating a HOME button press using the GameCube controller?

5. I could be wrong, but I think the HID descriptor is actually badly written. For instance, for Report 33 (the main controller report), we have Report Count 37. But Report Count 37 (for 8 bit data) should mean one byte of report ID followed by 37 bytes of data. But as far as I can tell from all the sources, what the controller sends is the report ID followed by 36 bytes of data. It doesn't really matter, since I suspect neither the Switch nor the Wii U cares about what is inside the HID descriptor.
 

arpruss

Member
OP
Newcomer
Joined
Jan 24, 2022
Messages
14
Trophies
0
Age
49
XP
34
Country
United States
And my code now supports rumble (I figured out how rumble works by looking at the Nintendont code). When I run the rumble motor on 3.3v (which is what my microcontroller uses), it's a bit weak, though. One could power the rumble motor separately using its 5V line if one wanted to.
In any case, if anyone wants it, all the code is in my switchgamecubeusbadapter repository in the arpruss github (I'm a newb in this forum, so they don't let me post links).

One thing I am planning to experiment with is whether I can write a better HID descriptor, and get the Switch to accept it, so that it would work on PCs without any special drivers (currently one needs vjoy and a special driver to use the GameCube USB adapter). Earlier experiments suggest that the Switch may not actually care about the contents of the HID descriptor.
 

arpruss

Member
OP
Newcomer
Joined
Jan 24, 2022
Messages
14
Trophies
0
Age
49
XP
34
Country
United States
My latest code changes the HID descriptor and presents the first GameCube controller plugged into the adapter to the PC as a normal game controller. As far as I can tell, the Switch ignores most of the HID descriptor (which probably explains why the original one is wrong). So for the Switch it should work as a 4-port adapter, and for the PC as a 1-port adapter with no special drivers needed.
 
General chit-chat
Help Users
    Veho @ Veho: Also it runs Windows 11.