I'm building an adaptor to connect various video game controllers to a PC via USB. The heart of it is the Teensy 3.1 microcontroller, which uses the Cortex-M4 processor.
The M4 is able to deal with raw USB packets and thus simulate any type of USB device. I've successfully programmed it to present a composite USB device:
- Interface 1, endpoint 1: USB serial port (for debugging) - status interface
- Interface 1, endpoint 2: USB serial TX/RX interface
- Interface 2, endpoint 3: HID joystick
The problem now is, I want to be able to connect several different types of game controller at once (e.g. Nintendo and Super Nintendo). In all my adaptor has more than 15 ports, which means I can't just assign one endpoint to each port, as USB allows only 16 endpoints total.
Reading the HID report descriptor spec, I get the impression that it's possible to define multiple independent devices on the same interface. However despite my best efforts, I can't seem to pull this off. Applications (such as jstest-gtk
) only see a single huge joystick.
Right now I'm using this report descriptor:
static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
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, 0x08, // Report Count (8)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x08, // Usage Maximum (Button #8)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x85, 0x02, // Report ID (2)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x10, // Report Count (16)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x10, // Usage Maximum (Button #16)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
};
I had hoped that would present one joystick with 8 buttons and one with 16, but instead applications see a single joystick with 24 buttons.
Is it actually possible to define multiple independent joysticks this way?