samedi 19 mars 2016

RetroPie's gamecon driver - readme.gz

(I retrieved this documentation through zless /usr/share/doc/gamecon_gpio_rpi/README.gz and tried to make it a bit friendlier.)

Game controller driver for Raspberry Pi's GPIO v1.0

1. Intro

The driver is designed to be used with retro game controllers connected to Raspberry Pi's GPIO. Currently, up to 4 controllers of following types are supported:

        -NES gamepads
        -SNES gamepads
        -PSX/PS2 gamepads
        -N64 gamepads
        -Gamecube gamepads

The driver is based on gamecon driver (see Documentation/input/joystick-parport.txt), but uses different pinout and parameters. No warranty - use at your own risk.

2. Required hardware

-Raspberry Pi and supported controllers
-Jumper wires between GPIO and pads
-Breadboard or splitter if multiple controllers are connected simultaneously

3. Connecting the controllers

Note that the GPIO input numbers do not match pin numbers.

GPIO pinout (all boards):

Pins P1-01 and P1-06 are used as common power and ground for all controllers. Note that 3.3V is used for all controllers, even if SNES&NES pads nominally are operated at 5V. They should work fine with 3.3V so no level shifters are needed for data pins. The maximum current spec. (50mA) should be enough for 4 controllers. However, use a proper ac adapter with Pi to avoid any unwanted voltage drops.

Pins P1-03,05,07,26 (GPIO0, GPIO1, GPIO4 and GPIO7 on older Pi boards) are independent data pins, one per pad.
NOTE: P1-03 & P1-05 correspond to GPIO2 & GPIO3 in rev.2 board, which must taken into account when loading the module. This is explained in section 4.

Pins P1-19 & P1-23 (GPIO10 & 11) are common signal pins for all NES/SNES pads.
Pins P1-08, P1-10 & P1-12 (GPIO14, 15 & 18) are common signal pins for all PSX/PS2 pads.

3.1 NES & SNES gamepads


Rpi pin
SNES controller pinNES controller pin
P1-01 (3.3V)
P1-06 (GND) 
1 (power)
2 (clock)
3 (latch)
4 (serial data)
7 (ground)
1 (power)
5 (clock)
6 (latch)
7 (data)
4 (ground)

 GPIOXX is the independent data pin. See section 4 on how to select the correct GPIO.

3.2 N64 pads

Rpi pin                            N64 controller pin

P1-01 (3.3V)   ====      power
GPIOXX          <-->      data
P1-06 (GND)  ====      ground

GPIOXX is the independent data pin. See section 4 on how to select the correct GPIO.

3.3 Gamecube pads

Rpi pin                         Gamecube controller pin

P1-01 (3.3V)  ====  6 (power/3.43V)
GPIOXX         <-->   3 (data)
P1-06 (GND) ====   2&5 (gnd)

GPIOXX is the independent data pin. See section 4 on how to select the correct GPIO.

3.4 PSX/PS2 pads

Rpi pin                         PSX controller pin (numbered right to left)

P1-01 (3.3V)   ====      5 (power/3.3V)
GPIO14            --->       2 (command)
GPIO15            --->       6 (select)
GPIO18            --->       7 (clock)
GPIOXX          <---       1 (data)
P1-06 (GND)   ====     4 (ground)

GPIOXX is the independent data pin. See section 4 below on how to select the correct GPIO.

4. Configuring the driver

Perform the following operations as root (or with sudo):

4.1 Configure pads

# modprobe gamecon_gpio_rpi map=<pad1/GPIO0>*,<pad2/GPIO1>*,<pad3/GPIO4>,<pad4/GPIO7>,<pad5/GPIO2>,<pad6/GPIO3>
        where <pad...> is a number defining the pad type:
        0 = no connection
        1 = SNES pad
        2 = NES pad
        3 = Gamecube pad
        6 = N64 pad
        7 = PSX/PS2 pad
        8 = PSX DDR controller
        9 = SNES mouse

For example (on a rev.1 Raspberry Pi), if a SNES pad is connected to GPIO0 and a N64 pad to GPIO7, the command would be "modprobe gamecon_gpio_rpi map=1,0,0,6".

* NOTE: pad1 & pad2 are only used with rev.1 board, and pad5 and pad6 with rev.2. So if you have rev.2 board, pad1 and pad2 must be set as 0.

Connecting these two controllers on a more recent Pi requires something like map=0,0,1,6,0,0 (if you use GPIOs 4 and 7).

The final pad index (used by the programs) is assigned sequentially for connected pads starting from 0. So in the previous example, snes pad would get index 0 and N64 pad index 1.

