RaspberryPi-Joystick icon indicating copy to clipboard operation
RaspberryPi-Joystick copied to clipboard

Emulate a Nintendo Switch controller

Open gdsports opened this issue 4 years ago • 37 comments

NSGamepad configures the gadget device into a USB gamepad. With the help of a Mayflash Magic NS adapter (about $20), the Pi Zero gamepad can control a Nintendo Switch. See PR https://github.com/milador/RaspberryPi-Joystick/pull/5

gdsports avatar Jan 27 '21 18:01 gdsports

@gdsports Awesome work. I will add a separate readme for it.

milador avatar Jan 31 '21 07:01 milador

I pushed up an example of using gpio pins to trigger gamepad buttons. The SDA/SCL and UART pins are not used because they might be useful for interfacing to other devices.

gdsports avatar Feb 01 '21 02:02 gdsports

Awesome. I don't have have Nintendo switch to test this but looks great. I try to get someone to test it. Thanks

milador avatar Feb 01 '21 06:02 milador

I tried the same descriptor which I used in a 32bit MCU that worked with XAC and still it doesn't work.

milador avatar Feb 11 '21 05:02 milador

I have had no success connecting to an XAC with the Pi Zero dwc2/libcomposite. I suspect kernel driver changes will be required to make this work but I am not a Linux driver guru.

Another option is to connect a small SAMD21 board (for example, QT Py or Seeeduino XIAO) programmed as an XAC compatible joystick via Pi UART. This frees up the Zero USB OTG port so it can be used in USB host mode. This option can also support two such boards, one for each XAC USB port. I will add a UART interface option to this project.

https://github.com/gdsports/xac_joystick_tinyusb

It should be possible to use Pi Pico boards instead of SAMD21 boards but Pi Picos are hard to get. I will probably take a look at Pi Pico when I have some time.

gdsports avatar Feb 11 '21 20:02 gdsports

I will get my Pi Picos by next week. I have got it working with ItsyBitsy board which has M0 chip. But having two different MCUs make the design hard to maintain and more difficult for XAC users to put it together. I was looking for some way to convert Bluetooth hid mouse to hid joystick for XAC. The Arduino nano RP2040 would work if we get Pico working.

milador avatar Feb 12 '21 08:02 milador

Great work though. I will use it for future projects. As I am switching to QT for most projects. Would be great if we can have it working with Pico soon as well.

milador avatar Feb 12 '21 08:02 milador

Adafruit nRF52840 boards work with the xac tinyusb driver but BT Classic is not supported. My BT keyboard and mouse are BT Classic so they do not work with the nRF52840. I was able to get an nRF52840 to send BLE HID keystrokes to another nRF52840 in BLE HID central mode. This probably works for BLE mice although I am not sure if this useful. Adafruit includes an Arduino example for BLE HID central but it only does keyboard. It has hooks for BLE HID mouse but it is not fully implemented. I will take a look at this.

My Pi Picos should arrive next week.

gdsports avatar Feb 12 '21 17:02 gdsports

I actually only need Bluetooth mouse working and keyboard not necessarily but that would be even better. Let me know if you have the sample code to test. That would solve my problem. I got it working with Teensy 3.6 but it's expensive comparing to your suggestion with nRF52840 and needs separate Bluetooth dongle. I have nRF52840 dongle which I can test your suggestion.

milador avatar Feb 12 '21 20:02 milador

@gdsports Would Adafruit ItsyBitsy nRF52840 Express work with this as well or do I need to modify the uf2?

milador avatar Feb 13 '21 04:02 milador

@milador I was never able to program an nRF52840 by dragging and dropping a UF2 file. I had to compile and upload using the IDE. This seems to only work with SAMD boards at the moment.

gdsports avatar Feb 13 '21 21:02 gdsports

The latest PR named xac_fix makes USB HID gadget work with the XAC! I was not making any progress with the nRF52840 so I switch gears to pi zero w. I changed a kernel source code but this does not require replacing the entire kernel or building a new IMG file. Replacing a single file installs the updated USB HID gadget driver (usb_f_hid.ko). A reboot is a good idea make sure the new version is running.

