360 controller raw USB gadget. (WIP)
Initially tried this using functionfs in both python and Rust, but this only worked on *nix hosts. The reason for this is that functionfs/gadgetfs only allows for well-defined USB classes/well-formed descriptors. After the interface descriptor, windows expects a vendor-specific descriptor, which is not supported by functionfs.
Thus, we're using raw-gadget + c here.
(First project using C, so don't judge too hard)
For now only the input endpoint is implemented, which allows for controller input to be sent to the host.
This project supports a range of hardware configurations, as listed below. You can build the project for your specific device using the appropriate make target.
Hardware | Build Target | Driver | Device |
---|---|---|---|
Raspberry Pi Zero (default target) | make |
20980000.usb |
20980000.usb (dwc2) |
Raspberry Pi 4 | make rpi4 |
fe980000.usb |
fe980000.usb (dwc2) |
Raspberry Pi 5 | make rpi5 |
1000480000.usb |
1000480000.usb (dwc2) |
USB Armory Mk II | make usb-armory-mk2 |
2184000.usb |
ci_hdrc.0 |
Orange Pi PC | make orange-pi-pc |
musb-hdrc |
musb-hdrc.4.auto |
Khadas VIM1 | make khadas-vim1 |
c9100000.usb |
c9100000.usb |
ThinkPad X1 Carbon Gen 6 | make thinkpad-x1 |
dwc3-gadget |
dwc3.1.auto |
NXP i.MX8MP | make nxp-imx8mp |
dwc3-gadget |
38100000.usb |
BeagleBone Black | make beaglebone-black |
musb-hdrc |
musb-hdrc.0 |
BeagleBone AI | make beaglebone-ai |
dwc3-gadget |
48380000.usb |
EC3380-AB | make ec3380-ab |
net2280 |
0000:04:00.0 |
Odroid C2 | make odroid-c2 |
dwc_otg_pcd |
dwc2_a |
Generic hardware | make generic |
dummy_udc |
dummy_udc.0 |
(Table is taken from the raw-gadget repository)
To build for your device, use the corresponding target, for example:
make rpi4
For the Raspberry Pi Zero / Zero 2, you can use the default target:
make
To run the gadget, you need to load the kernel module for raw-gadget and then run the gadget binary.
For the raw-gadget module, you can follow the instructions in the raw-gadget repo, e.g. for raspberry pi's: setup_raspberry-pi.md
After loading the module, you can run the gadget example binary:
sudo ./example
This will run the example function, which activates the A button every second.
For more input control, take a look at the partsnotincluded
link in the sources section.
If you want to use this in other projects, you can edit the makefile CFLAGS
. More info the makefile.
- Implement ep1 (output) for rumble
- Other endpoints (for audio, leds, etc.)?
useful links/sources:
More sources (old):