我正在构建一个适配器,通过USB将各种视频游戏控制器连接到PC。它的核心是Teensy 3.1微控制器,它使用Cortex-M4处理器。
M4能够处理原始USB数据包,从而模拟任何类型的USB设备。我已经成功地将其编程为呈现一个复合USB设备:
- 接口1,端点1:USB串口(用于调试)-状态接口
- 接口1,端点2:USB串行TX/RX接口
- 接口2,端点3:HID操纵杆
现在的问题是,我希望能够同时连接几种不同类型的游戏控制器(例如任天堂和超级任天堂)。我的适配器总共有15个以上的端口,这意味着我不能只为每个端口分配一个端点,因为USB总共只允许16个端点。
阅读HID报告描述符规范,我得到的印象是,可以在同一接口上定义多个独立的设备。然而,尽管我尽了最大的努力,我似乎还是无法做到这一点。应用程序(如jstest-gtk
)只能看到一个巨大的操纵杆。
现在我使用这个报告描述符:
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
};
我曾希望能提供一个有8个按钮的操纵杆和一个有16个按钮的操作杆,但应用程序看到的是一个有24个按钮的单操纵杆。
这样定义多个独立的操纵杆真的可行吗?
我最近用mbed实现了一个类似的项目,并且可以确认只使用您所描述的报告描述符就可以定义多个操纵杆。
在Windows中,它应该只工作。对于Linux,需要使用HID_QUIRK_MULTI_INPUT
怪癖加载usbhid驱动程序。
# rmmod usbhid && modprobe usbhid quirks=0xVID:0xPID:0x40
其中VID
是您的供应商id,PID
是您的产品id。然后它应该在/dev/input
中显示为多个操纵杆设备。