Descriptor HID para usar con un controlador de Playstation 2

Actualmente estoy haciendo un convertidor de controlador a USB de Playstaion 2 usando un Arduino Uno, y va muy bien, pero estoy atascado en un problema específico.

Estoy tratando de admitir los botones sensibles a la presión, pero no sé qué descriptor HID usar para el USB. Actualmente tengo lo siguiente, pero mi computadora no parece estar registrando los estados de los botones correctamente, y jstest muestra que los botones parecen "pegarse" en un estado activado. Además, no estoy muy seguro de si usar Rx y Ry para el segundo stick analógico es correcto.

¿Qué áreas del descriptor debo cambiar para que todo funcione correctamente?

Aquí está mi descripción actual:

const PROGMEM USB_Descriptor_HIDReport_Datatype_t hidDescriptor[] =
{
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Pointer)
    0xa1, 0x00,                    //   COLLECTION (Physical)
                                   //     ; Right stick
    0x09, 0x33,                    //     USAGE (Rx)
    0x09, 0x34,                    //     USAGE (Ry)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //     LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)

                                   //     ; Left stick
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //     LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION

    0x05, 0x09,                    //   USAGE_PAGE (Button)
                                   //   ; Pressure sensitive buttons
    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
    0x29, 0x0c,                    //   USAGE_MAXIMUM (Button 12)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x0c,                    //   REPORT_COUNT (12)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)

                                   //   ; Other buttons (L3, R3, Select, Start)
    0x19, 0x0d,                    //   USAGE_MINIMUM (Button 13)
    0x29, 0x10,                    //   USAGE_MAXIMUM (Button 16)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x04,                    //   REPORT_COUNT (4)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION
};

PD. Estoy usando LUFA y flasheando el firmware del controlador USB de Uno

Respuestas (2)

No puedes tener botones sensibles a la presión. Debe especificarlos como ejes adicionales.

Además, ¿el controlador realmente tiene 12 botones sensibles a la presión? En ese caso, no tiene suerte, ya que todavía tengo que encontrar un software que funcione con más de 8 ejes (¡incluidas las ventanas!).

Además, puedes consolidar algunos de tus controles de ejes:

const PROGMEM USB_Descriptor_HIDReport_Datatype_t hidDescriptor[] =
{
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Pointer)
    0xa1, 0x00,                    //   COLLECTION (Physical)

 // ----- Consolidated
                                   //     ; Right stick
    0x09, 0x33,                    //     USAGE (Rx)
    0x09, 0x34,                    //     USAGE (Ry)
                                   //     ; Left stick
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //     LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x02,                    //     REPORT_COUNT (4)    //changed
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)

    0xc0,                          //   END_COLLECTION


    0x05, 0x09,                    //   USAGE_PAGE (Button)
// this section isn't going to work...
                                   //   ; Pressure sensitive buttons
    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
    0x29, 0x0c,                    //   USAGE_MAXIMUM (Button 12)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x0c,                    //   REPORT_COUNT (12)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
// this section will, though the previous section will likely break something, and the whole descriptor will likely be rejected.
                                   //   ; Other buttons (L3, R3, Select, Start)
    0x19, 0x0d,                    //   USAGE_MINIMUM (Button 13)
    0x29, 0x10,                    //   USAGE_MAXIMUM (Button 16)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x04,                    //   REPORT_COUNT (4)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION
};

Lo que sospecho que está sucediendo es que la computadora está interpretando 0el valor de los botones como "no presionado" y cualquier otra cosa como "presionado". Como tal, a menos que el botón regrese por completo al estado en que no se presionó, parecerá que el botón se "pega".

De todos modos, la generic desktoppágina de uso de la tabla de uso de HID en realidad solo define un total de 9 ejes analógicos en su totalidad, por lo que no tiene suerte. Incluso el diagnóstico del controlador de Windows solo admite un máximo de 8 ejes, y la mayoría de las bibliotecas que acceden a los gamepads admiten incluso menos.

DirectX, por ejemplo, solo te permite acceder a 6 ejes analógicos.

De todos modos, eche un vistazo a las tablas de uso de USB HID aquí .

También pasé un tiempo jugando con mesas HID en el proceso de convertir un arduino leonardo en un joystick. Mira eso aquí .

Por cierto, si puedes, te recomiendo un Arduino Leonardo para este tipo de retoques. Es mucho más fácil lidiar con eso que tratar de volver a flashear el ATmega8U2 en un Arduino Uno.

¡El controlador de Playstation ciertamente tiene 12 botones sensibles a la presión! ( en.wikipedia.org/wiki/DualShock#DualShock_2 ) Además, afortunadamente, el sistema operativo que estoy usando es Linux, y usando jstest, parece informar bien todo el eje. El software de destino para el que iba a usar el controlador es PCSX2, y parece que también es compatible con todos los ejes
En serio. Eso es un poco ridículo. De todos modos, si el sistema operativo en el que está puede manejar muchos ejes, solo informe todos los botones como ejes analógicos separados, y debería estar bien.

Después de que Fake Name me dijera que tenía que usar axis para los botones, decidí usar este descriptor en su lugar, ¡y funciona! (Sin embargo, solo probé en Linux) Tuve
que repetir las Usage (Z)12 veces, pero eso no pareció causar ningún problema.

const PROGMEM USB_Descriptor_HIDReport_Datatype_t hidDescriptor[] =
{
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)

                                   //   ; Right stick
    0x09, 0x33,                    //   USAGE (Rx)
    0x09, 0x34,                    //   USAGE (Ry)
                                   //   ; Left stick
    0x09, 0x30,                    //   USAGE (X)
    0x09, 0x31,                    //   USAGE (Y)
                                   //   ; Pressure sensitive buttons
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x09, 0x32,                    //   USAGE (Z)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x10,                    //   REPORT_COUNT (16)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)

    0x05, 0x09,                    //   USAGE_PAGE (Button)
                                   //   ; Other buttons (L3, R3, Select, Start)
    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
    0x29, 0x04,                    //   USAGE_MAXIMUM (Button 4)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x04,                    //   REPORT_COUNT (4)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION
};