Stap 5: USB-HID verslagen en verslag Descriptors
Neem een kijkje op uw Wii Classic Controller. Het heeft 15 knoppen (ronde tot 16 voor de eenvoud) en twee joysticks. Dit betekent dat we moeten afgeven 15 stukjes van de gegevens voor de knoppen, en 4 nummers, één voor elk zwaartepunt van joystick gegevens. Definiëren we onze gegevensindeling om er als volgt uitzien:
Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | |
0 byte | Knop | Knop | Knop | Knop | Knop | Knop | Knop | Knop |
Byte 1 | Knop | Knop | Knop | Knop | Knop | Knop | Knop | Knop |
Byte 2 | Linker Stick X as als ondertekende Char Integer | |||||||
Byte 3 | Linker Stick Y as als ondertekende Char Integer | |||||||
Byte 4 | Juiste Stick X as als ondertekende Char Integer | |||||||
Byte 5 | Juiste Stick Y as als ondertekende Char Integer |
En dan kunnen we definiëren een gegevensstructuur in C/C++
struct gamepad_report_t { uint16_t buttons; int8_t left_x; int8_t left_y; int8_t right_x; int8_t right_y; }
Het schrijven van een verslag-descriptor gaat beschrijven een context gebruik eerst, en dan met een beschrijving van de betekenis van de gegevens ten opzichte van de context gebruik en vervolgens met een beschrijving van de gegevens qua bereik en grootte.
Controleer eerst de computer begrijpen dat het apparaat een gamepad is
USAGE_PAGE (Generic Desktop) USAGE (Game Pad) COLLECTION (Application) COLLECTION (Physical) ... END COLLECTION END COLLECTION
Vervolgens beschrijven de knop gegevens (16 bits)
USAGE_PAGE (Button) USAGE_MINIMUM (Button 1) USAGE_MAXIMUM (Button 16) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) REPORT_COUNT (16) REPORT_SIZE (1) INPUT (Data,Var,Abs)
Vervolgens beschrijven de gegevens 4 as als ondertekende 8-bits gehele getallen
USAGE_PAGE (Generic Desktop) USAGE (X) USAGE (Y) USAGE (Z) USAGE (Rx) LOGICAL_MINIMUM (-127) LOGICAL_MAXIMUM (127) REPORT_SIZE (8) REPORT_COUNT (4) INPUT (Data,Var,Abs)
- Opmerking: Z wordt gebruikt voor de X-as de juiste stick, Rx wordt gebruikt ter aanduiding van de juiste stick Y-as. Dit houdt geen steek, maar dit is hoe de meeste bestaande USB-Gamepads werken. Ik heb dit getest met behulp van Battlefield Bad Company 2, het werkt.
- Opmerking: Gebruik "absolute" voor iets zoals joysticks, maar "relatieve" voor dingen zoals muis.
Tot slot, het verslag-descriptor eruit:
USAGE_PAGE (generieke Desktop) gebruik (gamepad) collectie (toepassing) collectie (fysiek) USAGE_PAGE (Generic Desktop) USAGE (Game Pad) COLLECTION (Application) COLLECTION (Physical) USAGE_PAGE (Button) USAGE_MINIMUM (Button 1) USAGE_MAXIMUM (Button 16) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) REPORT_COUNT (16) REPORT_SIZE (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (X) USAGE (Y) USAGE (Z) USAGE (Rx) LOGICAL_MINIMUM (-127) LOGICAL_MAXIMUM (127) REPORT_SIZE (8) REPORT_COUNT (4) INPUT (Data,Var,Abs) END COLLECTION END COLLECTION
Nu dat we een verslag-descriptor hebben, hoe maken we onze AVR vertellen dit spul op de computer? Ga downloaden de officiële "HID Descriptor Tool" van http://www.usb.org/developers/hidpage/ . Gebruik het deze spullen in te zetten, en de tool zal het genereren van de juiste binaire matrix voor u.
Wanneer u uw resultaat, ga naar "File" -> "Save As" en zorg ervoor dat u kiest u "headerbestand (* .h)" opslaan in het dialoogvenster. Open vervolgens het bestand, het moet eruit
char ReportDescriptor[ some number here (size of array)] { a lot of bytes here };
Geweldig, de grootte van de matrix moet worden gekopieerd in V-USB's "usbconfig.h" waar het zegt "USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH", en "char ReportDescriptor" moet worden omgedoopt tot "PROGMEM char usbHidReportDescriptor" zodat het wordt opgeslagen in het geheugen van de flits van van de AVR. U eindigen met iets als:
PROGMEM char usbHidReportDescriptor[46] = { 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, 0x10, // USAGE_MAXIMUM (Button 16) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x95, 0x10, // REPORT_COUNT (16) 0x75, 0x01, // REPORT_SIZE (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) 0x09, 0x32, // USAGE (Z) 0x09, 0x33, // USAGE (Rx) 0x15, 0x81, // LOGICAL_MINIMUM (-127) 0x25, 0x7f, // LOGICAL_MAXIMUM (127) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x04, // REPORT_COUNT (4) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION 0xc0 // END_COLLECTION };
Dat stuk van code, plus de struct typedef we eerder deden, deel uitmaakt van onze broncode project (Zie hele broncode) later.
Meer lezen: