Holas... Yo contestaré tu pregunta porque curiosamente después de tanto leer, probar y ensayar contesté la mía.
Empezaré por el final. Para enviar una serie de datos usamos (después haber configurado todo) el siguiente comando en el Main de nuestro programa:
usb_put_packet(1,envia,6,USB_DTS_TOGGLE);
De donde:
'1': hace referencia al descriptor, EndPoint 1 (EP1).
'envia': es una variable que contiene los datos.
'6': Es el número de bytes a enviar.
'USB_DTS_TOGGLE': Sincronización de datos
Enfocandonos en la variable, que son 6 bytes (es un vector) tenemos distintos tipos de cosas:
envia[0]= eje_x
envia[1]= eje_y
envia[2]= eje_rx
envia[3]= eje_ry
envia[4]= botones1
envia[5]= botones2
En mi caso, todos mis datos, son de 8 bits cada uno. Esto es más sencillo porque si estás corto en bits de datos, debes acabar de llenar los 8 bits con otros datos que tengas por ahí y por tanto cambia el reporte.
Pero entonces volviendo por fin a tu pregunta: ¿Para que? Para que el PC pueda saber quien es que cosa, se debe definir el orden de lo que llega:
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x09, 0x05, // USAGE (Game Pad)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x39, 0x00, // DESIGNATOR_INDEX (0)
0x09, 0x30, // USAGE (X) ---eje_x
0x09, 0x31, // USAGE (Y) ---eje_y
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255)
0x95, 0x02, // REPORT_COUNT (2) ----'variables eje_x y eje_y'
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x00, // COLLECTION (Physical)
0x39, 0x01, // DESIGNATOR_INDEX (1)
0x09, 0x33, // USAGE (Rx)
0x09, 0x34, // USAGE (Ry)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255)
0x95, 0x02, // REPORT_COUNT (2) ----'variables eje_rx y eje_ry'
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1) ---- 'Botones'
0x29, 0x08, // USAGE_MAXIMUM (Button 8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x08, // REPORT_COUNT (8)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x09, // USAGE_MINIMUM (Button 9) 'MAS botones'
0x29, 0x10, // USAGE_MAXIMUM (Button 16)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x08, // REPORT_COUNT (8)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0 // END_COLLECTION
Defini estos reportes de cuantas maneras te puedas imaginar. Y solo leyendo, me enteré, que si tienes varias palancas físicas (como pasa en el mando de PSX) debes designar índices. Si no se dice para que sirve, el PC no lo entiende por lo tanto no va a funcionar. Hice chequeos de que el paquete se enviaba, con diferentes rutinas, con timeout donde todo parecía perfecto pero no había cambios (el gamepad no me reaccionaba para nada).
Otra cosa que cambién en el archivo de configuración de descriptores fue el número de interfases: #define USB_NUM_HID_INTERFACES 2, leí también que debía definirse de esta forma, aunque aclaro, que programé un firmware de megajoystick de 25 botones y este tampoco reaccionó (creo que lo habrán visto por ahí).
Estoy usando Windows 7 64-bits. y funciona perfectamente.
Saludos! Espero no haberme extendido mucho.
Empezaré por el final. Para enviar una serie de datos usamos (después haber configurado todo) el siguiente comando en el Main de nuestro programa:
usb_put_packet(1,envia,6,USB_DTS_TOGGLE);
De donde:
'1': hace referencia al descriptor, EndPoint 1 (EP1).
'envia': es una variable que contiene los datos.
'6': Es el número de bytes a enviar.
'USB_DTS_TOGGLE': Sincronización de datos
Enfocandonos en la variable, que son 6 bytes (es un vector) tenemos distintos tipos de cosas:
envia[0]= eje_x
envia[1]= eje_y
envia[2]= eje_rx
envia[3]= eje_ry
envia[4]= botones1
envia[5]= botones2
En mi caso, todos mis datos, son de 8 bits cada uno. Esto es más sencillo porque si estás corto en bits de datos, debes acabar de llenar los 8 bits con otros datos que tengas por ahí y por tanto cambia el reporte.
Pero entonces volviendo por fin a tu pregunta: ¿Para que? Para que el PC pueda saber quien es que cosa, se debe definir el orden de lo que llega:
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x09, 0x05, // USAGE (Game Pad)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x39, 0x00, // DESIGNATOR_INDEX (0)
0x09, 0x30, // USAGE (X) ---eje_x
0x09, 0x31, // USAGE (Y) ---eje_y
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255)
0x95, 0x02, // REPORT_COUNT (2) ----'variables eje_x y eje_y'
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x00, // COLLECTION (Physical)
0x39, 0x01, // DESIGNATOR_INDEX (1)
0x09, 0x33, // USAGE (Rx)
0x09, 0x34, // USAGE (Ry)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255)
0x95, 0x02, // REPORT_COUNT (2) ----'variables eje_rx y eje_ry'
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1) ---- 'Botones'
0x29, 0x08, // USAGE_MAXIMUM (Button 8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x08, // REPORT_COUNT (8)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x09, // USAGE_MINIMUM (Button 9) 'MAS botones'
0x29, 0x10, // USAGE_MAXIMUM (Button 16)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x08, // REPORT_COUNT (8)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0 // END_COLLECTION
Defini estos reportes de cuantas maneras te puedas imaginar. Y solo leyendo, me enteré, que si tienes varias palancas físicas (como pasa en el mando de PSX) debes designar índices. Si no se dice para que sirve, el PC no lo entiende por lo tanto no va a funcionar. Hice chequeos de que el paquete se enviaba, con diferentes rutinas, con timeout donde todo parecía perfecto pero no había cambios (el gamepad no me reaccionaba para nada).
Otra cosa que cambién en el archivo de configuración de descriptores fue el número de interfases: #define USB_NUM_HID_INTERFACES 2, leí también que debía definirse de esta forma, aunque aclaro, que programé un firmware de megajoystick de 25 botones y este tampoco reaccionó (creo que lo habrán visto por ahí).
Estoy usando Windows 7 64-bits. y funciona perfectamente.
Saludos! Espero no haberme extendido mucho.