PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard // LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard // Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x19, 0x00, // USAGE_MINIMUM (Reserved // (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM // (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
};
#define KEY_UP 82
#define KEY_DOWN 81
#define KEY_LEFT 80
#define KEY_RIGHT 79
/* -----------------------------*/
static void timerPoll(void)
{
static uchar timerCnt;
static uchar i;
if(TIFR & (1 << TOV1)){
TIFR = (1 << TOV1); /* clear overflow */
if(++timerCnt >= 63){ /* ~ 1 second interval */
timerCnt = 0;
if (!FlagKey) {
FlagKey = 1;
if (++i > 3)
i=0;
switch (i) {
case 0:
reportBuffer[0] = 0;
reportBuffer[1] = KEY_RIGHT;
break;
case 1:
reportBuffer[0] = 0;
reportBuffer[1] = KEY_DOWN;
break;
case 2:
reportBuffer[0] = 0;
reportBuffer[1] = KEY_LEFT;
break;
case 3:
reportBuffer[0] = 0;
reportBuffer[1] = KEY_UP;
break;
}
}
}
}
}
//
//
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard // LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard // Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x19, 0x00, // USAGE_MINIMUM (Reserved // (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM // (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
0x0105
0x0609
0x01A1
0x0705
0xE019
0xE729
0x0015
0x0125
0x0175
0x05
0x0281
0x0875
0x0195
0x0181
0x0019
0x0105
0x0209
0x01A1
0x0109
0x00A1
0x0905
0x0119
0x0329
0x0015
0x0125
0x0175
0x0395
0x0281
0x0575
0x01953
0x6529
0x0015
0x6525
0x0875
0x0695
0x0081
0x0805
0x0119
0x0529
0x0015
0x0125
0x0175
0x0595
0x0291
0x0375
0x0195
0x0191
0xC0
rom struct{byte report[HID_RPT01_SIZE];}hid_rpt01={
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x06, /* Usage (Keyboard) */
0xA1, 0x01, /* Collection (Application) */
0x05, 0x07, /* Usage page (Key Codes) */
0x19, 0xE0, /* Usage minimum (224) */
0x29, 0xE7, /* Usage maximum (231) */
0x15, 0x00, /* Logical minimum (0) */
0x25, 0x01, /* Logical maximum (1) */
0x75, 0x01, /* Report size (1) */
0x95, 0x08, /* Report count (8) */
0x81, 0x02, /* Input (data, variable, absolute) */
0x95, 0x01, /* Report count (1) */
0x75, 0x08, /* Report size (8) */
0x81, 0x01, /* Input (constant) */
0x95, 0x06, /* Report count (6) */
0x75, 0x08, /* Report size (8) */
0x15, 0x00, /* Logical minimum (0) */
0x25, 0x65, /* Logical maximum (101) */
0x05, 0x07, /* Usage page (key codes) */
0x19, 0x00, /* Usage minimum (0) */
0x29, 0x65, /* Usage maximum (101) */
0x81, 0x00, /* Input (data, array) */
0xC0}; /* End Collection */
rom struct{byte report[HID_RPT02_SIZE];}hid_rpt02={
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
0x09, 0x01, // USAGE (Consumer Control)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x01, // REPORT_ID (1)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x10, // REPORT_COUNT (16)
0x09, 0xe2, // USAGE (Mute) 0x01
0x09, 0xe9, // USAGE (Volume Up) 0x02
0x09, 0xea, // USAGE (Volume Down) 0x03
0x09, 0xcd, // USAGE (Play/Pause) 0x04
0x09, 0xb7, // USAGE (Stop) 0x05
0x09, 0xb6, // USAGE (Scan Previous Track) 0x06
0x09, 0xb5, // USAGE (Scan Next Track) 0x07
0x0a, 0x8a, 0x01, // USAGE (Mail) 0x08
0x0a, 0x92, 0x01, // USAGE (Calculator) 0x09
0x0a, 0x21, 0x02, // USAGE (www search) 0x0a
0x0a, 0x23, 0x02, // USAGE (www home) 0x0b
0x0a, 0x2a, 0x02, // USAGE (www favorites) 0x0c
0x0a, 0x27, 0x02, // USAGE (www refresh) 0x0d0x0a, 0x26, 0x02, // USAGE (www stop) 0x0e
0x0a, 0x25, 0x02, // USAGE (www forward) 0x0f
0x0a, 0x24, 0x02, // USAGE (www back) 0x10
0x81, 0x62, // INPUT (Data,Var,Abs,NPrf,Null)
0xc0,
// System Control Descriptor
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x80, /* Usage (System Control) */
0xA1, 0x01, /* Collection (Application) */
0x85, 0x02, /* Report ID 0x02 [SYSTEM CTRL] */
0x19, 0x82, /* Usage minimum (System Sleep) */
0x29, 0x83, /* Usage maximum (System Wake up) */
0x95, 0x02, /* Report count (2) */
0x81, 0x06, /*Input (data, variable, relative, Preferred) */
0x95, 0x06, /* Report count (6) */
0x81, 0x01, /*Input (Constant) */
0xC0 /*End Collection */
};
//Hid Table for interface:0 alternate:0 Length:0x3F
Descriptor_type_22_index_0_0_table:
DB 0x05,0x01
DB 0x09,0x06
DB 0xA1,0x01
DB 0x05,0x07 ;
DB 0x19,0xE0
DB 0x29,0xE7
DB 0x15,0x00
DB 0x25,0x01 ;
DB 0x75,0x01
DB 0x95,0x08
DB 0x81,0x02
DB 0x95,0x01 ;
DB 0x75,0x08
DB 0x81,0x03
DB 0x95,0x05
DB 0x75,0x01 ;
DB 0x05,0x08
DB 0x19,0x01
DB 0x29,0x05
DB 0x91,0x02 ;
DB 0x95,0x01
DB 0x75,0x03
DB 0x91,0x03
DB 0x95,0x06 ;
DB 0x75,0x08
DB 0x15,0x00
DB 0x25,0x65
DB 0x05,0x07 ;
DB 0x19,0x00
DB 0x29,0x65
DB 0x81,0x00
DB 0xC0
db 5h, 1h ; USAGE_PAGE (Generic Desktop)
db 9h, 6h ; USAGE (Keyboard)
db a1h, 1h ; COLLECTION (Application)
db 5h, 7h ; USAGE_PAGE (Keyboard)
db 19h, e0h ; USAGE_MINIMUM (Keyboard LeftControl)
db 29h, e7h ; USAGE_MAXIMUM (Keyboard Right GUI)
db 15h, 0h ; LOGICAL_MINIMUM (0)
db 25h, 1h ; LOGICAL_MAXIMUM (1)
db 75h, 1h ; REPORT_SIZE (1)
db 95h, 8h ; REPORT_COUNT (8)
db 81h, 2h ; INPUT (Data,Var,Abs)
db 95h, 1h ; REPORT_COUNT (1)
db 75h, 8h ; REPORT_SIZE (8)
db 81h, 3h ; INPUT (Cnst,Var,Abs)
db 95h, 5h ; REPORT_COUNT (5)
db 75h, 1h ; REPORT_SIZE (1)
db 5h, 8h ; USAGE_PAGE (LEDs)
db 19h, 1h ; USAGE_MINIMUM (Num Lock)
db 29h, 5h ; USAGE_MAXIMUM (Kana)
db 91h, 2h ; OUTPUT (Data,Var,Abs)
db 95h, 1h ; REPORT_COUNT (1)
db 75h, 3h ; REPORT_SIZE (3)
db 91h, 3h ; OUTPUT (Cnst,Var,Abs)
db 95h, 6h ; REPORT_COUNT (6)
db 75h, 8h ; REPORT_SIZE (8)
db 15h, 0h ; LOGICAL_MINIMUM (0)
db 25h, 65h ; LOGICAL_MAXIMUM (101)
db 5h, 7h ; USAGE_PAGE (Keyboard)
db 19h, 0h ; USAGE_MINIMUM (Reserved (no event indicated))
db 29h, 65h ; USAGE_MAXIMUM (Keyboard Application)
db 81h, 0h ; INPUT (Data,Ary,Abs)
db c0h ; END_COLLECTION
Usage Page and Usages for Audio Control
A device wanting to be to recognized as a HID audio control device must declare itself as being a Consumer Control device (usage 0x01), as defined in the Consumer Page (page 0x0C) in the Universal Serial Bus HID Usage Tables Version 1.0 specification. This means that its top-level application collection should be Usage Page (Consumer), Usage (Consumer Control).
When such a device is enumerated by the operating system, the supporting software (HIDSERVE.EXE) is installed and loaded on the host system. Table 1 outlines the Consumer Page audio controls that are supported in Windows 2000.
Table 1. Consumer Page audio controls supported in Windows 2000.
Usage | Usage Name | Usage Type |
0xE0 | Volume* | Linear Control (LC) |
0xE2 | Mute* | On/Off Control (OOC) |
0xE3 | Bass | Linear Control (LC) |
0xE4 | Treble | Linear Control (LC) |
0xE5 | Bass Boost* | On/Off Control (OOC) |
0xE7 | Loudness | On/Off Control (OOC) |
0xE9 | Volume Increment* | Re-trigger Control (RTC) |
0xEA | Volume Decrement* | Re-trigger Control (RTC) |
0x152 | Bass Increment | Re-trigger Control (RTC) |
0x153 | Bass Decrement | Re-trigger Control (RTC) |
0x154 | Treble Increment | Re-trigger Control (RTC) |
0x155 | Treble Decrement | Re-trigger Control (RTC) |
The Volume, Bass, and Treble usages (of type LC) should be deployed for controls that generate both increment and decrement data represented by a 2-bit value, whereas the associated Increment and Decrement usages (of type RTC) should be deployed for pairs of one-bit controls (traditional button controls). The hardware design and implementation determines what usage types are appropriate for the HID firmware implementation for a particular device.
It's also important to notice that any re-triggering of events should be done by software timers in the host system, and not by hardware timers in the device itself. For example, if the user keeps pressing the Volume Increment button, the device should only generate one input report with this state information. Host software will perform the actual re-triggering of events that will lead to continuous increments of the volume until the device generates another input report indicating that the button has been released or until the maximum volume has been reached.
Key Codes For Scan Code Set 2:
ACPI key | Make | Break | Windows Virtual Key |
Power Event | E0 37 | E0 F0 37 | N/A |
Sleep Event | E0 3F | E0 F0 3F | N/A |
Wake Event | E0 5E | E0 F0 5E | N/A |
ACPI Key | Usage Page | Usage Index (Dec) | Usage Index (Hex) | Typical AT-101 position |
Power Event | 0x01 | 129 | 81 | N/A |
Sleep Event | 0x01 | 130 | 82 | N/A |
Wake Event | 0x01 | 131 | 83 | N/A |