Nintendo classic i2c controller driver for Raspberry Pi
Allows connecting NES/SNES classic mini controllers directly via the I2C bus on the GPIO header of the Raspberry Pi.
The driver also supports Wii Classic Controller (Pro).
Plug side view:
/---------\
| |
| 1-2-3 |
| 4-5-6 |
| _____ |
\_/ \_/
Controller Pin | Function | Pi Pin |
---|---|---|
1 | I2C data | 3 (SDA) |
2 | device detect | - |
3 | +3.3V | 1 (+3.3V) |
4 | GND | 6 (GND) |
5 | not connected | - |
6 | I2C clock | 5 (SCL) |
One way to connect the wires without breaking the plug of your controller is to use one of many “nunchuck” breakout
boards sold by hobby electronic stores. Some of them seem to be out of stock by now so an alternative would be to
sacrifice a socket part from an snes/nes classic extension cable which are currently common and inexpensive.
This can be done with the bundled configuration tool raspi-config
under “Interfacing Options” > “I2C”.
If you want to do it manually, it comes down to:
dtparam=i2c_arm=on
line to /boot/config.txt
i2c_dev
module (sudo modprobe i2c_dev
for the current session and adding i2c_dev
line to /etc/modules
to load on boot)
sudo apt-get install build-essential cmake libi2c-dev i2c-tools
When properly connected it controller should be now visible at address 0x52 and all other addresses should
be empty.
$ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- 52 -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
cmake .
make
sudo ./i2c-classic-controller -d
If the controller is correctly connected it should display the button events:
Detected device: 01 00 A4 20 01 01
buttons: A
-y <n>
by default the driver is using /dev/i2c-1
for the i2c bus connection, which corresponds to the bus-f <n>
event polling frequency. The default is 60 per second and can be changed in range 1 - 1000.-d
print controller events to the standard output-a
report analog stick events. By default the driver will ignore the analog input which is not presnet on the classic-a6
report also the analog triggers. The triggers also report separate digital events, so enabling this may confuse-h
use full 8-bit accuracy readout for analog input. The snes/nes classic consoles use this mode even though the controllers don’t have analog sticks. This option may be required for some third party controllers which only implement
sudo make install
sudo systemctl enable nintendo-i2c-controller
This will install a systemd service which will run the driver on startup. Additionally a udev rule will be set
to remove ID_INPUT_KEY
property from the uinput node which prevents some software (specifically Kodi) to detect
the controller as a keyboard.
All Nintendo i2c controllers use the same static i2c address which means only one can be connected to an i2c bus at a time.
Raspberry Pi 2/3 SoC has 2 buses but bus 0 is used for internal purposes. Pi 4 has more i2c busses however this
functionality does not seem to be explored much so I did not try to use it.
Either way this driver theoretically would support multiple controllers when one instance of the driver is run for
each port (using the -y
bus id param).