模拟游戏设备 - Raspberry PI Zero [英] Emulate a Gaming Device - Raspberry PI Zero

查看:18
本文介绍了模拟游戏设备 - Raspberry PI Zero的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将我的 Raspberry PI Zero 用作 HID 设备(操纵杆).

Hi I want to use my Raspberry PI Zero as a HID Device (Joystick).

当我将 Raspberry PI Zero USB 端口连接到我的 PC 时,我希望它显示为操纵杆并添加 X &Y 轴,我目前设法将树莓派零显示为键盘并向其发送击键.通过使用 this 页面作为参考,有人知道我的想法是否真的可行吗?

When I connect my Raspberry PI Zero USB port to my PC I want it to show up as a joystick and add X & Y Axis to it, I currently managed to show the raspberry pi zero as a keyboard and send keystrokes to it. By using this page as reference, Anyone knows if my idea is actually possible?

推荐答案

应该是可以的(但我没有 PI 硬件来测试它).

It should be possible (but I don't have the PI hardware to test it on).

链接中的报告描述符指定了仅限键盘的 HID 报告描述符 - 即使标题是键盘/鼠标/操纵杆 (HID)":

The report descriptor in your link specifies a keyboard-only HID report descriptor - even though the heading is "Keyboard / Mouse / Joystick (HID)":

echo -ne \x05\x01\x09\x06\xa1\x01\x05\x07\x19\xe0\x29\xe7\x15\x00
\x25\x01\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x03
\x95\x05\x75\x01\x05\x08\x19\x01\x29\x05\x91\x02\x95\x01
\x75\x03\x91\x03\x95\x06\x75\x08\x15\x00\x25\x65\x05\x07
\x19\x00\x29\x65\x81\x00\xc0 > functions/hid.usb0/report_desc

...解码为:

//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------

/*
05 01        (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page 
09 06        (LOCAL)  USAGE              0x00010006 Keyboard (CA=Application Collection) 
A1 01        (MAIN)   COLLECTION         0x00000001 Application (Usage=0x00010006: Page=Generic Desktop Page, Usage=Keyboard, Type=CA)
05 07          (GLOBAL) USAGE_PAGE         0x0007 Keyboard/Keypad Page 
19 E0          (LOCAL)  USAGE_MINIMUM      0x000700E0 Keyboard Left Control (DV=Dynamic Value) 
29 E7          (LOCAL)  USAGE_MAXIMUM      0x000700E7 Keyboard Right GUI (DV=Dynamic Value) 
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0)  <-- Info: Consider replacing 15 00 with 14
25 01          (GLOBAL) LOGICAL_MAXIMUM    0x01 (1)  
75 01          (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field  
95 08          (GLOBAL) REPORT_COUNT       0x08 (8) Number of fields  
81 02          (MAIN)   INPUT              0x00000002 (8 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 01          (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field  
81 03          (MAIN)   INPUT              0x00000003 (1 field x 8 bits) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 05          (GLOBAL) REPORT_COUNT       0x05 (5) Number of fields  
75 01          (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field  
05 08          (GLOBAL) USAGE_PAGE         0x0008 LED Indicator Page 
19 01          (LOCAL)  USAGE_MINIMUM      0x00080001 Num Lock (OOC=On/Off Control) 
29 05          (LOCAL)  USAGE_MAXIMUM      0x00080005 Kana (OOC=On/Off Control) 
91 02          (MAIN)   OUTPUT             0x00000002 (5 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 01          (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
75 03          (GLOBAL) REPORT_SIZE        0x03 (3) Number of bits per field  
91 03          (MAIN)   OUTPUT             0x00000003 (1 field x 3 bits) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 06          (GLOBAL) REPORT_COUNT       0x06 (6) Number of fields  
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field  
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0 <-- Info: Consider replacing 15 00 with 14
25 65          (GLOBAL) LOGICAL_MAXIMUM    0x65 (101)  
05 07          (GLOBAL) USAGE_PAGE         0x0007 Keyboard/Keypad Page 
19 00          (LOCAL)  USAGE_MINIMUM      0x00070000 Keyboard No event indicated (Sel=Selector) 
29 65          (LOCAL)  USAGE_MAXIMUM      0x00070065 Keyboard Application (Sel=Selector) 
81 00          (MAIN)   INPUT              0x00000000 (6 fields x 8 bits) 0=Data 0=Array 0=Absolute 
C0           (MAIN)   END_COLLECTION     Application 
*/

//--------------------------------------------------------------------------------
// Keyboard/Keypad Page inputReport (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
                                                     // No REPORT ID byte
                                                     // Collection: Keyboard
  uint8_t  KB_KeyboardKeyboardLeftControl : 1;       // Usage 0x000700E0: Keyboard Left Control, Value = 0 to 1
  uint8_t  KB_KeyboardKeyboardLeftShift : 1;         // Usage 0x000700E1: Keyboard Left Shift, Value = 0 to 1
  uint8_t  KB_KeyboardKeyboardLeftAlt : 1;           // Usage 0x000700E2: Keyboard Left Alt, Value = 0 to 1
  uint8_t  KB_KeyboardKeyboardLeftGui : 1;           // Usage 0x000700E3: Keyboard Left GUI, Value = 0 to 1
  uint8_t  KB_KeyboardKeyboardRightControl : 1;      // Usage 0x000700E4: Keyboard Right Control, Value = 0 to 1
  uint8_t  KB_KeyboardKeyboardRightShift : 1;        // Usage 0x000700E5: Keyboard Right Shift, Value = 0 to 1
  uint8_t  KB_KeyboardKeyboardRightAlt : 1;          // Usage 0x000700E6: Keyboard Right Alt, Value = 0 to 1
  uint8_t  KB_KeyboardKeyboardRightGui : 1;          // Usage 0x000700E7: Keyboard Right GUI, Value = 0 to 1
  uint8_t  pad_2;                                    // Pad
  uint8_t  KB_Keyboard[6];                           // Value = 0 to 101
} inputReport_t;


