I am trying to emulate a USB-HID gamepad/controller using the MSP430 with 7-14 analog inputs but I had trouble getting the descriptors right for my custom USB-HID device.
I came across this code online: https://github.com/TI-FIRST/MSP430-Gamepad which worked great to get the MSP430 up and running as a gamepad with only 8 analog inputs.
The main.c file contains instructions to change the report structure:
- This example functions as a gamepad on the host. The gamepad has a HID report as described in
- report_desc_HID0 variable in descriptors.c. Please note that if this report structure is
- changed then the following lengths need to be updated -
-
- #define report_desc_size_HID0 in descriptors.h needs to be updated with descriptor size
-
- report_desc_size and report_len_input need t be updated in descriptors.c
- As is this demo will enumerate with 18 bytes of input report and 2 bytes of output report
- The input and output report structures for the gamepad as described in USB_gamepad.h
- The input reports are used to report ADC values and status of buttons (GPIO)
- The output report is used to set/reset indicators (GPIO)
The descriptors currently in the descriptors.c file are:
UsagePage(USB_HID_GENERIC_DESKTOP),
Usage(USB_HID_JOYSTICK),
Collection(USB_HID_APPLICATION),
//
// The axis for the controller.
//
UsagePage(USB_HID_GENERIC_DESKTOP),
Usage (USB_HID_POINTER),
Collection (USB_HID_PHYSICAL),
//
// The X, Y and Z values which are specified as 8-bit absolute
// position values.
//
Usage (USB_HID_X),
Usage (USB_HID_Y),
Usage (USB_HID_Z),
Usage (USB_HID_RX),
Usage (USB_HID_RY),
Usage (USB_HID_RZ),
Usage (USB_HID_SLIDER),
Usage (USB_HID_DIAL),
//
// 8 16-bit absolute values.
//
ReportSize(16),
ReportCount(8),
Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE |
USB_HID_INPUT_ABS),
//
// Max 32 buttons.
//
UsagePage(USB_HID_BUTTONS),
UsageMinimum(1),
UsageMaximum(NUM_BUTTONS),
LogicalMinimum(0),
LogicalMaximum(1),
PhysicalMinimum(0),
PhysicalMaximum(1),
//
// 8 - 1 bit values for the buttons.
//
ReportSize(1),
ReportCount(32),
Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE |
USB_HID_INPUT_ABS),
//
// Max 16 indicator bits
//
UsagePage(USB_HID_BUTTONS),
UsageMinimum(1),
UsageMaximum(NUM_INDICATORS),
LogicalMinimum(0),
LogicalMaximum(1),
PhysicalMinimum(0),
PhysicalMaximum(1),
//
// 8 - 1 bit values for the leds.
//
ReportSize(1),
ReportCount(16),
Output(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE |
USB_HID_INPUT_ABS),
EndCollection,
EndCollection
I would like to change it to 14 16-bit analog inputs like this:
UsagePage(USB_HID_GENERIC_DESKTOP),
Usage(USB_HID_JOYSTICK),
Collection(USB_HID_APPLICATION),
//
// The axis for the controller.
//
UsagePage(USB_HID_GENERIC_DESKTOP),
Usage (USB_HID_POINTER),
Collection (USB_HID_PHYSICAL),
//
// The X, Y and Z values which are specified as 8-bit absolute
// position values.
//
Usage (USB_HID_X),
Usage (USB_HID_Y),
Usage (USB_HID_Z),
Usage (USB_HID_RX),
Usage (USB_HID_RY),
Usage (USB_HID_RZ),
Usage (USB_HID_SLIDER),
Usage (USB_HID_DIAL),
Usage (USB_HID_VX),
Usage (USB_HID_VY),
Usage (USB_HID_VZ),
Usage (USB_HID_VRX),
Usage (USB_HID_VRY),
Usage (USB_HID_VRZ),
//
// 8 16-bit absolute values.
//
ReportSize(16),
ReportCount(14),
Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE |
USB_HID_INPUT_ABS),
//
// Max 32 buttons.
//
UsagePage(USB_HID_BUTTONS),
UsageMinimum(1),
UsageMaximum(6),
LogicalMinimum(0),
LogicalMaximum(1),
PhysicalMinimum(0),
PhysicalMaximum(1),
//
// 8 - 1 bit values for the buttons.
//
ReportSize(1),
ReportCount(32),
Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE |
USB_HID_INPUT_ABS),
//
// Max 16 indicator bits
//
UsagePage(USB_HID_BUTTONS),
UsageMinimum(1),
UsageMaximum(6),
LogicalMinimum(0),
LogicalMaximum(1),
PhysicalMinimum(0),
PhysicalMaximum(1),
//
// 8 - 1 bit values for the leds.
//
ReportSize(1),
ReportCount(16),
Output(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE |
USB_HID_INPUT_ABS),
EndCollection,
EndCollection
However, I cannot figure out how to calculate the length/size/bytes of the descriptor. I tried going through the USB-HID spec (Device Class Definition for HID 1.11 | USB-IF) which states that items have a byte prefix, but I can't really figure out which items to count and how they add up. Apologies but I am very inexperienced in USB.
Would someone be able look at the code, and let me know what values I need in report_desc_size, report_len_input in the descriptor files plus anything else I need to change to expand the functionality of this code for 14 16-bit analog inputs.
P.S. To replicate and see the working gamepad, just upload the code to a dev kit and search 'Set up USB Game Controllers' on Windows, which should recognize it as a gamepad if everything is running correctly and the reports are being accepted.
The size of the report descriptor is
sizeof(report_desc_HID0)
. For convenience I'd recommend restructuring the code so you compute the descriptor length at compile time instead of hard-coding it.You're using macros to construct the descriptor, and each macro adds a fixed number of bytes. You've added six new
Usage
items, each of which expands to two bytes:If the original descriptor is 80 bytes, I'd guess the new descriptor size is 92 bytes.