usb_gamepad.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright (c) 2026, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifndef USB_GAMEPAD_H
  7. #define USB_GAMEPAD_H
  8. #include "usb_hid.h"
  9. /*
  10. * GAMEPAD BUTTON LAYOUT
  11. *
  12. * ____________________________ __
  13. * / [__L2__] [__R2__] \ |
  14. * / [__ L1 __] [__ R1 __] \ | Triggers
  15. * __/________________________________\__ __|
  16. * / _ \ |
  17. * / /\ __ (B4) \ |
  18. * / || __ |A1| __ _ _ \ | Main Pad
  19. * | <===DP===> |S1| |S2| (B3) -|- (B2)| |
  20. * \ || ¯¯ ¯¯ _ / |
  21. * /\ \/ / \ / \ (B1) /\ __|
  22. * / \________ | LS | ____ | RS | _______/ \ |
  23. * | / \ \___/ / \ \___/ / \ | | Sticks
  24. * | / \_____/ \_____/ \ | __|
  25. * | / L3 R3 \ |
  26. * \_____/ \_____/
  27. *
  28. * |________|______| |______|___________|
  29. * D-Pad Left Right Face
  30. * Stick Stick Buttons
  31. *
  32. * Extended: A2=Touchpad/Capture A3=Mute L4/R4=Paddles
  33. */
  34. // W3C Gamepad API standard button order
  35. // Bit position = W3C button index (trivial conversion: 1 << index)
  36. //
  37. // Gamepad XInput Switch PS3/4/5 DInput
  38. // ------ ------ ------ ------- ------
  39. // Face buttons (right cluster)
  40. #define USB_GAMEPAD_BUTTON_B1 (1 << 0) // A B Cross 2
  41. #define USB_GAMEPAD_BUTTON_B2 (1 << 1) // B A Circle 3
  42. #define USB_GAMEPAD_BUTTON_B3 (1 << 2) // X Y Square 1
  43. #define USB_GAMEPAD_BUTTON_B4 (1 << 3) // Y X Triangle 4
  44. // Shoulder buttons
  45. #define USB_GAMEPAD_BUTTON_L1 (1 << 4) // LB L L1 5
  46. #define USB_GAMEPAD_BUTTON_R1 (1 << 5) // RB R R1 6
  47. #define USB_GAMEPAD_BUTTON_L2 (1 << 6) // LT ZL L2 7
  48. #define USB_GAMEPAD_BUTTON_R2 (1 << 7) // RT ZR R2 8
  49. // Center cluster
  50. #define USB_GAMEPAD_BUTTON_S1 (1 << 8) // Back - Select 9
  51. #define USB_GAMEPAD_BUTTON_S2 (1 << 9) // Start + Start 10
  52. // Stick clicks
  53. #define USB_GAMEPAD_BUTTON_L3 (1 << 10) // LS LS L3 11
  54. #define USB_GAMEPAD_BUTTON_R3 (1 << 11) // RS RS R3 12
  55. // D-pad
  56. #define USB_GAMEPAD_BUTTON_DU (1 << 12) // D-Up D-Up D-Up Hat
  57. #define USB_GAMEPAD_BUTTON_DD (1 << 13) // D-Down D-Down D-Down Hat
  58. #define USB_GAMEPAD_BUTTON_DL (1 << 14) // D-Left D-Left D-Left Hat
  59. #define USB_GAMEPAD_BUTTON_DR (1 << 15) // D-Right D-Right D-Right Hat
  60. // Auxiliary
  61. #define USB_GAMEPAD_BUTTON_A1 (1 << 16) // Guide Home PS 13
  62. #define USB_GAMEPAD_BUTTON_A2 (1 << 17) // - Capture Touchpad 14
  63. #define USB_GAMEPAD_BUTTON_A3 (1 << 18) // - - Mute -
  64. #define USB_GAMEPAD_BUTTON_A4 (1 << 19) // - - - -
  65. // Paddles (extended)
  66. #define USB_GAMEPAD_BUTTON_L4 (1 << 20) // P1 - - -
  67. #define USB_GAMEPAD_BUTTON_R4 (1 << 21) // P2 - - -
  68. #define XINPUT_VID 0x045E // Microsoft
  69. #define XINPUT_PID 0x028E // Xbox 360 Controller
  70. #define XINPUT_BCD_DEVICE 0x0114 // v1.14
  71. /* XInput (Xbox 360) USB */
  72. // XInput Interface Class/Subclass/Protocol
  73. #define XINPUT_INTERFACE_CLASS 0xFF
  74. #define XINPUT_INTERFACE_SUBCLASS 0x5D
  75. #define XINPUT_INTERFACE_PROTOCOL 0x01
  76. #define XINPUT_BUTTON_MASK_UP (1U << 0)
  77. #define XINPUT_BUTTON_MASK_DOWN (1U << 1)
  78. #define XINPUT_BUTTON_MASK_LEFT (1U << 2)
  79. #define XINPUT_BUTTON_MASK_RIGHT (1U << 3)
  80. #define XINPUT_BUTTON_MASK_START (1U << 4)
  81. #define XINPUT_BUTTON_MASK_BACK (1U << 5)
  82. #define XINPUT_BUTTON_MASK_L3 (1U << 6)
  83. #define XINPUT_BUTTON_MASK_R3 (1U << 7)
  84. #define XINPUT_BUTTON_MASK_LB (1U << 8)
  85. #define XINPUT_BUTTON_MASK_RB (1U << 9)
  86. #define XINPUT_BUTTON_MASK_GUIDE (1U << 10)
  87. //#define XINPUT_BUTTON_MASK_UNUSED (1U << 11)
  88. #define XINPUT_BUTTON_MASK_A (1U << 12)
  89. #define XINPUT_BUTTON_MASK_B (1U << 13)
  90. #define XINPUT_BUTTON_MASK_X (1U << 14)
  91. #define XINPUT_BUTTON_MASK_Y (1U << 15)
  92. // LED patterns for report_id 0x01
  93. #define XINPUT_LED_OFF 0x00
  94. #define XINPUT_LED_BLINK 0x01
  95. #define XINPUT_LED_FLASH_1 0x02
  96. #define XINPUT_LED_FLASH_2 0x03
  97. #define XINPUT_LED_FLASH_3 0x04
  98. #define XINPUT_LED_FLASH_4 0x05
  99. #define XINPUT_LED_ON_1 0x06
  100. #define XINPUT_LED_ON_2 0x07
  101. #define XINPUT_LED_ON_3 0x08
  102. #define XINPUT_LED_ON_4 0x09
  103. #define XINPUT_LED_ROTATE 0x0A
  104. #define XINPUT_LED_BLINK_SLOW 0x0B
  105. #define XINPUT_LED_BLINK_SLOW_1 0x0C
  106. #define XINPUT_LED_BLINK_SLOW_2 0x0D
  107. struct xinput_in_report {
  108. uint8_t report_id; /* Always 0x00 */
  109. uint8_t report_size; /* Always 0x14 (20) */
  110. uint16_t buttons; /* DPAD, Start, Back, L3, R3, LB, RB, Guide, A, B, X, Y */
  111. uint8_t lt; /* Left trigger (0-255) */
  112. uint8_t rt; /* Right trigger (0-255) */
  113. int16_t lx; /* Left stick X (-32768 to 32767) */
  114. int16_t ly; /* Left stick Y (-32768 to 32767) */
  115. int16_t rx; /* Right stick X (-32768 to 32767) */
  116. int16_t ry; /* Right stick Y (-32768 to 32767) */
  117. uint8_t reserved[6]; /* Reserved/padding */
  118. } __PACKED;
  119. struct xinput_out_report {
  120. uint8_t report_id; // 0x00 = rumble, 0x01 = LED
  121. uint8_t report_size; // 0x08
  122. uint8_t led; // LED pattern (0x00 for rumble)
  123. uint8_t rumble_l; // Left motor (large, 0-255)
  124. uint8_t rumble_r; // Right motor (small, 0-255)
  125. uint8_t reserved[3]; // Padding
  126. } __PACKED;
  127. // clang-format off
  128. #define XINPUT_DESCRIPTOR_LEN (9 + 16 + 7 + 7)
  129. #define XINPUT_DESCRIPTOR_INIT(bInterfaceNumber, out_ep, in_ep) \
  130. USB_INTERFACE_DESCRIPTOR_INIT(bInterfaceNumber, 0x00, 0x02, 0xff, 0x5d, 0x01, 0x00), /* XInput proprietary descriptor (0x21) */ \
  131. 16, 0x21, 0x00, 0x01, 0x01, 0x24, in_ep, 0x14, 0x03, 0x00, 0x03, 0x13, out_ep, 0x00, 0x03, 0x00, \
  132. USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x03, 32, 0x01), \
  133. USB_ENDPOINT_DESCRIPTOR_INIT(out_ep, 0x03, 32, 0x08)
  134. // clang-format on
  135. #define SWITCH_VID 0x0F0D // 0x057E Nintendo Pro Controller
  136. #define SWITCH_PID 0x0092 // 0x2009
  137. #define SWITCH_BCD_DEVICE 0x0100 // v1.00
  138. // Button masks (16-bit)
  139. #define SWITCH_MASK_Y (1U << 0)
  140. #define SWITCH_MASK_B (1U << 1)
  141. #define SWITCH_MASK_A (1U << 2)
  142. #define SWITCH_MASK_X (1U << 3)
  143. #define SWITCH_MASK_L (1U << 4)
  144. #define SWITCH_MASK_R (1U << 5)
  145. #define SWITCH_MASK_ZL (1U << 6)
  146. #define SWITCH_MASK_ZR (1U << 7)
  147. #define SWITCH_MASK_MINUS (1U << 8)
  148. #define SWITCH_MASK_PLUS (1U << 9)
  149. #define SWITCH_MASK_L3 (1U << 10)
  150. #define SWITCH_MASK_R3 (1U << 11)
  151. #define SWITCH_MASK_HOME (1U << 12)
  152. #define SWITCH_MASK_CAPTURE (1U << 13)
  153. // D-pad / Hat switch values
  154. #define SWITCH_HAT_UP 0x00
  155. #define SWITCH_HAT_UP_RIGHT 0x01
  156. #define SWITCH_HAT_RIGHT 0x02
  157. #define SWITCH_HAT_DOWN_RIGHT 0x03
  158. #define SWITCH_HAT_DOWN 0x04
  159. #define SWITCH_HAT_DOWN_LEFT 0x05
  160. #define SWITCH_HAT_LEFT 0x06
  161. #define SWITCH_HAT_UP_LEFT 0x07
  162. #define SWITCH_HAT_CENTER 0x08
  163. // Analog stick range
  164. #define SWITCH_JOYSTICK_MIN 0x00
  165. #define SWITCH_JOYSTICK_MID 0x80
  166. #define SWITCH_JOYSTICK_MAX 0xFF
  167. struct switch_in_report {
  168. uint16_t buttons; // 16 button bits
  169. uint8_t hat; // D-pad (hat switch, 0-8)
  170. uint8_t lx; // Left stick X (0-255, 128 = center)
  171. uint8_t ly; // Left stick Y (0-255, 128 = center)
  172. uint8_t rx; // Right stick X (0-255, 128 = center)
  173. uint8_t ry; // Right stick Y (0-255, 128 = center)
  174. uint8_t vendor; // Vendor-specific byte
  175. } __PACKED;
  176. struct switch_out_report {
  177. uint8_t data[8]; // Vendor-specific rumble data
  178. } __PACKED;
  179. #define HID_SWITCH_REPORT_DESC_SIZE 86
  180. // clang-format off
  181. #define SWITCH_DESCRIPTOR_LEN HID_CUSTOM_INOUT_DESCRIPTOR_LEN
  182. #define SWITCH_DESCRIPTOR_INIT(bInterfaceNumber, out_ep, in_ep) \
  183. HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, 0x00, HID_SWITCH_REPORT_DESC_SIZE, out_ep, in_ep, 64, 0x01)
  184. // clang-format on
  185. struct usb_gamepad_report {
  186. uint32_t buttons;
  187. uint8_t lt;
  188. uint8_t rt;
  189. uint8_t lx;
  190. uint8_t ly;
  191. uint8_t rx;
  192. uint8_t ry;
  193. };
  194. #endif /* USB_GAMEPAD_H */