====== 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**.
{{.:kodi:micreal-usb-gamepad.jpg?400|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:
* **kodi-peripheral-joystick**
Altri pacchetti sono utili a individuare eventuali problemi:
* **input-utils** - Contiene i tool **lsinput** e **input-events** per visualizzare gli eventi input prodotti dal gamepad.
* **evtest** - Contiene il tool **evtest** per monitorare gli eventi input.
In generale, dopo aver installato il pacchetto **kodi-peripheral-joystick** e riavviato Kodi, è sufficiente andare nel menu **Settings** => **System settings** => **Input** => **Configure 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: **[[https://retropie.org.uk/forum/topic/25657/controler-issue-no-left-and-right-not-working-at-all/| 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 **[[https://www.kernel.org/doc/Documentation/usb/usbmon.txt|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 =====
* **[[https://www.retropie-italia.it/viewtopic.php?f=19&t=702|[GUIDA] DragonRise Inc. Generic USB Joystick]]**
* **[[https://retropie.org.uk/forum/topic/25657/controler-issue-no-left-and-right-not-working-at-all/|Controler Issue (no left and right not working at all)]]**