On the nRF52840 I cannot even get key input in Central mode. I recall this worked a while back but it does not work now.

The Zero is a better solution since it works for BT Classic and BLE. The Raspberry Pi OS BT GUI tool is not helpful. It does not auto connect to BT devices so the user must use the tray applet to connect to devices on every boot and disconnect. :{

gdsports avatar Feb 13 '21 21:02 gdsports

This is awesome 👌 I will give it a try tomorrow with few input devices and hopefully write a detailed instructions for it. It should be possible to use a little LCD and buttons on pi to scan and connect to the device. I have done something very similar to that so I will add it as alternative option in instructions. I might do a short video of raspberry solution and teensy solution for the community of XAC users to show the potentials. This opens the door for lots of possibilities.

milador avatar Feb 14 '21 08:02 milador

I am happy to hear you have a better way to configure BT. Running the GUI+VNC slows down the Pi Zero boot up so it is best not to avoid them.

gdsports avatar Feb 14 '21 17:02 gdsports

I tried your changes and I think it doesn't work since I am using older kernel version. I updated it to 5.10 but still no luck. So just put new fresh image and about to do another test. I make a separate page for it once I get it working. Some people may want to use simple 8 button joystick. Yes, VNC slows down and a simple Interface would work. I did a arduino .hex uploader using RPi zero and Ardafruit lcd module. I just need to combine that with my device scanner code.Thanks again for your support.

milador avatar Feb 16 '21 00:02 milador

I have been testing with the latest kernel. I will make sure it works starting from a fresh installation.

gdsports avatar Feb 16 '21 00:02 gdsports

I burned 2021-01-11-raspios-buster-armhf.zip to a microsd card to make sure I have not left out any steps or files.

Boot PiZeroW then use raspi-config to enable and configure WiFi, ssh, VNC (remote desktop). Change hostname to btgadget.

Update to the latest kernel and install required and optional packages.

sudo apt update
sudo apt full-upgrade
sudo apt install git python3-evdev python3-gpiozero
sudo apt install vim ctags screen build-essential # optional stuff I use
sudo reboot

Login again. Verify the kernel version.

uname -a
Linux btgadget 5.10.11+ #1399 Thu Jan 28 12:02:28 GMT 2021 armv6l GNU/Linux

Pair BT keyboard/mouse using GUI.

Set up USB gadget mode.

git clone https://github.com/milador/RaspberryPi-Joystick
cd RaspberryPi-Joystick
sudo echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt
sudo echo "dwc2" | sudo tee -a /etc/modules
sudo echo "libcomposite" | sudo tee -a /etc/modules
KERNEL_RELEASE=`uname -r`
sudo cp /lib/modules/${KERNEL_RELEASE}/kernel/drivers/usb/gadget/function/usb_f_hid.ko /lib/modules/${KERNEL_RELEASE}/kernel/drivers/usb/gadget/function/usb_f_hid.ko.orig
sudo cp rpi-5.10/usb_f_hid.ko /lib/modules/${KERNEL_RELEASE}/kernel/drivers/usb/gadget/function/
sudo reboot

Login again.

cd RaspberryPi-Joystick/8_Buttons_Joystick
sudo ./8_buttons_joystick
cd Code
sudo python3 joystick_demo.py

This is my test setup.

Pi4 - XAC - PiZeroW
       |
      5V2A

On the Pi4, jstest-gtk (sudo apt install jstest-gtk) is running which shows the Xbox Controller buttons and axes. The joystick demo program running on the PiZeroW should be pressing and releasing buttons and moving the (X,Y) axes.

If the XAC does not its own power suppy, it may not be able to supply enough current to the PiZeroW. I am sure the PiZeroW draws far more than 100 mA but less than 500 mA. When the XAC has its power supply, it can supply as much as 500 mA to each of its USB host ports.

gdsports avatar Feb 16 '21 01:02 gdsports

Tested and it's working. My PC decided to do a BIOS update during this time and messed up everything! Checked it with another PC and all good. I will just update the instructions now. Thanks for sending me your details commands.

milador avatar Feb 16 '21 04:02 milador

@gdsports Added x and y mapping for mice to joystick using 2 modes. One will keep the output position and the other mode returns to center when you stop moving mice. The Scroll wheel is next. I am turning it to a button press that keep pressing when Scroll up and release button when you scroll down. Take a look and see if there are bugs anywhere. I powered RPI zero using external power source and that is working as well without connecting power source to XAC.

milador avatar Feb 17 '21 04:02 milador

My first Pi Pico driver using the C SDK. Bare minimum example but it works on an XAC.

https://github.com/gdsports/xac_joystick_pipico

I'll take a look at your latest code. Looks like lots of progress.

gdsports avatar Feb 18 '21 03:02 gdsports

Awesome 👌 I will try it when I get my pico. I am still waiting. I also working on running the mouse and keyboard automatically using systemctl. Doesn't start no matter what I do but should be able to figure out the issue by printing few logs.

milador avatar Feb 18 '21 07:02 milador

@gdsports It seems that /etc/udev/rules.d is the solution.

milador avatar Feb 19 '21 08:02 milador

@milador I am back! I had some urgent work so I had to pause. I saw the youtube videos and it is gratifying to see the system in use with a game.

Running the python program as a service makes sense. As does using a udev rule to make the hidg0 accessible without being root.

I have never tried USB gadget on a Pi4 so I will give it a try. I am concerned it draws too much current so I hope the PC/laptop protects itself from this. A disadvantage of the PiZ is the quantity 1 limit so the Pi4 is a good alternative.

gdsports avatar Feb 26 '21 06:02 gdsports

@gdsports Glad you are back! Appreciate your support and I already made some contacts to test it with few different devices.

I just tested a bluetooth switch interface and it worked other than pairing issue. It seems debian bluetooth GUI interface doesn't support authentication so I need to create a helper software or python code to take care of that. Mapping profile would be another feature of helper software.

I found mice is not the best option as joystick as you need to keep moving the mice. I am wondering if move and lock direction until you move it again would be a better option.

Looked at ways to create a modified OS with all the code pre installed and it would be way to go once the code is tested and working with few different devices.

I will post another video tomorrow testing another device.

milador avatar Feb 26 '21 07:02 milador

@gdsports I am having issues with NS version after making changes to kernel module. All 4 other descriptors work but NS descriptor doesn't get recognized any more. Can you test it again? Probably need to go back to original hid kernel modules.

BTW, did you use toolchain for a 64-bit kernel or 32-bit for compiling on rpi4? I compiled it but doesn't work with current setting. The ones you pushed work.

milador avatar Mar 01 '21 07:03 milador

I used the 32-bit toolchain for all. I have not tried the NS version in a while so I will take a look. This is what I use.

KERNEL=kernel7l
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig
make -j ${NUMCPU} ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
DESTDIR="${DEST}/5.10.11-v7l+/${TAIL}"
if [ ! -d ${DESTDIR} ]
then
    mkdir -p ${DESTDIR}
fi
find . -name usb_f_hid.ko -print0 |xargs -0 -I{} cp {} "${DESTDIR}"

gdsports avatar Mar 01 '21 22:03 gdsports

@milador And I build from a branch and commit as close as possible to the current kernel. I should have all the steps in the Drivers/README.md but let me know if I left things out.

git clone --depth=1 --branch rpi-5.10.y https://github.com/raspberrypi/linux
cd linux
git checkout raspberrypi-kernel_1.20210201-1

gdsports avatar Mar 01 '21 22:03 gdsports

@gdsports I did all the steps other than checkout. I repeat it again maybe I messed up with changes to hid descriptor.

milador avatar Mar 02 '21 00:03 milador

@gdsports I get: error: pathspec 'raspberrypi-kernel_1.20210201-1' did not match any file(s) known to git

when I do checkout.

milador avatar Mar 03 '21 05:03 milador

@gdsports It's working now. It was a permission issue.

milador avatar Mar 04 '21 06:03 milador