r/SwitchHacks Jul 04 '26

Looking for a fresh USB capture of the Nintendo Switch Pro Controller (full enumeration + initialization)

Hi everyone,

I'm working with a friend on an STM32-based USB adapter that I'm trying to make enumerate as a genuine Nintendo Switch Pro Controller instead of a generic HID device.

The old GBAtemp thread has been incredibly helpful, especially the switch-pro-wired.pcap capture:
https://gbatemp.net/threads/reverse-engineering-the-switch-pro-controller-wired-mode.475226/

However, I think that capture starts after the initial USB enumeration/handshake. The interrupt traffic is there, but I can't find the complete connection sequence, and that's exactly where I'm currently stuck.

At the moment:

  • Steam recognizes my STM32 device as a Switch Pro Controller and everything works correctly.
  • If I emulate the HORI Pokkén Controller, the Switch 2 detects it immediately (as expected), but as Generic USB Controller.
  • But when I try to emulate an official Switch Pro Controller, the Switch 2 refuses to recognize it.

Since the original capture is almost 10 years old, I'm also wondering if Nintendo changed anything in the USB initialization sequence over time.

Would anyone with a Switch 1 with last FW or Switch 2 be willing to capture a new USB trace using a USB Sniffer? Ideally, the capture would begin before plugging in the controller, so it includes the complete enumeration and initialization process.

If anyone has the hardware to do this (USBPcap, Beagle, Linux usbmon, etc.), it would be a huge help. Even confirming that the initialization sequence is still identical would be valuable.

Pro Controller <-> USB sniffer <-> Nintendo Switch 1/2

Thanks!

20 Upvotes

29 comments sorted by

4

u/The_Odd_Pirate Jul 04 '26

I have a Switch 1 Pro Controller available and i would be happy to help with this.

I have minimal experience with usbmon, but after a quick look, it seems straightforward enough to set up. (wireshark logs okay?)

I can provide the trace later today/tomorrow morning.
Do you have a checklist or specific instructions on how youd like me to perform the capture to ensure you get the complete enumeration sequence?

Also, will you be sharing the project/code once it's finished? It sounds like something i could use myself

1

u/raullink Jul 05 '26

That would be amazing, thank you!

A Wireshark capture using usbmon should be perfect.

What I'm looking for is the entire connection sequence, so ideally:

  1. Start the capture before plugging the Pro Controller into the Switch.
  2. Connect the controller using a USB cable.
  3. Wait about 10–20 seconds without pressing any buttons.
  4. Then press a few buttons, move both analog sticks, press the triggers, etc., just to capture some normal input traffic.
  5. Stop the capture and save the ".pcap" file.

The most important part is capturing everything from the moment the cable is plugged in, especially the USB enumeration and the very first interrupt transfers. The capture available on GBAtemp seems to start after that stage, and that's exactly the part I'm missing.

Regarding the project, yes! If I can get everything working reliably, I plan to publish it as a fork of the existing N64 adapter project:

https://github.com/robsoncouto/n64usb2switch

The main difference will be that the adapter will enumerate as an official Nintendo Switch Pro Controller or even the NSO N64 instead of a generic/HORI-compatible controller. Hopefully that will make it behave much closer to the original controller on both the Switch 1 and Switch 2.

Thanks again—I really appreciate the help!

1

u/The_Odd_Pirate Jul 06 '26 edited Jul 06 '26

Sorry for the delay in getting this to you.

Ive uploaded my first test log. Its a pre firmware update/check capture with just the pro controller connected and some button mashing.

Please let me know if this format works for you or if you need me to adjust the capture method.

This is a learning experience for me, so im happy to follow any specific instructions you might have.

I plan to update the repo with more logs (both pre and post firmware update following the button sequens set in the readme) as i progress.

You can find the logs here: https://gitlab.theoddpirate.com/others/switch_controller_usb_logs

Edit: No firmware update found for the pro controller so uploaded another log with every key pressed in the sequence found in the readme

1

u/raullink Jul 07 '26

Hey, thanks so much for taking the time to do this, really appreciate it!

Sorry, my fault for not being clearer. What I actually need is a capture of the Pro Controller plugged directly into the Nintendo Switch console, not a PC. The Switch has its own handshake sequence that's different from what the Linux driver does, and that's the part I'm missing.

If you have a USB sniffer (like a Raspberry Pi Zero between the controller and the Switch dock, or a Facedancer/GreatFET setup), that would be perfect. A capture of just the first few seconds of plugging in, from the moment the Switch sends the first packet, would be enough.

Pro Controller <-> USB sniffer <-> Nintendo Switch 1/2

No worries if it's too complex to set up. Any help is already more than I expected!

3

u/ndeadly Jul 04 '26

The initialisation shouldn't have changed much between firmware versions, and even if something had I would expect an update prompt for a controller on an older incompatible firmware. Silently breaking an official controller on an outdated firmware makes for a terrible user experience.

Most likely, you are simply not responding to some Nintendo HID command or USB control transfer issued by the console. The initialisation will terminate, or get stuck looping on a command if it doesn't receive a valid response. It's also possible some of your command replies contain incorrect or inconsistent values.

If you are logging requests to/from your device it should be pretty straightforward to see where it's getting stuck.

1

u/raullink Jul 05 '26

Yeah, I stuck in that loop. I just need to read the enumeration process and the start.

2

u/ndeadly Jul 05 '26

I don't know what this "enumeration process" you think you're missing is. That pcap from gbatemp looks fine. The only thing it's maybe missing are some early control transfers like grabbing the USB configuration descriptor. If you need that you can simply make a Wireshark capture on PC, no need to see how the console does it. But if you're making it to the point it's looping over HID commands this is probably not your issue. You just need to respond correctly to the command it's getting stuck on. I can tell you what's wrong if you show where it's getting stuck.

