USB: можно определить несколько разных HID джойстиков на одном интерфейсе?

Я создаю адаптер для подключения различных контроллеров видеоигр к ПК через USB. Сердцем этого является микроконтроллер Teensy 3.1, в котором используется процессор Cortex-M4.

M4 может работать с необработанными USB-пакетами и таким образом моделировать USB-устройство любого типа. Я успешно запрограммировал его для представления композитного устройства USB:

  • Интерфейс 1, конечная точка 1: последовательный порт USB (для отладки) - интерфейс состояния
  • Интерфейс 1, конечная точка 2: последовательный интерфейс USB TX/RX
  • Интерфейс 2, конечная точка 3: HID джойстик

Проблема в том, что я хочу иметь возможность подключать несколько разных типов игровых контроллеров одновременно (например, Nintendo и Super Nintendo). Всего у моего адаптера более 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 кнопками.

Можно ли на самом деле определить несколько независимых джойстиков таким образом?

1 ответ

Недавно я реализовал аналогичный проект с помощью mbed и могу подтвердить, что несколько джойстиков можно определить, используя только описатель отчета, как вы описали.

В Windows это должно просто работать. В Linux драйвер usbhid должен быть загружен с помощью HID_QUIRK_MULTI_INPUT галтель.

# rmmod usbhid && modprobe usbhid quirks=0xVID:0xPID:0x40

куда VID Ваш идентификатор поставщика, и PID это идентификатор вашего продукта. Затем он должен отображаться как несколько устройств джойстика в /dev/input,

Другие вопросы по тегам