convertir el ejemplo de mouse USB de descubrimiento STM32F4 a gamepad

Tengo una placa de descubrimiento stm32f4, para la cual se puede descargar un proyecto de demostración aquí: http://www.st.com/web/en/catalog/tools/PF257904

Esta demostración consiste en un software para usar la placa como un mouse usb hid, usando el acelerómetro para controlar el movimiento del mouse. Quiero convertir esto en un gamepad, por ahora dejo las otras partes del descriptor igual, así que solo cambié el uso de 0x09,0x02 (uso: mouse) a 0x09, 0x09 (uso: gamepad). (estos valores se pueden encontrar en el archivo usb_hid_core)

Pero después de este cambio, la computadora todavía lo ve como un mouse, pero uno que no funciona correctamente. ¿Qué más debo cambiar?

Cualquier ayuda sería muy apreciada, he estado intentando todo tipo de cosas durante semanas, pero nada parece funcionar.

el archivo usb_hid_core se puede encontrar en este archivo en esta ubicación:

stsw-stm32068\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32_USB_Device_Library\Class\hid\src

(Tenía la impresión de que todo lo que tendría que cambiar sería esta línea en el descriptor para que pareciera un gamepad, ya que los datos que se envían seguirán cumpliendo con el descriptor entonces, también intenté cambiarlo a un dispositivo muy simple que envía solo un byte antes de cambiarlo a un gamepad, y traté de cambiar varias otras cosas como la clase oculta). Así es como aparece después de cambiarlo a un gamepad (pero entonces no funciona): http://hmsprojects.com/USB-invoerapparaat.html

Respuestas (1)

Necesitas cambiar algunas otras cosas para que funcione como un gamepad. En usbd_hid_core.c necesitas cambiar:

 0x02,         //nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse

al valor 0x00.

Otra cosa, el descriptor del informe debe cambiarse, este es el mío para un gamepad de 3 botones y 2 ejes (puede cambiarlo para agregar un botón o cualquier otra cosa con HIDtool):

__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
  0x05,   0x01, // USAGE_PAGE (Generic Desktop)
  0x09,   0x05, // USAGE (Game Pad)
  0xA1,   0x01, // COLLECTION (Application)

  0xA1,   0x00, // COLLECTION (Physical)
  0x05,   0x09, // USAGE_PAGE (Button)
  0x19,   0x01, // USAGE_MINIMUM (Button 1)
  0x29,   0x03, // USAGE_MAXIMUM (Button 3)

  0x15,   0x00, // LOGICAL_MINIMUM (0)
  0x25,   0x01, // LOGICAL_MAXIMUM (1)
  0x95,   0x03, // REPORT_COUNT (3)
  0x75,   0x01, // REPORT_SIZE (1)

  0x81,   0x02, // INPUT (Data,Var,Abs)
  0x95,   0x01, // REPORT_COUNT (1)
  0x75,   0x05, // REPORT_SIZE (5)
  0x81,   0x07, // INPUT (Cnst,Var,Rel)

  0x05,   0x01, // USAGE_PAGE (Generic Desktop)
  0x09,   0x30, // USAGE (X)
  0x09,   0x31, // USAGE (Y)

  0x15,   0x81, // LOGICAL_MINIMUM (-127)
  0x25,   0x7F, // LOGICAL_MAXIMUM (127)
  0x75,   0x08, // REPORT_SIZE (8)
  0x95,   0x02, // REPORT_COUNT (2)

  0x81,   0x02, // INPUT (Data,Var,Abs)
  0xC0,   0xC0  // END_COLLECTION x2
}; 

El tamaño del descriptor del informe ha cambiado, así que modifíquelo en usbd_hid_core.c:

#define HID_MOUSE_REPORT_DESC_SIZE    48

Ahora el gamepad sería reconocido. Solo necesita enviar un informe de 3 bytes (el primero para el botón, y los otros dos para el eje). Para una prueba, podría hacerlo usando este código en stm32xx_it.c:

static uint8_t *USBD_HID_GetPos (void)
{
static uint8_t HID_Buffer[3] = {0};

static int8_t val_abs_x=0;
static uint8_t sens_x=0;

HID_Buffer[1] = 0;
HID_Buffer[2] = 0;

// X move
if (val_abs_x > 120)
{
    sens_x = 0; // --
    HID_Buffer[0]=0;
}
else if (val_abs_x < -120)
{
    sens_x = 1; // ++
    HID_Buffer[0]=1;
}

if (sens_x == 1)
    val_abs_x = val_abs_x + 3;
else
    val_abs_x = val_abs_x - 3;

HID_Buffer[1] = val_abs_x;
HID_Buffer[2] = 0;

return HID_Buffer;
}

Anf finalmente cambia la línea (en el mismo archivo):

  USBD_HID_SendReport (&USB_OTG_dev, buf, 4);

a :

  USBD_HID_SendReport (&USB_OTG_dev, buf, 3);

Esto debería funcionar bien en la placa de descubrimiento STM32f4. Si no, intente cambiar el PID agregando 1 (como 0x5711) en usbd_desc.c).

Solo quiero agradecerle su respuesta, ya que me ha sido muy útil para modificar el descriptor de usb para gamepad en STM32F103C8T6, la clave fue cambiar el PID agregando 1. ¡Muchas gracias!