//--------------------------------------------------------------------------------
// LED Indicator Page outputReport (Device <-- Host)
//--------------------------------------------------------------------------------

typedef struct
{
                                                     // No REPORT ID byte
                                                     // Collection: Keyboard
  uint8_t  LED_KeyboardNumLock : 1;                  // Usage 0x00080001: Num Lock, Value = 0 to 1
  uint8_t  LED_KeyboardCapsLock : 1;                 // Usage 0x00080002: Caps Lock, Value = 0 to 1
  uint8_t  LED_KeyboardScrollLock : 1;               // Usage 0x00080003: Scroll Lock, Value = 0 to 1
  uint8_t  LED_KeyboardCompose : 1;                  // Usage 0x00080004: Compose, Value = 0 to 1
  uint8_t  LED_KeyboardKana : 1;                     // Usage 0x00080005: Kana, Value = 0 to 1
  uint8_t  : 3;                                      // Pad
} outputReport_t;

我认为至少需要更改 HID 报告描述符字节以指定操纵杆报告而不是键盘报告.有很多替代方案,但类似于以下定义了 8 位 x 轴和 y 轴以及 8 个按钮的内容可能是一个不错的起点:

I think at least the HID report descriptor bytes would need to be changed to specify a joystick report rather than a keyboard report. There are many alternatives, but something like the following, which defines an 8-bit x- and y-axis and 8 buttons, could be a good place to start:

//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------

