Table of Contents

Kodi con Gamepad Wireless USB

Vogliamo utilizzare questo Gamepad come telecomando per Kodi su Raspberry Pi, la distribuzione di riferimento è RaspiOS basata su Debian 10 Buster. Si tratta un controller SNES wireless a 2.4 GHz con micro ricevitore USB per PC, nella confezione è compreso anche un ricevitore per Nintendo. Il produttore si chiama YSTEK e il prodotto MICREAL, Linux lo supporta tramite il modulo kernel DragonRise hid_dr.

The Micreal USB Gamepad using DragonRise driver

Viene riconosciuto dal comando lsusb come:

Bus 001 Device 015: ID 0079:0011 DragonRise Inc. Gamepad

La periferica dovrebbe essere riconosciuta in automatico e quindi i moduli kernel necessari dovrebbero essere caricati automaticamente (verificare i moduli hid_dr, ff_memless e hid).

Per effettuare il pairing tra gamepad e ricevitore USB si procede anzitutto scollegando il dongle USB dell'host. Quindi si premono contemporaneamente i tasti Start, Select e Up sul gamepad; il LED rosso inizia a lampeggiare rapidamente. Durante i 10 secondi successivi si deve inserire il ricevitore USB nella porta dell'host, il pairing avviene automaticamente.

Sono necessari i seguenti pacchetti Debian:

Altri pacchetti sono utili a individuare eventuali problemi:

In generale, dopo aver installato il pacchetto kodi-peripheral-joystick e riavviato Kodi, è sufficiente andare nel menu SettingsSystem settingsInputConfigure attached controller. In questa schermata è possibile scegliere il tipo di controller: Kodi 17 dispone del generico controller Kodi 17.6, mentre Kodi 18.7 consente di scegliere fra il generico Kodi oppure lo specifico controller Super Nintendo.

È possibile riprogrammare la funzione di ciascun tasto, ma le impostazioni predefinite dovrebbero andare bene. In generale saranno necessarie le seguenti funzioni:

Tasto Funzione
A Selezione / conferma
B Indietro
X Menu contestuale
Y
Start
Select
4 frecce Spostamento

La configurazione personalizzata viene salvata in un file nella cartella $HOME/.kodi/userdata/peripheral_data/, ad esempio nel nostro caso il file si chiama addon_YSTEK_MICREAL_USB_Gamepad.xml.

Il gamepad va in modalità stand-by dopo poco tempo di non utilizzo, per risvegliarlo è necessario premere il pulsante start. Il LED rosso si accende e i tasti funzionano nuovamente.

Problema freccia destra e sinistra non funzionanti

Tutto funziona correttamente su un sistema Raspberry Pi 3, RaspiOS basato su Debian 9.11 Stretch e Kodi 17.6.

Ci sono dei problemi invece con un sistema Raspberry Pi 4, RaspiOS basato su Debian 10.8 e Kodi 18.7: i tasti freccia Left e Right non funzionano.

C'è chi ha riscontrato lo stesso problema utilizzando Retropie: Controler Issue (no left and right not working at all).

Debug con input-events ed evtest

Eseguendo il comando lsinput si vede che il gamepad è stato associato al device event5:

/dev/input/event5
   bustype : BUS_USB
   vendor  : 0x79
   product : 0x11
   version : 272
   name    : "YSTEK MICREAL USB Gamepad"
   phys    : "usb-0000:01:00.0-1.3/input0"
   uniq    : ""
   bits ev : EV_SYN EV_KEY EV_ABS EV_MSC

Quindi è possibile monitorare gli eventi per 300 secondi eseguendo il comando:

input-events -t 300 5

Quando ad esempio si preme e si rilascia il tasto freccia su si ottiene:

07:58:36.696246: EV_ABS ABS_Y 0
07:58:36.696246: EV_SYN code=0 value=0
07:58:36.816264: EV_ABS ABS_Y 127
07:58:36.816264: EV_SYN code=0 value=0

L'evento EV_ABS (cambio di valore di un absolute axis) ci segnala che lasse ABS_Y ha assunto il valore 0 (zero). Quando il tasto viene rilasciato il valore torna a 127 (posizione neutra). Analogamente se si prema il tasto freccia giù il valore diventa 255. In pratica i tasti freccia simulano un joystick analogico, ma gli unici valori possibili sono:

0 Posizione estrema in alto
127 Posizione centrale
255 Posizione estrema in basso

