2015-03-30 11 views
2

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

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

  • интерфейс 1, конечной точки 1: USB последовательный порт (для отладки) - интерфейс статуса
  • Интерфейс 1, конечная точка 2: USB последовательный интерфейс TX/RX
  • Interface 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 кнопками.

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

+0

Целью подключения нескольких контроллеров одновременно для многопользовательских игр или просто для того, чтобы один пользователь мог переключаться между контроллерами по желанию? Похоже, что в корпусе одного контроллера Teensy может мультиплексировать входы контроллера в один 16-кнопочный контроллер. –

+1

В идеале я хотел бы подключить сразу несколько контроллеров. На практике, вероятно, не более четырех будет использоваться сразу, но, например, у вас может быть один игрок, использующий контроллер SNES и один с N64, и вы захотите оставить их включенными и просто забрать и использовать. Я могу прибегнуть к переключению между парой за раз, но я бы предпочел, чтобы все подключенные контроллеры были представлены как джойстики во все времена. – Rena

+0

Это большая проблема. Я думаю, что самая простая вещь (честно говоря, я не знаю) заключалась бы в мультиплексировании нескольких контроллеров в один «плеер», чтобы вы представили четырех (или более) «игроков» в качестве конечных точек USB. Затем Teensy помещал в очередь входные отчеты всякий раз, когда на контроллере есть активность. –

ответ

2

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

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

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

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