/*
05 01        (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page 
09 04        (LOCAL)  USAGE              0x00010004 Joystick (CA=Application Collection) 
A1 01        (MAIN)   COLLECTION         0x00000001 Application (Usage=0x00010004: Page=Generic Desktop Page, Usage=Joystick, Type=CA)
15 81          (GLOBAL) LOGICAL_MINIMUM    0x81 (-127)  
25 7F          (GLOBAL) LOGICAL_MAXIMUM    0x7F (127)  
09 01          (LOCAL)  USAGE              0x00010001 Pointer (CP=Physical Collection) 
A1 00          (MAIN)   COLLECTION         0x00000000 Physical (Usage=0x00010001: Page=Generic Desktop Page, Usage=Pointer, Type=CP)
09 30            (LOCAL)  USAGE              0x00010030 X (DV=Dynamic Value) 
09 31            (LOCAL)  USAGE              0x00010031 Y (DV=Dynamic Value) 
75 08            (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field  
95 02            (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (2 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0             (MAIN)   END_COLLECTION     Physical 
05 09          (GLOBAL) USAGE_PAGE         0x0009 Button Page 
19 01          (LOCAL)  USAGE_MINIMUM      0x00090001 Button 1 Primary/trigger (MULTI=Selector, On/Off, Momentary, or One Shot) 
29 08          (LOCAL)  USAGE_MAXIMUM      0x00090008 Button 8 (MULTI=Selector, On/Off, Momentary, or One Shot) 
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0)  <-- Info: Consider replacing 15 00 with 14
25 01          (GLOBAL) LOGICAL_MAXIMUM    0x01 (1)  
75 01          (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field  
95 08          (GLOBAL) REPORT_COUNT       0x08 (8) Number of fields  
81 02          (MAIN)   INPUT              0x00000002 (8 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0           (MAIN)   END_COLLECTION     Application 
*/

//--------------------------------------------------------------------------------
// Generic Desktop Page inputReport (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
                                                     // No REPORT ID byte
                                                     // Collection: Joystick Pointer
  int8_t   GD_JoystickPointerX;                      // Usage 0x00010030: X, Value = -127 to 127
  int8_t   GD_JoystickPointerY;                      // Usage 0x00010031: Y, Value = -127 to 127
                                                     // Collection: Joystick
  uint8_t  BTN_JoystickButton1 : 1;                  // Usage 0x00090001: Button 1 Primary/trigger, Value = 0 to 1
  uint8_t  BTN_JoystickButton2 : 1;                  // Usage 0x00090002: Button 2 Secondary, Value = 0 to 1
  uint8_t  BTN_JoystickButton3 : 1;                  // Usage 0x00090003: Button 3 Tertiary, Value = 0 to 1
  uint8_t  BTN_JoystickButton4 : 1;                  // Usage 0x00090004: Button 4, Value = 0 to 1
  uint8_t  BTN_JoystickButton5 : 1;                  // Usage 0x00090005: Button 5, Value = 0 to 1
  uint8_t  BTN_JoystickButton6 : 1;                  // Usage 0x00090006: Button 6, Value = 0 to 1
  uint8_t  BTN_JoystickButton7 : 1;                  // Usage 0x00090007: Button 7, Value = 0 to 1
  uint8_t  BTN_JoystickButton8 : 1;                  // Usage 0x00090008: Button 8, Value = 0 to 1
} inputReport_t;

您可能还需要更改:

echo 1 > functions/hid.usb0/protocol
echo 1 > functions/hid.usb0/subclass

...它定义了一个 BOOT 键盘,以:

...which defines a BOOT keyboard, to:

echo 0 > functions/hid.usb0/protocol
echo 0 > functions/hid.usb0/subclass

...表示设备没有特定的子类(例如 BOOT 设备)或协议(例如键盘或鼠标).

...which says that the device has no specific subclass (e.g. BOOT device) or protocol (e.g. keyboard or mouse).

可能还需要进行其他更改,但正如我所说,我没有可以试验的硬件.

There may be other changes necessary but, as I said, I don't have the hardware to experiment with.

我希望这会有所帮助.

这篇关于模拟游戏设备 - Raspberry PI Zero的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