In maniera del tutto analoga dovrebbero funzionare i tasti freccia destra e sinistra, generando un evento EV_ABS di ABS_X. Peccato che questo non avvenga: nessun evento viene mostrato da input-events.

Qualche informazione in più viene mostrata da evtest:

Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x79 product 0x11 version 0x110
Input device name: "YSTEK MICREAL USB Gamepad"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 288 (BTN_TRIGGER)
    Event code 289 (BTN_THUMB)
    Event code 290 (BTN_THUMB2)
    Event code 291 (BTN_TOP)
    Event code 292 (BTN_TOP2)
    Event code 293 (BTN_PINKIE)
    Event code 294 (BTN_BASE)
    Event code 295 (BTN_BASE2)
    Event code 296 (BTN_BASE3)
    Event code 297 (BTN_BASE4)
    Event code 298 (BTN_BASE5)
    Event code 299 (BTN_BASE6)
    Event code 300 (?)
    Event code 301 (?)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value      1
      Min        0
      Max      255
      Flat      15
    Event code 1 (ABS_Y)
      Value    127
      Min        0
      Max      255
      Flat      15
  Event type 4 (EV_MSC)
    Event code 4 (MSC_SCAN)

Si vede che nella posizione a riposo dell'asse ABS_X il Value è 1 invece dell'atteso 127.

Il problema non è circoscritto al Raspberry Pi, lo stesso malfunzionamento si riscontra anche su un PC amd64 con sistema Debian 10.8 e kernel 4.19.160. Il problema esiste già con il kernel 4.19.98. Il gamepad invece funziona correttamente sullo stesso PC, ma con il vecchio kernel 4.9.189.

I moduli kernel interessati dovrebbero essere: hid_dr, ff_memless e hid.

Questo il dmesg per il kernel 4.9.189 (funzionante):

usb 2-1.3: new low-speed USB device number 4 using ehci-pci
usb 2-1.3: New USB device found, idVendor=0079, idProduct=0011
usb 2-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 2-1.3: Product: MICREAL USB Gamepad
usb 2-1.3: Manufacturer: YSTEK
input: YSTEK MICREAL USB Gamepad as
    /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:0079:0011.0003/input/input17
dragonrise 0003:0079:0011.0003: input,hidraw2: USB HID v1.10 Joystick [YSTEK MICREAL USB Gamepad]
    on usb-0000:00:1d.0-1.3/input0

Questo invece il dmesg per il kernel 4.19.98 (non funzionante):

usb 2-1.3: new low-speed USB device number 9 using ehci-pci
usb 2-1.3: New USB device found, idVendor=0079, idProduct=0011, bcdDevice= 3.11
usb 2-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 2-1.3: Product: MICREAL USB Gamepad
usb 2-1.3: Manufacturer: YSTEK
input: YSTEK MICREAL USB Gamepad as
    /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:0079:0011.0008/input/input24
dragonrise 0003:0079:0011.0008: input,hidraw2: USB HID v1.10 Joystick [YSTEK MICREAL USB Gamepad]
    on usb-0000:00:1d.0-1.3/input0

Debug con usbmon

In teoria dovrebbe essere possibile ispezionare il traffico direttamente sul bus USB utilizzando la funzione usbmon del kernel Linux. Seguendo le istruzioni usbmon:

# Mount debugs, if not already mounted:
mount -t debugfs none_debugs /sys/kernel/debug
modprobe usbmon

quindi si chiede l'elenco di tutte le periferiche USB:

cat /sys/kernel/debug/usb/devices
...
T:  Bus=02 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#=  6 Spd=1.5  MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=0079 ProdID=0011 Rev= 3.11
S:  Manufacturer=YSTEK
S:  Product=MICREAL USB Gamepad
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=10ms
...

È possibile ispezionare il traffico di tutti i bus (utilizzando il numero 0), oppure solo quello del bus #2

cat /sys/kernel/debug/usb/usbmon/2u

Nel caso del nostro gamepad non si ottiene alcun tracciato, mentre si vede il passaggio dei pacchetti quando si muove un mouse collegato allo stesso bus.

Kernel funzionanti e kernel non funzionanti

System Kernel ABS_X Working
Raspberry Pi 3 4.19.66-v7+ Yes
Raspberry Pi 4 5.10.11-v7l+ No
PC amd64 Debian 10.8 4.9.189-3+deb9u2 Yes
PC amd64 Debian 10.8 4.19.67-2+deb10u2 Yes
PC amd64 Debian 10.8 4.19.98-1+deb10u1 No
PC amd64 Debian 10.8 4.19.160-2 No

Web References