Use "tail /var/log/kern.log" to verify that module loading was successful

4.2 Testing the pads

# apt-get install joystick
# jstest /dev/input/jsX
        where X corresponds to the pad index (0-3)

4.3 Calibrating the axis of N64 analog pad

# jscal -s 4,1,0,0,0,6972137,6972137,1,0,0,0,6547006,6468127,1,0,0,0,536854528,536854528,1,0,0,0,536854528,536854528 /dev/input/jsX
        for each N64 controller

4.4 Setting access delay for psx pads

The access delay for PSX pads is set to 10us, which minimizes the performance penalty caused by the driver. However, in some rare cases it may not be enough to get stable input. If you have issues when reading psx pads, raise the delay with following extra modprobe parameter:

"psx_delay=<delay>". <delay> is value in us, and can be set between 1-50.

5. More information


mercredi 16 mars 2016

How I got the gamecon driver to work on RetroPie (EmulationStation) and was able to use a Nintendo 64 controller connected to the GPIO port of my Raspberry Pi 2

​I took the following steps before downloading the gamecon GPIO driver:
  • After booting from the SD for the first time, launch RetroPie-Setup, look for option 312 and upgrade Raspbian (you need the latest version of your system before installing the latest gamecon driver developed for it - logical, right?) and reboot.
  • Update raspi-config (A0 in advanced options) and reboot.
  • Update the RetroPie-Setup script and reboot.
  • Change locale (I1)
  • Change timezone (I2)
  • Change keyboard (I3)
  • Overclock the Pi (8)
  • Reboot (sudo reboot is the command you can type directly into the Pi's console or remotely through Putty)
  • Binary based installation (in RetroPie-Setup) and reboot.
  • Install (finally!) the GPIO/DB9 gamecon drivers and accept the offer to configure it for two SNES controllers (even if you want to use other controllers).
  • Reboot
I know that's a lot of reboots but I didn't want to risk damaging Raspbian (and start over from a blank SD because I'm not a Linux guru) :/

Another thing I like to do is use the 'Quit EmulationStation' option to return to the command line in case some of its files (like the games' metadata) need to be modified (like by the scraper) and won't be locked by the running program.

[At any moment, feel free to add some games to the ROM directories (in Windows: '\\retropie\roms' if you connected your Pi to the (W)LAN) !]

Now, to correctly (on RetroPie 3.6) configure gamecon:

  • From the console (pi@retropie:~ $), type cd /etc/modprobe.d
  • Type sudo nano gamecon.conf
You are now inside the 'nano' editor and can adjust the mapping according to your controller type and wiring (my gamecon.conf file looks like this:
options gamecon_gpio_rpi map=0,0,0,0,6,0
...because I only wired one N64 controller (type 6) to the first available (on a Raspberry Pi 2) GPIO pin.)

  • Use Ctrl+X to exit, press Y and Enter to save the changes.
Recent versions of Linux don't accept these parameters inside the 'modules' file. It should only have 'gamecon_gpio_rpi' without the 'map' part, which is to be written to the .conf file we just mentioned above or there will be a boot error because the deprecated way of setting things is not accepted anymore.

My modules file looks like this:
# /etc/modules: kernel modules to load at boot time.
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.


You'll (obviously) need to reboot once again to test these settings.

To learn more about connecting a classic controller to the GPIO port, read this :)

After that, I was able to setup the N64 gamepad as a controller inside EmulationStation; everything but the analog stick was usable there. If this happens to you, just configure the functions you can and skip the others. After that, edit (comfortably, from Windows, in Notepad++) the .cfg file generated in '\\retropie\configs\all\retroarch-joypads'.

These were the four missing lines from my N64controller.cfg:
input_l_y_minus_axis = "-1"
input_l_x_plus_axis = "+0"
input_l_y_plus_axis = "+1"
input_l_x_minus_axis = "-0"

Then, I tried to play Mario Kart 64 but the D-pad was not responding so I edited the InputAutoCfg from '\\retropie\configs\n64' and corrected a few lines again:
; N64 controller_START
[N64 controller]


R Trig = button(8)
L Trig = button(7)
Start = button(9)
Z Trig = button(0)
C Button D = button(3)
C Button U = button(6)
C Button L = button(5)
C Button R = button(4)
A Button = button(1)
B Button = button(2)
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)
DPad U = hat(0 Up)
DPad D = hat(0 Down)
DPad L = hat(0 Left)
DPad R = hat(0 Right)
; N64 controller_END
Then all the controls worked in Mario Kart :)