The NES Advantage shipped in 1987 with a hardwired cable and a nine-pin plug. It is a good stick, and there is nothing modern to plug it into. I wanted mine working on a Switch and on a real NES without giving up anything the original did.

Rules I set before starting:

The board

One 2-layer PCB, 78 x 36 mm, replaces the cable and drops into the stock case. A bare ESP32-WROOM-32E reads the stick's original CD4021 shift registers, the same parts the controller has always used to serialize its buttons, and presents the result over Bluetooth. 39 placed parts, all hand-solderable, though the two QFN-style regulators are easier with hot air.

Power is a TP4056 linear charger for the 1S LiPo cell and a TPS63900 buck-boost for the 3.3 V rail, with a load-share path built from a P-channel MOSFET and a Schottky diode so the stick plays while it charges. The TPS63900 idles at 75 nA, which is what makes the standby figure below possible. Battery sense goes through a divider whose ground leg is switched by a small N-FET, so it draws nothing when no one is reading it.

Two transports, one radio

Switch mode (Bluetooth Classic)

A clean-room Switch Pro Controller emulation. It pairs directly from Change Grip/Order on a Switch 1 or a Switch 2 with no adapter in between, and it pairs with an 8BitDo NES Retro Receiver, which is how the stick gets back onto a real NES.

BLE mode

A standard BLE HID gamepad. Windows, Linux, SteamOS, Android, and BlueRetro all take it without drivers. The player-select slider does something new here: the stick shows up as two gamepads, so you flip the slider to hand off and map each gamepad to a player in your emulator. On a Switch the slider still picks which player you report as, since one Pro Controller is one player no matter what.

Hold Select and Start for five seconds to change transports. The RGB status LEDs say which one you are in.

Buttons the NES never had

The Switch expects buttons that 1987 hardware does not have. They live on Select-held chords, which fire instantly instead of needing a long hold, so they work mid-game:

Hold Select, pressSends
StartHome
UpZL + ZR, which opens the menu in NSO retro games
LeftZL
RightZR
DownCapture, held to record a clip

The chord has to start inside a short window, 200 ms out of the box. Hold Select past that and it settles into being an ordinary Minus you can keep held, which some games need. The window is adjustable from 100 to 500 ms, or you can set it to Hold for no limit at all, or switch chords off and get a plain Select back. In BLE mode they do not exist: a PC has no use for Home or Capture, and a holdable Select is worth more than either.

Numbers

Configuration in a browser

There is no app to install. Hold A, B, and Select for five seconds to put the stick in config mode, then open the hosted page in Chrome or Edge and connect over Web Bluetooth. Every button, the D-pad, the slider, and both turbo dials light up live as you use them, which turned out to be the fastest way to catch a dirty switch or a wire on the wrong pin while installing the mod. The same page sets transport, button profile, directional mode, and the chord window, and it flashes new firmware over the air. Dropping a firmware.bin on it is the whole update process. It checks the image before sending and writes only the inactive OTA slot, so settings and pairings survive the update.

What the Switch Pro protocol cost me

Reading the stick was the easy half. Convincing a console that the thing asking to pair is a Pro Controller was the rest of it.

All of this is in docs/switch_pro_protocol.md in the repo, in more detail and with the register values, on the theory that it saves the next person a week.