This page shows the unique attributes for a Harmony USB Human Interface Device (HID) device project. To get the most out of this page it is useful to have reviewed the USB Device Page showing the Harmony features common to all device projects. After finishing this page you should be able to more easily follow the step-by-step description of Developer Help's example HID device project.
HID devices respond to host requests by returning a data element called an HID Report. The length and format of the HID Report is set by the HID Report Descriptor. It is the responsibility of the application to format the HID report in compliance with the HID report descriptor.
The sample Harmony USB projects use some of the most common HID report examples including a mouse, a keyboard and a user-defined protocol. This examples below are the HID Report formats for a simple three-button mouse and a game pad controller.
|bit 7||bit 6||bit 5||bit 4||bit 3||bit 3||bit 1||bit 0|
|Byte 0||- - -||- - -||- - -||- - -||- - -||Left Button||Middle Button||Right Button|
|Byte 1||X axis relative movement as signed char|
|Byte 2||Y axis relative movement as signed char|
|bit 7||bit 6||bit 5||bit 4||bit 3||bit 3||bit 1||bit 0|
|Byte 2||Left X axis as signed char|
|Byte 3||Left Y as signed char|
|Byte 4||Right X axis as signed char|
|Byte 5||Right Y as signed char|
HID Report Descriptor
The HID Report Descriptor resides in the device and defines the format which the device will send messages to the host. This information is shared with the host during enumeration.
The example below shows the code defining a HID Report Descriptor for a simple three-button mouse. The report indicates three bytes will be sent:
- The first byte contains three single elements which are input variables, and five one-bit inputs which are constants (i.e. padding)
- The second and third bytes each have a range of -127 to +127 and their input is variable (set by the applications).
Device Descriptor Table
The device descriptor table is the mechanism by which a device informs the host of the communication expectations of the device. The descriptor table is read from the device by the host during the enumeration process. There is very little room for variance with the Descriptor Table for HID Devices. The USB standard for HID devices dictate much of the descriptor table contents. All HID device descriptor table have these common attributes:
- At least one Interface must exist with the class code for a HID device
- The HID interface will have exactly two data endpoints (Endpoint1 IN and Endpoint1 OUT)
- Both endpoints will have Interrupt Transfer types, be 64 bytes in length, and be scheduled to be polled every frame
USB specifications allow the developer to select the Vendor/Product ID numbers, power consumption figures, as well as any identification text strings used.
Below is an example of a Device Descriptor for a single configuration HID device. The device configuration has a maximum power consumption of 50 ma, and a Vendor ID/Product ID (VID/PID) of 0x0480/0x0000. There are two identifying text strings for this device.
Driver Event Handler
Harmony USB projects schedule a HID Driver Task (either DRV_USBFS_Tasks or DRV_USBHS_Tasks) to run on each iteration of the main while loop. When the device is enumerated a user-written function is designated as the HID Driver Event Handler by USB_DEVICE_HID_EventHandlerSet().
The Driver task monitors the communication between the host and the device. When certain events are detected the user-written event handler is called. The event handler will then process the following events:
|HID Events Detected by Driver Function||Description|
|USB_DEVICE_HID_EVENT_GET_REPORT||a GET REPORT command received from the host|
|USB_DEVICE_HID_EVENT_SET_REPORT||a SET REPORT command received from the host|
|USB_DEVICE_HID_EVENT_REPORT_SENT||The data in Endpoint1 IN has successfully been
sent to the host
|USB_DEVICE_HID_EVENT_REPORT_RECEIVED||A data packet has been received from the
and has been placed in Endpoint 1 OUT
|USB_DEVICE_HID_EVENT_SET_IDLE||SET IDLE command received from the host. The
device will set the new idle rate.
|USB_DEVICE_HID_EVENT_GET_IDLE||GET IDLE command received from host. The device
responds by sending the current idle rate value.
|USB_DEVICE_HID_EVENT_SET_PROTOCOL||SET PROTOCOL command received from host
device will accept the new protocol value
|USB_DEVICE_HID_EVENT_GET_PROTOCOL||GET PROTOCOL command received. The device
returns the value of the current protocol
|USB_DEVICE_HID_EVENT_CONTROL_TRANSFER_DATA_SENT||The host has sent a control packet
to the device
|USB_DEVICE_HID_EVENT_CONTROL_TRANSFER_DATA_RECEIVED||The host has a received a control
packet response from the device
|USB_DEVICE_HID_EVENT_CONTROL_TRANSFER_DATA_ABORTED||Host has aborted a control transfer|
How is the Driver Event Handler used in an Application?
One of the most common usages of the HID Event Handler is to inform the application of either the receipt or the successful transmission of an HID Report. The code below shows an application program working with the a sample event handler to track the transmission of a report.
Sample HID Event Handler
// Application HID Event Handler Code
void APP_USBDeviceHIDEventHandler(USB_DEVICE_HID_INDEX hidInstance,
USB_DEVICE_HID_EVENT event, void * eventData, uintptr_t userData)
appdata.SendBufferEmpty = TRUE ; // Set a flag for the application program.
// Registering the HID Event Handler
APP_USBDeviceHIDEventHandler, (uintptr_t)&appdata) ;
An Application communicating with the sample HID Event Handler
if (appdata.SendBufferEmpty == TRUE) // Can the data be sent?
&appReport, sizeof(appReport)); // initiate sending the HID Report.
appdata.SendBufferEmpty = FALSE ; // Clear the flag
commdata.state = WAIT_FOR_HID_REPORT_TO_BE_SENT ;
if (appdata.SendbufferEmpty == TRUE) // Did EventHandler Set the flag?
commdata.state = DATA_SENT: // If so, the data was sent