Descriptor de HID para usar con un controlador de Playstation 2

1

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

Estoy intentando admitir los botones sensibles a la presión, pero no sé qué descriptor de 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 que el uso de Rx y Ry para el segundo stick analógico sea correcto.

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

Aquí está mi descriptor 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
};

PS. Estoy usando LUFA y actualizando el firmware del controlador USB de Uno

    
pregunta 小太郎

2 respuestas

1

Después de que Nombre falso dijera que tenía que usar el eje para los botones, decidí usar este descriptor en su lugar, ¡y funciona! (Aunque solo he probado en Linux)
Tuve que repetir el 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
};
    
respondido por el 小太郎
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, está fuera de suerte, ya que todavía tengo que encontrar cualquier software que funcione con más de 8 ejes (¡incluso ventanas!).

Además, puede consolidar algunos de sus 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 un 0 para el valor de los botones como "no presionado", y cualquier otra cosa como "presionado". Como tal, a menos que el botón completamente vuelva al estado no presionado, el botón parecerá "pegado".

De todos modos, la página de uso generic desktop de la tabla de uso de HID en realidad solo define un total de 9 ejes analógicos en su totalidad, por lo que está un poco desafortunado. 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 le 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 rato jugando con tablas HID en el proceso de convertir un arduino leonardo en un joystick. Mire eso aquí .

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

    
respondido por el Connor Wolf

Lea otras preguntas en las etiquetas