Paso 5: Crear el descriptor HID de su nuevo dispositivo
Ahora has probado la configuración del prototipo que puede comenzar a convertir tu Arduino en un dispositivo compatible con HID. El entorno de Arduino ya está configurado para permitir que funcione como un teclado y un ratón, pero es necesario agregar otro tipo de dispositivo en la mezcla.
Las especificaciones HID están diseñadas para permitir a cualquier persona crear un dispositivo de clase USB o aplicaciones sin la necesidad de crear controladores personalizados. Esto es muy útil, pero significa que la especificación es bastante compleja ya que intenta ser todo para todos los hombres. Esencialmente se especifica el tipo de dispositivo que está creando - teclado, Joystick, ratón, Gamepad, volante, etc - y luego especificar una o más colecciones de entradas de varios tipos. Estos parámetros y el tipo y tamaño de los datos de entrada se especifican con una larga serie de códigos Arcanos y no para una fácil lectura. Afortunadamente la mayoría descriptores que he encontrado están nadando con comentarios de texto que hacen la vida un poco más fácil. También hay algunas buenas guías y tablas de uso en la web. Son un poco secos pero te ayudará a encontrar lo que necesita. Aquí hay un par que he encontrado útil:
Tutorial de HID: http://developer.mbed.org/media/uploads/wim/hid_usb_intro_an249.pdf
HID de uso de tabla: http://www.freebsddiary.org/APC/usb_hid_usages.php
También puede encontrar información más detallada y una herramienta de descriptor HID (bastante torpe) en http://www.usb.org/developers/hidpage#HID Descriptor de herramienta
Este es el descriptor HID que estoy utilizando para mi configuración:
0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x05, // USAGE (Game Pad) 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x03, // REPORT_ID (3) (This is important when HID_SendReport() is called) 0xA1, 0x00, // COLLECTION (Physical) // 8 buttons 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) 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) <br> // 1 Hat Switch 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x39, // USAGE (Hat switch) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x07, // LOGICAL_MAXIMUM (7) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315) 0x65, 0x14, // UNIT (Eng Rot:Angular Pos) 0x75, 0x04, // REPORT_SIZE (4) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) <br> // Padding (4 bytes) 0x75, 0x04, // REPORT_SIZE (4) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x03, // INPUT (Cnst,Var,Abs) // 1 D-pads - Dummy so Elite:Dangerous recognises it 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, //END COLLECTION 0xC0, //END COLLECTION
Para llegar hasta aquí miré sobre las especificaciones de uso y USAGE_PAGE y decidió que la almohadilla de juego era la mejor descripción para usar como un Joystick técnicamente tiene por lo menos 2 ejes analógicos más al menos dos botones. El cojín del juego puede tener X analógico / Y o un interruptor de 4 vías digital plus al menos dos botones, por lo que pude ajustar mi extensión en esta categoría. Después de especifique una colección para la aplicación y darle un ID de informe. Esto nos ayuda a identificar los datos más adelante.
Ahora especificamos una colección física. Esto es nuestro botones. Usted puede tener más colecciones, anidadas o side-by-side, pero no siento la necesidad. Dentro de la colección física ahora se especifican las entradas. Para empezar la pagina de uso botón y especifique los valores mínimos y máximos, en este caso 1 y 8 ya que tengo 8 botones. Luego especificar la lógica mínimo y máximo para cada uno de esos botones. Como son simples interruptores solo tengo 1 y 0 para presionado y no presionado. Luego especificar el número de elementos en el informe y el número de informes de esta página de uso. Finalmente especificar el tipo de entrada para este valor de-datos, que es Variable y consiste en valores absolutos, en lugar de valores que son relativos a los valores reportados por última.
El interruptor es algo diferente. Un interruptor requiere un valor de 0 a 7 que especifica la dirección del sombrero en incrementos de 45 grados - 0 = arriba, 1 = arriba/derecha, 2 =, 3 = abajo/derecha, etc.. Esto significa que especificamos la lógica mín/máx 0, 7 y la física min/max 0 y 315. No tenemos que ir alguno más como 360 grados es equivalente a 0 grados. También especificamos la unidad como una posición de rotación angular. 0-7 puede ser contenido en cuatro bits el tamaño del informe está 4.
¿Por lo tanto, 8 botones y un sombrero, hemos terminado? No del todo. Usted necesitará transferir un número entero de bytes para cada informe a los USB host por lo que debemos agregar algún relleno. Podría hacer esto mediante la adición de otro sombrero fantasma que nunca se utiliza, pero es más limpio simplemente agregar otro informe de 4 bits y establecer el tipo de entrada constante. Una vez hecho esto usted puede cerrar ambos físico y colecciones de aplicaciones y listo.
Desafortunadamente, mientras que Windows reconoce el dispositivo bien encontrará que algunos juegos no como esperan encontrar una X / eje Y así como se puede ver en el archivo anterior que he añadido ficticio X / Y ejes. Estos aparecerán en los datos transferidos, pero nunca no cambiamos los valores de 0 entonces el palillo dummy nunca aparece como para moverse.