Multi-Platform Gamepad Firmware for RP2040 customized by tamanegi_taro
This firmware is customized by tamanegi_taro. Added compatibility with following mini series:
- Astrocity mini
- Astrocity V mini
- Mega drive mini
- Mega drive 2 mini
- Genesis mini
- Genesis 2 mini
- Egret II mini
- Neogeo mini
- Neogeo international mini
- PC Engine mini
- Core Grafx mini
- TurboGrafx-16 mini
This project does not include USB descriptors for controllers of mini series so you'll need to supply USB descriptors by yourself. Don't worry. I will provide steps to get USB descriptors from your controller pads below.
Hold following button while plugging USB to select input mode
-
P1 DirectInput
-
P2 PS4
-
K1 Switch
-
K2 Xinput
-
R1 Astrocity/Mega Drive/Genesis mini
-
L1 Egret II mini
-
R2 Keyboard
-
L2 Neogeo mini
-
R3 PC Engine/Core Grafx/TurboGrafx-16 mini
-
Important! Make sure to select DPad : Digital for mini series
In my project, following descriptors need to be modified by you for mini series compatibility:
GP2040-CE\headers\gamepad\descriptors\AstroDescriptors.h
- astro_string_manufacturer[]
- astro_string_product[]
- astro_device_descriptor[]
- astro_configuration_descriptor[]
- astro_report_descriptor[]
GP2040-CE\headers\gamepad\descriptors\EgretDescriptors.h
- egret_string_manufacturer[]
- egret_string_product[]
- egret_device_descriptor[]
- egret _configuration_descriptor[]
- egret _report_descriptor[]
GP2040-CE\headers\gamepad\descriptors\NeogeoDescriptors.h
- neogeo_string_manufacturer[]
- neogeo_string_product[]
- neogeo_device_descriptor[]
- neogeo_configuration_descriptor[]
- neogeo_report_descriptor[]
GP2040-CE\headers\gamepad\descriptors\PCEngineDescriptors.h
- pcengine_string_manufacturer[]
- pcengine_string_product[]
- pcengine_device_descriptor[]
- pcengine_configuration_descriptor[]
- pcengine_report_descriptor[]
You need following gamepads for finding USB descriptors information, respectively.
- Megadrive mini 6 button pad(For Astrocity, Mega drive and Genesis mini support)
- Egret II mini pad(For Egret II mini support)
- Neogeo mini pad(For Neogeo mini support)
- PC Engine mini Turbopad(For PC Engine, CoreGrafx and TG-16 mini support)
You also need USB-C extension cable + logic analyzer(USB protocol) for Neogeo mini support.
Here is how you get descriptors for Mega Drive(Astrocity), EgretII and PC Engine mini series.
- (1) Install Wireshark with USB Cap
- (2) Run Wireshark with USB Cap and start recording USB packets
- (3) Plug your controller to your PC
- (4) Stop Wireshark recording
- (5) Scroll up until you find descriptors of your controller
Click on "GET DESCRIPTOR Response DEVICE" then click on "DEVICE DESCRIPTOR". The binary array is highlighted in blue. Use this 18 byte array for xx_device_descriptor[] array. (Descriptor shown in this figure is GP2040-CE Nintendo Switch descriptor.)
There are two "GET DESCRIPTOR Response CONFIGURATION". Click on second one. Also click on "CONFIGURATION DESCRIPTOR" to highlight what you will need for xx_configuration_descriptor[] array. (Descriptor shown in this figure is GP2040-CE Nintendo Switch descriptor.)
This configuration descriptor include several "ENDPOINT DESCRIPTOR". Click on it to find byte which corresponds to bInterval byte. There are several ENDPOINT and bInterval in this descriptor. If these are not 0x01, change them to 0x01 for xx_configuration_descriptor[] for fastest response. (Descriptor shown in this figure is GP2040-CE Nintendo Switch descriptor.)
Click on "GET DESCRIPTOR Response HID Report" and "HID Report". The binary array is highlighted in blue. Use this array for xx_report_descriptor[] array. (Descriptor shown in this figure is GP2040-CE Nintendo Switch descriptor.)
For xx_string_manufacturer[] and xx_string_product[], open game controller configuration in windows settings. You can see gamepad's name.("6B controller" in this example figure.). Use this string for both xx_string_manufacturer[] and xx_string_product[].
For Neogeo pad, it is little difficult because you will need logic analyzer. Connect logic analyzer between Neogeo pad and Neogeo mini.
After communicating USB descriptor, Neogeo mini will apply reset on Neogeo pad and Neogeo Pad will send new USB descriptor after reset.
You need to dump this new USB descriptor. Should not use first USB descriptor. In new USB descriptor, find descriptor which starts from 0x12 0x01. Use it as neogeo_device_descriptor[].
Find descriptor which starts from 0x09 0x02. This is configuration descriptor. There are two configuration descriptors. Find longer one and use it as neogeo_configuration_descriptor[]. Make sure to set bInterval as 0x01 for fastest response.
Next, find string descriptor which starts from 0x06 0x03. Search in google for ASCII table and find which character is used for this string descriptor. For example, if value of string descriptor is 0x06 0x03 0x42 0x00 0x42 0x00, string will be "BB". Use string you found for both xx_string_manufacturer[] and xx_string_product[]. Neogeo mini will not recognize your GP2040-CE as pad unless you use correct string.
Next, find descriptor which start from 0x05 0x01. This descriptor might be divided into multiple transfers if the array is too long. Combine them and use this for neogeo_report_descriptor[].
GP2040-CE (Community Edition) is a gamepad firmware for the Raspberry Pi Pico and other boards based on the RP2040 microcontrollers that combines multi-platform compatibility, low latency and a rich feature set to provide endless customization possibilities without sacrificing performance.
GP2040-CE is compatible with PC, PS3 and PS4, Nintendo Switch, Steam Deck, MiSTer and Android.
Downloads | Installation | Wiring | Usage | FAQ | GitHub
Full documentation can be found at https://gp2040-ce.info
- Select from 5 input modes: XInput, Nintendo Switch, PS4, PS3 and Keyboard
- Overclocked polling rate for less than 1 ms of input latency in all modes.
- Multiple SOCD cleaning modes - Up Priority (a.k.a. Stickless), Neutral, and Second Input Priority.
- Left and Right stick emulation via D-pad inputs as well as dedicated toggle switches.
- Dual direction via D-pad + LS/RS.
- Reversed input via a button.
- Turbo and Turbo LED with selectable speed
- Per-button RGB LED support.
- PWM Player indicator LED support (XInput only).
- Multiple LED profiles support.
- Support for 128x64 monochrome I2C displays - SSD1306, SH1106, and SH1107 compatible.
- Custom startup splash screen and easy image upload via web configuration.
- Support for passive buzzer speaker (3v or 5v).
- Built-in, embedded web configuration - No download required!
Visit the GP2040-CE Usage page for more details.
Input latency is tested using the methodology outlined at WydD's inputlag.science website, using the default 1000 Hz (1 ms) polling rate in the firmware.
Version | Mode | Poll Rate | Min | Max | Avg | Stdev | % on time | %1f skip | %2f skip |
---|---|---|---|---|---|---|---|---|---|
v0.7.0 | All modes (except PS4) | 1 ms | 0.53 ms | 1.36 ms | 0.86 ms | 0.25 ms | 95.91% | 4.09% | 0% |
v0.7.0 | PS4 Mode | 1 ms | 1.45 ms | 2.14 ms | 1.86 ms | 0.16 ms | 90.26% | 9.74% | 0% |
Full results can be found in the GP2040-CE Firmware Latency Test Results Google Sheet.
If you would like to discuss features, issues or anything else related to GP2040-CE please create an issue or join the OpenStick GP2040-CE Discord support channel.
Want to help improve GP2040-CE? There are a bunch of ways to contribute!
Have an idea for a cool new feature, or just want to discuss some technical details with the developers? Join the OpenStick GP2040-CE Discord server to participate in our active and ever-growing community!
Pull requests are welcome and encouraged for enhancements, bug fixes and documentation updates.
Please respect the coding style of the file(s) you are working in, and enforce the use of the .editorconfig
file when present.
- FeralAI for building GP2040 and laying the foundation for this community project
- Ha Thach's excellent TinyUSB library examples
- fluffymadness's tinyusb-xinput sample
- Kevin Boone's blog post on using RP2040 flash memory as emulated EEPROM
- bitbank2 for the OneBitDisplay and BitBang_I2C libraries, which were ported for use with the Pico SDK
- arntsonl for the amazing cleanup and feature additions that brought us to v0.5.0
- alirin222 for the awesome turbo code (@alirin222 on Twitter)
- deeebug for improvements to the web-UI and fixing the PS3 home button issue
- TheTrain and Fortinbra for helping keep our community chugging along
- PassingLink for the technical details and code for PS4 implementation
- Youssef Habchi for allowing us to purchase a license to use Road Rage font for the project