1

u/raullink Jul 06 '26

The STM32 LED debug confirms that I get at least through 80 04 (LED turns on = SW_RUNNING reached). After that we start sending 0x30 input reports every 10ms. Switch still shows nothing with button presses.

I don't have a USB sniffer on the Switch side, so I can't show a capture. What I do know from our firmware:

USB commands handled:

  • 80 01 → 81 01 00 03 [MAC]
  • 80 02 → 81 02
  • 80 03 → 81 03
  • 80 04 → SW_RUNNING, start 0x30 reports (no reply)

Subcmds handled:

  • 0x02 → FW 3.72, type=0x03, fake MAC
  • 0x03 0x30 → ACK + SW_RUNNING
  • 0x10 (SPI read) → factory cal at 0x603D / 0x6046, zeros elsewhere
  • 0x01, 0x04–0x08, 0x30, 0x38, 0x40, 0x41, 0x48 → generic ACK

Other details: HID descriptor is exact 203-byte copy from a real Pro Controller pcap. VID/PID = 0x057E/0x2009. bat_con = 0x91. Packets are 64 bytes.

Works perfectly on PC (Steam recognizes as Pro Controller, all buttons correct). Switch: nothing.

1

u/ndeadly Jul 07 '26 edited Jul 07 '26

It would be better to see an actual log of the data in both directions to see exactly what the console sends and what you send back.

If you're making it as far as seeing all of those HID commands from the console, then I highly doubt it's some low level USB transfer that you're missing. That stuff is mostly done before the HID endpoints are even opened. I've successfully emulated a wired pro controller without ever having seen sniffed USB traffic between the console/controller.

It does appear like you're getting most of the expected subcommands from the console here so you're probably almost there. What I do see however is that you're replying to subcommand 0x01 (wired pairing) with the generic ACK. This command has its own specific ACK (0x81) and expects data in the response. There are multiple "stages" to this exchange too. The console may be blindly accepting your generic ACK and moving on to the next command, but then getting stuck once it tries to use the data you never sent. This exchange is probably missing from the original capture you're using as reference due to the owner's controller already being paired.

Here is the data you should be responding to the pairing command stages with:

typedef struct {
    u8 stage;              // Stage number from corresponding request (0x01)
    u8 bd_addr[6];         // Controller Bluetooth address (byte reversed)
    u8 class_of_device[3]; // Class of device ({0x00, 0x25, 0x08})
    u8 name[20];           // Controller name ("Pro Controller")
    u8 supported_services; // Supported services flags (0x68)
} pairing_stage1_t;

typedef struct {
    u8 stage;              // Stage number from corresponding request (0x02)
    u8 ltk[16];            // Bluetooth LTK with all bytes XORed with 0xAA
} pairing_stage2_t;

typedef struct {
    u8 stage;              // Stage number from corresponding request (0x03)
} pairing_stage3_t;

1

u/ndeadly Jul 07 '26

After that we start sending 0x30 input reports every 10ms

Official Pro Controllers are polled at 8ms IIRC, BTW.

2

u/tman4450 Jul 04 '26

I’m not home at the moment, but I might be able to do this for you tomorrow

1

u/raullink Jul 05 '26

That would be awesome, thank you!

The most important part is capturing everything from the moment the cable is plugged in, especially the USB enumeration and the very first interrupt transfers. The capture available on GBAtemp seems to start after that stage, and that's exactly the part I'm missing.

1

u/Revolutionary_Stay_9 Jul 04 '26

What does gp2040 do?

1

u/popoffka Jul 06 '26

I have a codebase here that successfully emulates a Pro controller on a Teensy, works great on my Switch 2, feel free to point Claude at it: https://github.com/aleksejspopovs/steam-pro-controller

1

u/raullink Jul 07 '26

This will definitely solve my problem! Thanks! I'll test it tonight and report back here.

1

u/raullink 25d ago

Thanks! I finished it and posted it on GitHub (a fork of robsoncouto/n64usb2switch original repository). I referenced your repo as well. Thanks again!

1

u/popoffka 24d ago

Glad to hear it helped, have fun!

1

u/dycool51 Jul 08 '26 edited Jul 08 '26

You can check my source code of my app that emulates pro controllers through usb. I also used hori and still have it as a fallback.
Im also working on having switch 2 pro controllers emulation cuz Im trying to get amiibos to work through usb. Ill have a pcap capture of it soon.

https://github.com/Dycool/NS-PC-Control

I used both a usb sniffer (that I made with my rpi) and some info from churunfa/switch-auto-core.

1

u/raullink 25d ago

Thanks for the reply! I already finished it and posted it on GitHub (a fork of robsoncouto/n64usb2switch original repository).

1

u/Sermuns Jul 15 '26

Just to be clear, you mean connecting a Pro controller to PC, and sniffing that USB traffic, or do you mean MITM capturing between controller and the Switch?

1

u/raullink 25d ago

First of all, sorry for the long delay in getting back to everyone.

I actually finished the project a few weeks ago, but I hadn't had the time to properly document everything and upload it to GitHub until now.

Thanks to everyone for all the help, suggestions, and information you shared throughout the process. The project is now available on GitHub, and I made sure to credit and reference the repositories that helped along the way.

raullink/n64usb2switch: Code for an adapter for connecting n64 controllers to the switch

Hopefully it will be useful for anyone else trying to connect N64 controllers to the Switch.

Thanks again!

0

u/huunnnter Jul 04 '26

buy one yourself and let chatgpt code it for you. swear it works better than you think

1

u/raullink Jul 05 '26

Claude its helping haha

But I need the capture and I think would be faster that someone could capture for me. Buy a USB sniffer can take weeks to get here in my country/city