Étape 5: Créer le descripteur de HID pour votre nouveau périphérique
Maintenant, vous avez testé votre configuration de prototype, que vous pouvez commencer à transformer votre Arduino périphérique HID-Compatible. L’environnement Arduino est déjà mis en place afin qu’il puisse fonctionner comme un clavier et une souris, mais il faut ajouter un autre type d’appareil dans le mélange.
Les spécifications de HID sont conçues pour permettre à quiconque de créer un dispositif de classe USB ou une application sans devoir créer des pilotes personnalisés. C’est très pratique, mais ne signifie que la spécification est assez complexe car il cherche à être toutes choses à tous les hommes. Essentiellement, vous spécifiez le type de périphérique que vous créez - clavier, Joystick, souris, manette, volant, etc. - et puis spécifiez une ou plusieurs collections d’entrées de différents types. Ces paramètres, le type et la taille des données d’entrée spécifiées avec une longue série de codes arcanes et ne font pas pour faciliter la lecture. Heureusement la plupart des descripteurs que j’ai trouvé nageant avec des commentaires de texte brut qui rendent la vie un peu plus facile. Il y a aussi quelques bons guides et tableaux d’utilisation sur le web. Ils sont un peu secs, mais ils vous aideront à trouver ce dont vous avez besoin. Voici un couple que j’ai trouvé très pratique :
HID tutoriel : http://developer.mbed.org/media/uploads/wim/hid_usb_intro_an249.pdf
Table d’utilisation HID : http://www.freebsddiary.org/APC/usb_hid_usages.php
Vous pouvez également trouver des informations plus détaillées et un outil de descripteur (assez maladroit) HID à http://www.usb.org/developers/hidpage#HID outil descripteur
Voici le descripteur HID que j’utilise pour ma configuration :
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
Pour arriver ici, j’ai regardé sur les spécifications de USAGE_PAGE et de son utilisation et a décidé que la manette de jeu est la meilleure description d’utiliser comme une manette de jeu techniquement a au moins 2 axes analogiques plus au moins deux boutons. La manette de jeu peut avoir soit analogique X / Y ou un commutateur 4 voies numérique plus au moins deux boutons, donc je pourrais monter mon extension dans cette catégorie. Après cela nous spécifier une collection d’application et attribuez-lui un ID de rapport. Cela nous permet d’identifier les données plus tard.
Maintenant, nous spécifions une collection physique. C’est nos boutons. Vous pouvez avoir plusieurs collections, imbriquées ou side-by-side, mais je ne ressens pas le besoin. À l’intérieur de la collection physique vous maintenant spécifiez les entrées. Pour commencer j’ai la liste de la page utilisation de bouton et puis spécifiez les valeurs minimales et maximales, dans ce cas 1 et 8, comme je l’ai 8 boutons. J’ai ensuite spécifier logique minimum et maximum pour chacun de ces boutons. Car ils sont de simples interrupteurs je n’ai que 1 et 0 pour pressé et ne pas pressé. Puis je spécifier le nombre d’éléments dans le rapport et le nombre de rapports pour cette page de son utilisation. Enfin, je précise le type d’entrée pour cette valeur - données, qui sont Variable et se compose des valeurs absolues, plutôt que les valeurs qui sont relatives à des valeurs déclarées sur le derniers.
Le commutateur de chapeau est quelque peu différent. Un commutateur de chapeau nécessite une valeur de 0 à 7 qui spécifie la direction du chapeau par incréments de 45 degrés - 0 = vers le haut, 1 = haut/droite, 2 = droite, 3 = bas/droite, etc.. Cela signifie que nous spécifions la logique min/max comme 0 et 7 min/max physique 0 et 315. Nous n’avez pas besoin d’aller un plus loin en 360 degrés est équivalent à 0 degrés. Nous avons également spécifier l’unité comme une position de rotation angulaire. 0-7 peut être figurant dans quatre bits la taille du rapport est à 4 cette fois.
Ainsi, 8 boutons et un chapeau, nous avons terminé ? Pas tout à fait. Vous avez besoin de transférer un nombre entier d’octets pour chaque rapport à la prise USB, donc nous avons besoin d’ajouter un padding. Vous pouvez le faire en ajoutant un autre chapeau fantôme qui n’est jamais utilisé, mais c’est plus propre à simplement ajouter un autre rapport de 4 bits, puis affectez-lui le type d’entrée constante. Cela fait, vous pouvez fermer les deux physiques et collections de l’application et vous avez terminé.
Malheureusement, alors que Windows reconnaît le périphérique très bien vous trouverez que certains jeux ne sera pas comme ils s’attendent à trouver un X / axe Y donc, comme vous pouvez le voir dans le fichier ci-dessus, j’ai ajouté X factice / axes des ordonnées. Ceux-ci apparaîtront dans les données transférées, mais que nous changeons jamais les valeurs de 0 alors le bâton factice n’apparaîtront jamais à se déplacer.