logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

usb_descriptor.c (51878B)


  1. /*
  2. * Copyright 2012 Jun Wako <wakojun@gmail.com>
  3. * This file is based on:
  4. * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
  5. * LUFA-120219/Demos/Device/Lowlevel/GenericHID
  6. */
  7. /*
  8. LUFA Library
  9. Copyright (C) Dean Camera, 2012.
  10. dean [at] fourwalledcubicle [dot] com
  11. www.lufa-lib.org
  12. */
  13. /*
  14. Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
  15. Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
  16. Permission to use, copy, modify, distribute, and sell this
  17. software and its documentation for any purpose is hereby granted
  18. without fee, provided that the above copyright notice appear in
  19. all copies and that both that the copyright notice and this
  20. permission notice and warranty disclaimer appear in supporting
  21. documentation, and that the name of the author not be used in
  22. advertising or publicity pertaining to distribution of the
  23. software without specific, written prior permission.
  24. The author disclaim all warranties with regard to this
  25. software, including all implied warranties of merchantability
  26. and fitness. In no event shall the author be liable for any
  27. special, indirect or consequential damages or any damages
  28. whatsoever resulting from loss of use, data or profits, whether
  29. in an action of contract, negligence or other tortious action,
  30. arising out of or in connection with the use or performance of
  31. this software.
  32. */
  33. #include "util.h"
  34. #include "report.h"
  35. #include "usb_descriptor.h"
  36. #include "usb_descriptor_common.h"
  37. #ifdef JOYSTICK_ENABLE
  38. # include "joystick.h"
  39. #endif
  40. #ifdef OS_DETECTION_ENABLE
  41. # include "os_detection.h"
  42. #endif
  43. #if defined(SERIAL_NUMBER) || (defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE)
  44. # define HAS_SERIAL_NUMBER
  45. # if defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE
  46. # include "hardware_id.h"
  47. # endif
  48. #endif // defined(SERIAL_NUMBER) || (defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE)
  49. // clang-format off
  50. /*
  51. * HID report descriptors
  52. */
  53. #ifdef KEYBOARD_SHARED_EP
  54. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  55. # define SHARED_REPORT_STARTED
  56. #else
  57. const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = {
  58. #endif
  59. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  60. HID_RI_USAGE(8, 0x06), // Keyboard
  61. HID_RI_COLLECTION(8, 0x01), // Application
  62. #ifdef KEYBOARD_SHARED_EP
  63. HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD),
  64. #endif
  65. // Modifiers (8 bits)
  66. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  67. HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control
  68. HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI
  69. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  70. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  71. HID_RI_REPORT_COUNT(8, 0x08),
  72. HID_RI_REPORT_SIZE(8, 0x01),
  73. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  74. // Reserved (1 byte)
  75. HID_RI_REPORT_COUNT(8, 0x01),
  76. HID_RI_REPORT_SIZE(8, 0x08),
  77. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  78. // Keycodes (6 bytes)
  79. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  80. HID_RI_USAGE_MINIMUM(8, 0x00),
  81. HID_RI_USAGE_MAXIMUM(8, 0xFF),
  82. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  83. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  84. HID_RI_REPORT_COUNT(8, 0x06),
  85. HID_RI_REPORT_SIZE(8, 0x08),
  86. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  87. // Status LEDs (5 bits)
  88. HID_RI_USAGE_PAGE(8, 0x08), // LED
  89. HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock
  90. HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana
  91. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  92. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  93. HID_RI_REPORT_COUNT(8, 0x05),
  94. HID_RI_REPORT_SIZE(8, 0x01),
  95. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  96. // LED padding (3 bits)
  97. HID_RI_REPORT_COUNT(8, 0x01),
  98. HID_RI_REPORT_SIZE(8, 0x03),
  99. HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
  100. HID_RI_END_COLLECTION(0),
  101. #ifndef KEYBOARD_SHARED_EP
  102. };
  103. #endif
  104. #ifdef MOUSE_ENABLE
  105. # ifndef MOUSE_SHARED_EP
  106. const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = {
  107. # elif !defined(SHARED_REPORT_STARTED)
  108. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  109. # define SHARED_REPORT_STARTED
  110. # endif
  111. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  112. HID_RI_USAGE(8, 0x02), // Mouse
  113. HID_RI_COLLECTION(8, 0x01), // Application
  114. # ifdef MOUSE_SHARED_EP
  115. HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
  116. # endif
  117. HID_RI_USAGE(8, 0x01), // Pointer
  118. HID_RI_COLLECTION(8, 0x00), // Physical
  119. // Buttons (8 bits)
  120. HID_RI_USAGE_PAGE(8, 0x09), // Button
  121. HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
  122. HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8
  123. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  124. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  125. HID_RI_REPORT_COUNT(8, 0x08),
  126. HID_RI_REPORT_SIZE(8, 0x01),
  127. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  128. # ifdef MOUSE_EXTENDED_REPORT
  129. // Boot protocol XY ignored in Report protocol
  130. HID_RI_REPORT_COUNT(8, 0x02),
  131. HID_RI_REPORT_SIZE(8, 0x08),
  132. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  133. # endif
  134. // X/Y position (2 or 4 bytes)
  135. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  136. HID_RI_USAGE(8, 0x30), // X
  137. HID_RI_USAGE(8, 0x31), // Y
  138. # ifndef MOUSE_EXTENDED_REPORT
  139. HID_RI_LOGICAL_MINIMUM(8, -127),
  140. HID_RI_LOGICAL_MAXIMUM(8, 127),
  141. HID_RI_REPORT_COUNT(8, 0x02),
  142. HID_RI_REPORT_SIZE(8, 0x08),
  143. # else
  144. HID_RI_LOGICAL_MINIMUM(16, -32767),
  145. HID_RI_LOGICAL_MAXIMUM(16, 32767),
  146. HID_RI_REPORT_COUNT(8, 0x02),
  147. HID_RI_REPORT_SIZE(8, 0x10),
  148. # endif
  149. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  150. # ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE
  151. HID_RI_COLLECTION(8, 0x02),
  152. // Feature report and padding (1 byte)
  153. HID_RI_USAGE(8, 0x48), // Resolution Multiplier
  154. HID_RI_REPORT_COUNT(8, 0x01),
  155. HID_RI_REPORT_SIZE(8, 0x02),
  156. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  157. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  158. HID_RI_PHYSICAL_MINIMUM(8, 1),
  159. HID_RI_PHYSICAL_MAXIMUM(8, POINTING_DEVICE_HIRES_SCROLL_MULTIPLIER),
  160. HID_RI_UNIT_EXPONENT(8, POINTING_DEVICE_HIRES_SCROLL_EXPONENT),
  161. HID_RI_FEATURE(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  162. HID_RI_PHYSICAL_MINIMUM(8, 0x00),
  163. HID_RI_PHYSICAL_MAXIMUM(8, 0x00),
  164. HID_RI_REPORT_SIZE(8, 0x06),
  165. HID_RI_FEATURE(8, HID_IOF_CONSTANT),
  166. # endif
  167. // Vertical wheel (1 or 2 bytes)
  168. HID_RI_USAGE(8, 0x38), // Wheel
  169. # ifndef WHEEL_EXTENDED_REPORT
  170. HID_RI_LOGICAL_MINIMUM(8, -127),
  171. HID_RI_LOGICAL_MAXIMUM(8, 127),
  172. HID_RI_REPORT_COUNT(8, 0x01),
  173. HID_RI_REPORT_SIZE(8, 0x08),
  174. # else
  175. HID_RI_LOGICAL_MINIMUM(16, -32767),
  176. HID_RI_LOGICAL_MAXIMUM(16, 32767),
  177. HID_RI_REPORT_COUNT(8, 0x01),
  178. HID_RI_REPORT_SIZE(8, 0x10),
  179. # endif
  180. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  181. // Horizontal wheel (1 or 2 bytes)
  182. HID_RI_USAGE_PAGE(8, 0x0C),// Consumer
  183. HID_RI_USAGE(16, 0x0238), // AC Pan
  184. # ifndef WHEEL_EXTENDED_REPORT
  185. HID_RI_LOGICAL_MINIMUM(8, -127),
  186. HID_RI_LOGICAL_MAXIMUM(8, 127),
  187. HID_RI_REPORT_COUNT(8, 0x01),
  188. HID_RI_REPORT_SIZE(8, 0x08),
  189. # else
  190. HID_RI_LOGICAL_MINIMUM(16, -32767),
  191. HID_RI_LOGICAL_MAXIMUM(16, 32767),
  192. HID_RI_REPORT_COUNT(8, 0x01),
  193. HID_RI_REPORT_SIZE(8, 0x10),
  194. # endif
  195. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  196. # ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE
  197. HID_RI_END_COLLECTION(0),
  198. # endif
  199. HID_RI_END_COLLECTION(0),
  200. HID_RI_END_COLLECTION(0),
  201. # ifndef MOUSE_SHARED_EP
  202. };
  203. # endif
  204. #endif
  205. #ifdef JOYSTICK_ENABLE
  206. # ifndef JOYSTICK_SHARED_EP
  207. const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] = {
  208. # elif !defined(SHARED_REPORT_STARTED)
  209. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  210. # define SHARED_REPORT_STARTED
  211. # endif
  212. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  213. HID_RI_USAGE(8, 0x04), // Joystick
  214. HID_RI_COLLECTION(8, 0x01), // Application
  215. # ifdef JOYSTICK_SHARED_EP
  216. HID_RI_REPORT_ID(8, REPORT_ID_JOYSTICK),
  217. # endif
  218. HID_RI_COLLECTION(8, 0x00), // Physical
  219. # if JOYSTICK_AXIS_COUNT > 0
  220. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  221. HID_RI_USAGE(8, 0x30), // X
  222. # if JOYSTICK_AXIS_COUNT > 1
  223. HID_RI_USAGE(8, 0x31), // Y
  224. # endif
  225. # if JOYSTICK_AXIS_COUNT > 2
  226. HID_RI_USAGE(8, 0x32), // Z
  227. # endif
  228. # if JOYSTICK_AXIS_COUNT > 3
  229. HID_RI_USAGE(8, 0x33), // Rx
  230. # endif
  231. # if JOYSTICK_AXIS_COUNT > 4
  232. HID_RI_USAGE(8, 0x34), // Ry
  233. # endif
  234. # if JOYSTICK_AXIS_COUNT > 5
  235. HID_RI_USAGE(8, 0x35), // Rz
  236. # endif
  237. # if JOYSTICK_AXIS_RESOLUTION == 8
  238. HID_RI_LOGICAL_MINIMUM(8, -JOYSTICK_MAX_VALUE),
  239. HID_RI_LOGICAL_MAXIMUM(8, JOYSTICK_MAX_VALUE),
  240. HID_RI_REPORT_COUNT(8, JOYSTICK_AXIS_COUNT),
  241. HID_RI_REPORT_SIZE(8, 0x08),
  242. # else
  243. HID_RI_LOGICAL_MINIMUM(16, -JOYSTICK_MAX_VALUE),
  244. HID_RI_LOGICAL_MAXIMUM(16, JOYSTICK_MAX_VALUE),
  245. HID_RI_REPORT_COUNT(8, JOYSTICK_AXIS_COUNT),
  246. HID_RI_REPORT_SIZE(8, 0x10),
  247. # endif
  248. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  249. # endif
  250. # ifdef JOYSTICK_HAS_HAT
  251. // Hat Switch (4 bits)
  252. HID_RI_USAGE(8, 0x39), // Hat Switch
  253. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  254. HID_RI_LOGICAL_MAXIMUM(8, 0x07),
  255. HID_RI_PHYSICAL_MINIMUM(8, 0),
  256. HID_RI_PHYSICAL_MAXIMUM(16, 315),
  257. HID_RI_UNIT(8, 0x14), // Degree, English Rotation
  258. HID_RI_REPORT_COUNT(8, 1),
  259. HID_RI_REPORT_SIZE(8, 4),
  260. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NULLSTATE),
  261. // Padding (4 bits)
  262. HID_RI_REPORT_COUNT(8, 0x04),
  263. HID_RI_REPORT_SIZE(8, 0x01),
  264. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  265. # endif
  266. # if JOYSTICK_BUTTON_COUNT > 0
  267. HID_RI_USAGE_PAGE(8, 0x09), // Button
  268. HID_RI_USAGE_MINIMUM(8, 0x01),
  269. HID_RI_USAGE_MAXIMUM(8, JOYSTICK_BUTTON_COUNT),
  270. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  271. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  272. HID_RI_REPORT_COUNT(8, JOYSTICK_BUTTON_COUNT),
  273. HID_RI_REPORT_SIZE(8, 0x01),
  274. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  275. # if (JOYSTICK_BUTTON_COUNT % 8) != 0
  276. HID_RI_REPORT_COUNT(8, 8 - (JOYSTICK_BUTTON_COUNT % 8)),
  277. HID_RI_REPORT_SIZE(8, 0x01),
  278. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  279. # endif
  280. # endif
  281. HID_RI_END_COLLECTION(0),
  282. HID_RI_END_COLLECTION(0),
  283. # ifndef JOYSTICK_SHARED_EP
  284. };
  285. # endif
  286. #endif
  287. #ifdef DIGITIZER_ENABLE
  288. # ifndef DIGITIZER_SHARED_EP
  289. const USB_Descriptor_HIDReport_Datatype_t PROGMEM DigitizerReport[] = {
  290. # elif !defined(SHARED_REPORT_STARTED)
  291. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  292. # define SHARED_REPORT_STARTED
  293. # endif
  294. HID_RI_USAGE_PAGE(8, 0x0D), // Digitizers
  295. HID_RI_USAGE(8, 0x01), // Digitizer
  296. HID_RI_COLLECTION(8, 0x01), // Application
  297. # ifdef DIGITIZER_SHARED_EP
  298. HID_RI_REPORT_ID(8, REPORT_ID_DIGITIZER),
  299. # endif
  300. HID_RI_USAGE(8, 0x20), // Stylus
  301. HID_RI_COLLECTION(8, 0x00), // Physical
  302. // In Range, Tip Switch & Barrel Switch (3 bits)
  303. HID_RI_USAGE(8, 0x32), // In Range
  304. HID_RI_USAGE(8, 0x42), // Tip Switch
  305. HID_RI_USAGE(8, 0x44), // Barrel Switch
  306. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  307. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  308. HID_RI_REPORT_COUNT(8, 0x03),
  309. HID_RI_REPORT_SIZE(8, 0x01),
  310. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  311. // Padding (5 bits)
  312. HID_RI_REPORT_COUNT(8, 0x05),
  313. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  314. // X/Y Position (4 bytes)
  315. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  316. HID_RI_USAGE(8, 0x30), // X
  317. HID_RI_USAGE(8, 0x31), // Y
  318. HID_RI_LOGICAL_MAXIMUM(16, 0x7FFF),
  319. HID_RI_REPORT_COUNT(8, 0x02),
  320. HID_RI_REPORT_SIZE(8, 0x10),
  321. HID_RI_UNIT(8, 0x13), // Inch, English Linear
  322. HID_RI_UNIT_EXPONENT(8, 0x0E), // -2
  323. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  324. HID_RI_END_COLLECTION(0),
  325. HID_RI_END_COLLECTION(0),
  326. # ifndef DIGITIZER_SHARED_EP
  327. };
  328. # endif
  329. #endif
  330. #if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
  331. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  332. #endif
  333. #ifdef EXTRAKEY_ENABLE
  334. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  335. HID_RI_USAGE(8, 0x80), // System Control
  336. HID_RI_COLLECTION(8, 0x01), // Application
  337. HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
  338. HID_RI_USAGE_MINIMUM(8, 0x01), // Pointer
  339. HID_RI_USAGE_MAXIMUM(16, 0x00B7), // System Display LCD Autoscale
  340. HID_RI_LOGICAL_MINIMUM(8, 0x01),
  341. HID_RI_LOGICAL_MAXIMUM(16, 0x00B7),
  342. HID_RI_REPORT_COUNT(8, 1),
  343. HID_RI_REPORT_SIZE(8, 16),
  344. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  345. HID_RI_END_COLLECTION(0),
  346. HID_RI_USAGE_PAGE(8, 0x0C), // Consumer
  347. HID_RI_USAGE(8, 0x01), // Consumer Control
  348. HID_RI_COLLECTION(8, 0x01), // Application
  349. HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
  350. HID_RI_USAGE_MINIMUM(8, 0x01), // Consumer Control
  351. HID_RI_USAGE_MAXIMUM(16, 0x02A0), // AC Desktop Show All Applications
  352. HID_RI_LOGICAL_MINIMUM(8, 0x01),
  353. HID_RI_LOGICAL_MAXIMUM(16, 0x02A0),
  354. HID_RI_REPORT_COUNT(8, 1),
  355. HID_RI_REPORT_SIZE(8, 16),
  356. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  357. HID_RI_END_COLLECTION(0),
  358. #endif
  359. #ifdef PROGRAMMABLE_BUTTON_ENABLE
  360. HID_RI_USAGE_PAGE(8, 0x0C), // Consumer
  361. HID_RI_USAGE(8, 0x01), // Consumer Control
  362. HID_RI_COLLECTION(8, 0x01), // Application
  363. HID_RI_REPORT_ID(8, REPORT_ID_PROGRAMMABLE_BUTTON),
  364. HID_RI_USAGE(8, 0x03), // Programmable Buttons
  365. HID_RI_COLLECTION(8, 0x04), // Named Array
  366. HID_RI_USAGE_PAGE(8, 0x09), // Button
  367. HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
  368. HID_RI_USAGE_MAXIMUM(8, 0x20), // Button 32
  369. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  370. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  371. HID_RI_REPORT_COUNT(8, 32),
  372. HID_RI_REPORT_SIZE(8, 1),
  373. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  374. HID_RI_END_COLLECTION(0),
  375. HID_RI_END_COLLECTION(0),
  376. #endif
  377. #ifdef NKRO_ENABLE
  378. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  379. HID_RI_USAGE(8, 0x06), // Keyboard
  380. HID_RI_COLLECTION(8, 0x01), // Application
  381. HID_RI_REPORT_ID(8, REPORT_ID_NKRO),
  382. // Modifiers (8 bits)
  383. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  384. HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control
  385. HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI
  386. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  387. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  388. HID_RI_REPORT_COUNT(8, 0x08),
  389. HID_RI_REPORT_SIZE(8, 0x01),
  390. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  391. // Keycodes
  392. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  393. HID_RI_USAGE_MINIMUM(8, 0x00),
  394. HID_RI_USAGE_MAXIMUM(8, NKRO_REPORT_BITS * 8 - 1),
  395. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  396. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  397. HID_RI_REPORT_COUNT(8, NKRO_REPORT_BITS * 8),
  398. HID_RI_REPORT_SIZE(8, 0x01),
  399. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  400. // Status LEDs (5 bits)
  401. HID_RI_USAGE_PAGE(8, 0x08), // LED
  402. HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock
  403. HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana
  404. HID_RI_REPORT_COUNT(8, 0x05),
  405. HID_RI_REPORT_SIZE(8, 0x01),
  406. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  407. // LED padding (3 bits)
  408. HID_RI_REPORT_COUNT(8, 0x01),
  409. HID_RI_REPORT_SIZE(8, 0x03),
  410. HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
  411. HID_RI_END_COLLECTION(0),
  412. #endif
  413. #ifdef SHARED_EP_ENABLE
  414. };
  415. #endif
  416. #ifdef RAW_ENABLE
  417. const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] = {
  418. HID_RI_USAGE_PAGE(16, RAW_USAGE_PAGE), // Vendor Defined
  419. HID_RI_USAGE(8, RAW_USAGE_ID), // Vendor Defined
  420. HID_RI_COLLECTION(8, 0x01), // Application
  421. // Data to host
  422. HID_RI_USAGE(8, 0x62), // Vendor Defined
  423. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  424. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  425. HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
  426. HID_RI_REPORT_SIZE(8, 0x08),
  427. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  428. // Data from host
  429. HID_RI_USAGE(8, 0x63), // Vendor Defined
  430. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  431. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  432. HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
  433. HID_RI_REPORT_SIZE(8, 0x08),
  434. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  435. HID_RI_END_COLLECTION(0),
  436. };
  437. #endif
  438. #ifdef CONSOLE_ENABLE
  439. const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
  440. HID_RI_USAGE_PAGE(16, 0xFF31), // Vendor Defined (PJRC Teensy compatible)
  441. HID_RI_USAGE(8, 0x74), // Vendor Defined (PJRC Teensy compatible)
  442. HID_RI_COLLECTION(8, 0x01), // Application
  443. // Data to host
  444. HID_RI_USAGE(8, 0x75), // Vendor Defined
  445. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  446. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  447. HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
  448. HID_RI_REPORT_SIZE(8, 0x08),
  449. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  450. HID_RI_END_COLLECTION(0),
  451. };
  452. #endif
  453. /*
  454. * Device descriptor
  455. */
  456. const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
  457. .Header = {
  458. .Size = sizeof(USB_Descriptor_Device_t),
  459. .Type = DTYPE_Device
  460. },
  461. .USBSpecification = VERSION_BCD(2, 0, 0),
  462. #if VIRTSER_ENABLE
  463. .Class = USB_CSCP_IADDeviceClass,
  464. .SubClass = USB_CSCP_IADDeviceSubclass,
  465. .Protocol = USB_CSCP_IADDeviceProtocol,
  466. #else
  467. .Class = USB_CSCP_NoDeviceClass,
  468. .SubClass = USB_CSCP_NoDeviceSubclass,
  469. .Protocol = USB_CSCP_NoDeviceProtocol,
  470. #endif
  471. .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
  472. // Specified in config.h
  473. .VendorID = VENDOR_ID,
  474. .ProductID = PRODUCT_ID,
  475. .ReleaseNumber = DEVICE_VER,
  476. .ManufacturerStrIndex = 0x01,
  477. .ProductStrIndex = 0x02,
  478. #ifdef HAS_SERIAL_NUMBER
  479. .SerialNumStrIndex = 0x03,
  480. #else // HAS_SERIAL_NUMBER
  481. .SerialNumStrIndex = 0x00,
  482. #endif // HAS_SERIAL_NUMBER
  483. .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
  484. };
  485. #ifndef USB_MAX_POWER_CONSUMPTION
  486. # define USB_MAX_POWER_CONSUMPTION 500
  487. #endif
  488. #ifndef USB_POLLING_INTERVAL_MS
  489. # define USB_POLLING_INTERVAL_MS 1
  490. #endif
  491. /*
  492. * Configuration descriptors
  493. */
  494. const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
  495. .Config = {
  496. .Header = {
  497. .Size = sizeof(USB_Descriptor_Configuration_Header_t),
  498. .Type = DTYPE_Configuration
  499. },
  500. .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
  501. .TotalInterfaces = TOTAL_INTERFACES,
  502. .ConfigurationNumber = 1,
  503. .ConfigurationStrIndex = NO_DESCRIPTOR,
  504. .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
  505. .MaxPowerConsumption = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)
  506. },
  507. #ifndef KEYBOARD_SHARED_EP
  508. /*
  509. * Keyboard
  510. */
  511. .Keyboard_Interface = {
  512. .Header = {
  513. .Size = sizeof(USB_Descriptor_Interface_t),
  514. .Type = DTYPE_Interface
  515. },
  516. .InterfaceNumber = KEYBOARD_INTERFACE,
  517. .AlternateSetting = 0x00,
  518. .TotalEndpoints = 1,
  519. .Class = HID_CSCP_HIDClass,
  520. .SubClass = HID_CSCP_BootSubclass,
  521. .Protocol = HID_CSCP_KeyboardBootProtocol,
  522. .InterfaceStrIndex = NO_DESCRIPTOR
  523. },
  524. .Keyboard_HID = {
  525. .Header = {
  526. .Size = sizeof(USB_HID_Descriptor_HID_t),
  527. .Type = HID_DTYPE_HID
  528. },
  529. .HIDSpec = VERSION_BCD(1, 1, 1),
  530. .CountryCode = 0x00,
  531. .TotalReportDescriptors = 1,
  532. .HIDReportType = HID_DTYPE_Report,
  533. .HIDReportLength = sizeof(KeyboardReport)
  534. },
  535. .Keyboard_INEndpoint = {
  536. .Header = {
  537. .Size = sizeof(USB_Descriptor_Endpoint_t),
  538. .Type = DTYPE_Endpoint
  539. },
  540. .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
  541. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  542. .EndpointSize = KEYBOARD_EPSIZE,
  543. .PollingIntervalMS = USB_POLLING_INTERVAL_MS
  544. },
  545. #endif
  546. #ifdef RAW_ENABLE
  547. /*
  548. * Raw HID
  549. */
  550. .Raw_Interface = {
  551. .Header = {
  552. .Size = sizeof(USB_Descriptor_Interface_t),
  553. .Type = DTYPE_Interface
  554. },
  555. .InterfaceNumber = RAW_INTERFACE,
  556. .AlternateSetting = 0x00,
  557. .TotalEndpoints = 2,
  558. .Class = HID_CSCP_HIDClass,
  559. .SubClass = HID_CSCP_NonBootSubclass,
  560. .Protocol = HID_CSCP_NonBootProtocol,
  561. .InterfaceStrIndex = NO_DESCRIPTOR
  562. },
  563. .Raw_HID = {
  564. .Header = {
  565. .Size = sizeof(USB_HID_Descriptor_HID_t),
  566. .Type = HID_DTYPE_HID
  567. },
  568. .HIDSpec = VERSION_BCD(1, 1, 1),
  569. .CountryCode = 0x00,
  570. .TotalReportDescriptors = 1,
  571. .HIDReportType = HID_DTYPE_Report,
  572. .HIDReportLength = sizeof(RawReport)
  573. },
  574. .Raw_INEndpoint = {
  575. .Header = {
  576. .Size = sizeof(USB_Descriptor_Endpoint_t),
  577. .Type = DTYPE_Endpoint
  578. },
  579. .EndpointAddress = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
  580. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  581. .EndpointSize = RAW_EPSIZE,
  582. .PollingIntervalMS = 0x01
  583. },
  584. .Raw_OUTEndpoint = {
  585. .Header = {
  586. .Size = sizeof(USB_Descriptor_Endpoint_t),
  587. .Type = DTYPE_Endpoint
  588. },
  589. .EndpointAddress = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
  590. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  591. .EndpointSize = RAW_EPSIZE,
  592. .PollingIntervalMS = 0x01
  593. },
  594. #endif
  595. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  596. /*
  597. * Mouse
  598. */
  599. .Mouse_Interface = {
  600. .Header = {
  601. .Size = sizeof(USB_Descriptor_Interface_t),
  602. .Type = DTYPE_Interface
  603. },
  604. .InterfaceNumber = MOUSE_INTERFACE,
  605. .AlternateSetting = 0x00,
  606. .TotalEndpoints = 1,
  607. .Class = HID_CSCP_HIDClass,
  608. .SubClass = HID_CSCP_BootSubclass,
  609. .Protocol = HID_CSCP_MouseBootProtocol,
  610. .InterfaceStrIndex = NO_DESCRIPTOR
  611. },
  612. .Mouse_HID = {
  613. .Header = {
  614. .Size = sizeof(USB_HID_Descriptor_HID_t),
  615. .Type = HID_DTYPE_HID
  616. },
  617. .HIDSpec = VERSION_BCD(1, 1, 1),
  618. .CountryCode = 0x00,
  619. .TotalReportDescriptors = 1,
  620. .HIDReportType = HID_DTYPE_Report,
  621. .HIDReportLength = sizeof(MouseReport)
  622. },
  623. .Mouse_INEndpoint = {
  624. .Header = {
  625. .Size = sizeof(USB_Descriptor_Endpoint_t),
  626. .Type = DTYPE_Endpoint
  627. },
  628. .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
  629. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  630. .EndpointSize = MOUSE_EPSIZE,
  631. .PollingIntervalMS = USB_POLLING_INTERVAL_MS
  632. },
  633. #endif
  634. #ifdef SHARED_EP_ENABLE
  635. /*
  636. * Shared
  637. */
  638. .Shared_Interface = {
  639. .Header = {
  640. .Size = sizeof(USB_Descriptor_Interface_t),
  641. .Type = DTYPE_Interface
  642. },
  643. .InterfaceNumber = SHARED_INTERFACE,
  644. .AlternateSetting = 0x00,
  645. .TotalEndpoints = 1,
  646. .Class = HID_CSCP_HIDClass,
  647. # ifdef KEYBOARD_SHARED_EP
  648. .SubClass = HID_CSCP_BootSubclass,
  649. .Protocol = HID_CSCP_KeyboardBootProtocol,
  650. # else
  651. .SubClass = HID_CSCP_NonBootSubclass,
  652. .Protocol = HID_CSCP_NonBootProtocol,
  653. # endif
  654. .InterfaceStrIndex = NO_DESCRIPTOR
  655. },
  656. .Shared_HID = {
  657. .Header = {
  658. .Size = sizeof(USB_HID_Descriptor_HID_t),
  659. .Type = HID_DTYPE_HID
  660. },
  661. .HIDSpec = VERSION_BCD(1, 1, 1),
  662. .CountryCode = 0x00,
  663. .TotalReportDescriptors = 1,
  664. .HIDReportType = HID_DTYPE_Report,
  665. .HIDReportLength = sizeof(SharedReport)
  666. },
  667. .Shared_INEndpoint = {
  668. .Header = {
  669. .Size = sizeof(USB_Descriptor_Endpoint_t),
  670. .Type = DTYPE_Endpoint
  671. },
  672. .EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM),
  673. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  674. .EndpointSize = SHARED_EPSIZE,
  675. .PollingIntervalMS = USB_POLLING_INTERVAL_MS
  676. },
  677. #endif
  678. #ifdef CONSOLE_ENABLE
  679. /*
  680. * Console
  681. */
  682. .Console_Interface = {
  683. .Header = {
  684. .Size = sizeof(USB_Descriptor_Interface_t),
  685. .Type = DTYPE_Interface
  686. },
  687. .InterfaceNumber = CONSOLE_INTERFACE,
  688. .AlternateSetting = 0x00,
  689. .TotalEndpoints = 1,
  690. .Class = HID_CSCP_HIDClass,
  691. .SubClass = HID_CSCP_NonBootSubclass,
  692. .Protocol = HID_CSCP_NonBootProtocol,
  693. .InterfaceStrIndex = NO_DESCRIPTOR
  694. },
  695. .Console_HID = {
  696. .Header = {
  697. .Size = sizeof(USB_HID_Descriptor_HID_t),
  698. .Type = HID_DTYPE_HID
  699. },
  700. .HIDSpec = VERSION_BCD(1, 1, 1),
  701. .CountryCode = 0x00,
  702. .TotalReportDescriptors = 1,
  703. .HIDReportType = HID_DTYPE_Report,
  704. .HIDReportLength = sizeof(ConsoleReport)
  705. },
  706. .Console_INEndpoint = {
  707. .Header = {
  708. .Size = sizeof(USB_Descriptor_Endpoint_t),
  709. .Type = DTYPE_Endpoint
  710. },
  711. .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
  712. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  713. .EndpointSize = CONSOLE_EPSIZE,
  714. .PollingIntervalMS = 0x01
  715. },
  716. #endif
  717. #ifdef MIDI_ENABLE
  718. /*
  719. * MIDI
  720. */
  721. .Audio_Interface_Association = {
  722. .Header = {
  723. .Size = sizeof(USB_Descriptor_Interface_Association_t),
  724. .Type = DTYPE_InterfaceAssociation
  725. },
  726. .FirstInterfaceIndex = AC_INTERFACE,
  727. .TotalInterfaces = 2,
  728. .Class = AUDIO_CSCP_AudioClass,
  729. .SubClass = AUDIO_CSCP_ControlSubclass,
  730. .Protocol = AUDIO_CSCP_ControlProtocol,
  731. .IADStrIndex = NO_DESCRIPTOR,
  732. },
  733. .Audio_ControlInterface = {
  734. .Header = {
  735. .Size = sizeof(USB_Descriptor_Interface_t),
  736. .Type = DTYPE_Interface
  737. },
  738. .InterfaceNumber = AC_INTERFACE,
  739. .AlternateSetting = 0,
  740. .TotalEndpoints = 0,
  741. .Class = AUDIO_CSCP_AudioClass,
  742. .SubClass = AUDIO_CSCP_ControlSubclass,
  743. .Protocol = AUDIO_CSCP_ControlProtocol,
  744. .InterfaceStrIndex = NO_DESCRIPTOR
  745. },
  746. .Audio_ControlInterface_SPC = {
  747. .Header = {
  748. .Size = sizeof(USB_Audio_Descriptor_Interface_AC_t),
  749. .Type = AUDIO_DTYPE_CSInterface
  750. },
  751. .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
  752. .ACSpecification = VERSION_BCD(1, 0, 0),
  753. .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
  754. .InCollection = 1,
  755. .InterfaceNumber = AS_INTERFACE,
  756. },
  757. .Audio_StreamInterface = {
  758. .Header = {
  759. .Size = sizeof(USB_Descriptor_Interface_t),
  760. .Type = DTYPE_Interface
  761. },
  762. .InterfaceNumber = AS_INTERFACE,
  763. .AlternateSetting = 0,
  764. .TotalEndpoints = 2,
  765. .Class = AUDIO_CSCP_AudioClass,
  766. .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
  767. .Protocol = AUDIO_CSCP_StreamingProtocol,
  768. .InterfaceStrIndex = NO_DESCRIPTOR
  769. },
  770. .Audio_StreamInterface_SPC = {
  771. .Header = {
  772. .Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t),
  773. .Type = AUDIO_DTYPE_CSInterface
  774. },
  775. .Subtype = AUDIO_DSUBTYPE_CSInterface_General,
  776. .AudioSpecification = VERSION_BCD(1, 0, 0),
  777. .TotalLength = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC) + sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t) - offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)
  778. },
  779. .MIDI_In_Jack_Emb = {
  780. .Header = {
  781. .Size = sizeof(USB_MIDI_Descriptor_InputJack_t),
  782. .Type = AUDIO_DTYPE_CSInterface
  783. },
  784. .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
  785. .JackType = MIDI_JACKTYPE_Embedded,
  786. .JackID = 0x01,
  787. .JackStrIndex = NO_DESCRIPTOR
  788. },
  789. .MIDI_In_Jack_Ext = {
  790. .Header = {
  791. .Size = sizeof(USB_MIDI_Descriptor_InputJack_t),
  792. .Type = AUDIO_DTYPE_CSInterface
  793. },
  794. .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
  795. .JackType = MIDI_JACKTYPE_External,
  796. .JackID = 0x02,
  797. .JackStrIndex = NO_DESCRIPTOR
  798. },
  799. .MIDI_Out_Jack_Emb = {
  800. .Header = {
  801. .Size = sizeof(USB_MIDI_Descriptor_OutputJack_t),
  802. .Type = AUDIO_DTYPE_CSInterface
  803. },
  804. .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
  805. .JackType = MIDI_JACKTYPE_Embedded,
  806. .JackID = 0x03,
  807. .NumberOfPins = 1,
  808. .SourceJackID = {0x02},
  809. .SourcePinID = {0x01},
  810. .JackStrIndex = NO_DESCRIPTOR
  811. },
  812. .MIDI_Out_Jack_Ext = {
  813. .Header = {
  814. .Size = sizeof(USB_MIDI_Descriptor_OutputJack_t),
  815. .Type = AUDIO_DTYPE_CSInterface
  816. },
  817. .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
  818. .JackType = MIDI_JACKTYPE_External,
  819. .JackID = 0x04,
  820. .NumberOfPins = 1,
  821. .SourceJackID = {0x01},
  822. .SourcePinID = {0x01},
  823. .JackStrIndex = NO_DESCRIPTOR
  824. },
  825. .MIDI_In_Jack_Endpoint = {
  826. .Endpoint = {
  827. .Header = {
  828. .Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t),
  829. .Type = DTYPE_Endpoint
  830. },
  831. .EndpointAddress = (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM),
  832. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  833. .EndpointSize = MIDI_STREAM_EPSIZE,
  834. .PollingIntervalMS = 0x05
  835. },
  836. .Refresh = 0,
  837. .SyncEndpointNumber = 0
  838. },
  839. .MIDI_In_Jack_Endpoint_SPC = {
  840. .Header = {
  841. .Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t),
  842. .Type = AUDIO_DTYPE_CSEndpoint
  843. },
  844. .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
  845. .TotalEmbeddedJacks = 0x01,
  846. .AssociatedJackID = {0x01}
  847. },
  848. .MIDI_Out_Jack_Endpoint = {
  849. .Endpoint = {
  850. .Header = {
  851. .Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t),
  852. .Type = DTYPE_Endpoint
  853. },
  854. .EndpointAddress = (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM),
  855. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  856. .EndpointSize = MIDI_STREAM_EPSIZE,
  857. .PollingIntervalMS = 0x05
  858. },
  859. .Refresh = 0,
  860. .SyncEndpointNumber = 0
  861. },
  862. .MIDI_Out_Jack_Endpoint_SPC = {
  863. .Header = {
  864. .Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t),
  865. .Type = AUDIO_DTYPE_CSEndpoint
  866. },
  867. .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
  868. .TotalEmbeddedJacks = 0x01,
  869. .AssociatedJackID = {0x03}
  870. },
  871. #endif
  872. #ifdef VIRTSER_ENABLE
  873. /*
  874. * Virtual Serial
  875. */
  876. .CDC_Interface_Association = {
  877. .Header = {
  878. .Size = sizeof(USB_Descriptor_Interface_Association_t),
  879. .Type = DTYPE_InterfaceAssociation
  880. },
  881. .FirstInterfaceIndex = CCI_INTERFACE,
  882. .TotalInterfaces = 2,
  883. .Class = CDC_CSCP_CDCClass,
  884. .SubClass = CDC_CSCP_ACMSubclass,
  885. .Protocol = CDC_CSCP_ATCommandProtocol,
  886. .IADStrIndex = NO_DESCRIPTOR,
  887. },
  888. .CDC_CCI_Interface = {
  889. .Header = {
  890. .Size = sizeof(USB_Descriptor_Interface_t),
  891. .Type = DTYPE_Interface
  892. },
  893. .InterfaceNumber = CCI_INTERFACE,
  894. .AlternateSetting = 0,
  895. .TotalEndpoints = 1,
  896. .Class = CDC_CSCP_CDCClass,
  897. .SubClass = CDC_CSCP_ACMSubclass,
  898. .Protocol = CDC_CSCP_ATCommandProtocol,
  899. .InterfaceStrIndex = NO_DESCRIPTOR
  900. },
  901. .CDC_Functional_Header = {
  902. .Header = {
  903. .Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t),
  904. .Type = CDC_DTYPE_CSInterface
  905. },
  906. .Subtype = 0x00,
  907. .CDCSpecification = VERSION_BCD(1, 1, 0),
  908. },
  909. .CDC_Functional_ACM = {
  910. .Header = {
  911. .Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t),
  912. .Type = CDC_DTYPE_CSInterface
  913. },
  914. .Subtype = 0x02,
  915. .Capabilities = 0x02,
  916. },
  917. .CDC_Functional_Union = {
  918. .Header = {
  919. .Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t),
  920. .Type = CDC_DTYPE_CSInterface
  921. },
  922. .Subtype = 0x06,
  923. .MasterInterfaceNumber = CCI_INTERFACE,
  924. .SlaveInterfaceNumber = CDI_INTERFACE,
  925. },
  926. .CDC_NotificationEndpoint = {
  927. .Header = {
  928. .Size = sizeof(USB_Descriptor_Endpoint_t),
  929. .Type = DTYPE_Endpoint
  930. },
  931. .EndpointAddress = (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM),
  932. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  933. .EndpointSize = CDC_NOTIFICATION_EPSIZE,
  934. .PollingIntervalMS = 0xFF
  935. },
  936. .CDC_DCI_Interface = {
  937. .Header = {
  938. .Size = sizeof(USB_Descriptor_Interface_t),
  939. .Type = DTYPE_Interface
  940. },
  941. .InterfaceNumber = CDI_INTERFACE,
  942. .AlternateSetting = 0,
  943. .TotalEndpoints = 2,
  944. .Class = CDC_CSCP_CDCDataClass,
  945. .SubClass = CDC_CSCP_NoDataSubclass,
  946. .Protocol = CDC_CSCP_NoDataProtocol,
  947. .InterfaceStrIndex = NO_DESCRIPTOR
  948. },
  949. .CDC_DataOutEndpoint = {
  950. .Header = {
  951. .Size = sizeof(USB_Descriptor_Endpoint_t),
  952. .Type = DTYPE_Endpoint
  953. },
  954. .EndpointAddress = (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM),
  955. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  956. .EndpointSize = CDC_EPSIZE,
  957. .PollingIntervalMS = 0x05
  958. },
  959. .CDC_DataInEndpoint = {
  960. .Header = {
  961. .Size = sizeof(USB_Descriptor_Endpoint_t),
  962. .Type = DTYPE_Endpoint
  963. },
  964. .EndpointAddress = (ENDPOINT_DIR_IN | CDC_IN_EPNUM),
  965. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  966. .EndpointSize = CDC_EPSIZE,
  967. .PollingIntervalMS = 0x05
  968. },
  969. #endif
  970. #if defined(JOYSTICK_ENABLE) && !defined(JOYSTICK_SHARED_EP)
  971. /*
  972. * Joystick
  973. */
  974. .Joystick_Interface = {
  975. .Header = {
  976. .Size = sizeof(USB_Descriptor_Interface_t),
  977. .Type = DTYPE_Interface
  978. },
  979. .InterfaceNumber = JOYSTICK_INTERFACE,
  980. .AlternateSetting = 0x00,
  981. .TotalEndpoints = 1,
  982. .Class = HID_CSCP_HIDClass,
  983. .SubClass = HID_CSCP_NonBootSubclass,
  984. .Protocol = HID_CSCP_NonBootProtocol,
  985. .InterfaceStrIndex = NO_DESCRIPTOR
  986. },
  987. .Joystick_HID = {
  988. .Header = {
  989. .Size = sizeof(USB_HID_Descriptor_HID_t),
  990. .Type = HID_DTYPE_HID
  991. },
  992. .HIDSpec = VERSION_BCD(1, 1, 1),
  993. .CountryCode = 0x00,
  994. .TotalReportDescriptors = 1,
  995. .HIDReportType = HID_DTYPE_Report,
  996. .HIDReportLength = sizeof(JoystickReport)
  997. },
  998. .Joystick_INEndpoint = {
  999. .Header = {
  1000. .Size = sizeof(USB_Descriptor_Endpoint_t),
  1001. .Type = DTYPE_Endpoint
  1002. },
  1003. .EndpointAddress = (ENDPOINT_DIR_IN | JOYSTICK_IN_EPNUM),
  1004. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  1005. .EndpointSize = JOYSTICK_EPSIZE,
  1006. .PollingIntervalMS = USB_POLLING_INTERVAL_MS
  1007. },
  1008. #endif
  1009. #if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
  1010. /*
  1011. * Digitizer
  1012. */
  1013. .Digitizer_Interface = {
  1014. .Header = {
  1015. .Size = sizeof(USB_Descriptor_Interface_t),
  1016. .Type = DTYPE_Interface
  1017. },
  1018. .InterfaceNumber = DIGITIZER_INTERFACE,
  1019. .AlternateSetting = 0x00,
  1020. .TotalEndpoints = 1,
  1021. .Class = HID_CSCP_HIDClass,
  1022. .SubClass = HID_CSCP_NonBootSubclass,
  1023. .Protocol = HID_CSCP_NonBootProtocol,
  1024. .InterfaceStrIndex = NO_DESCRIPTOR
  1025. },
  1026. .Digitizer_HID = {
  1027. .Header = {
  1028. .Size = sizeof(USB_HID_Descriptor_HID_t),
  1029. .Type = HID_DTYPE_HID
  1030. },
  1031. .HIDSpec = VERSION_BCD(1, 1, 1),
  1032. .CountryCode = 0x00,
  1033. .TotalReportDescriptors = 1,
  1034. .HIDReportType = HID_DTYPE_Report,
  1035. .HIDReportLength = sizeof(DigitizerReport)
  1036. },
  1037. .Digitizer_INEndpoint = {
  1038. .Header = {
  1039. .Size = sizeof(USB_Descriptor_Endpoint_t),
  1040. .Type = DTYPE_Endpoint
  1041. },
  1042. .EndpointAddress = (ENDPOINT_DIR_IN | DIGITIZER_IN_EPNUM),
  1043. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  1044. .EndpointSize = DIGITIZER_EPSIZE,
  1045. .PollingIntervalMS = USB_POLLING_INTERVAL_MS
  1046. },
  1047. #endif
  1048. };
  1049. /*
  1050. * String descriptors
  1051. */
  1052. #define USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(str) \
  1053. (sizeof(USB_Descriptor_Header_t) + sizeof(str) - sizeof(wchar_t)) // include header, don't count null terminator
  1054. const USB_Descriptor_String_t PROGMEM LanguageString = {
  1055. .Header = {
  1056. .Size = sizeof(USB_Descriptor_Header_t) + sizeof(uint16_t),
  1057. .Type = DTYPE_String
  1058. },
  1059. .UnicodeString = {LANGUAGE_ID_ENG}
  1060. };
  1061. const USB_Descriptor_String_t PROGMEM ManufacturerString = {
  1062. .Header = {
  1063. .Size = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(MANUFACTURER)),
  1064. .Type = DTYPE_String
  1065. },
  1066. .UnicodeString = USBSTR(MANUFACTURER)
  1067. };
  1068. const USB_Descriptor_String_t PROGMEM ProductString = {
  1069. .Header = {
  1070. .Size = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(PRODUCT)),
  1071. .Type = DTYPE_String
  1072. },
  1073. .UnicodeString = USBSTR(PRODUCT)
  1074. };
  1075. // clang-format on
  1076. #if defined(SERIAL_NUMBER)
  1077. // clang-format off
  1078. const USB_Descriptor_String_t PROGMEM SerialNumberString = {
  1079. .Header = {
  1080. .Size = USB_DESCRIPTOR_SIZE_LITERAL_U16STRING(USBSTR(SERIAL_NUMBER)),
  1081. .Type = DTYPE_String
  1082. },
  1083. .UnicodeString = USBSTR(SERIAL_NUMBER)
  1084. };
  1085. // clang-format on
  1086. #else // defined(SERIAL_NUMBER)
  1087. # if defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE
  1088. # if defined(__AVR__)
  1089. # error Dynamically setting the serial number on AVR is unsupported as LUFA requires the string to be in PROGMEM.
  1090. # endif // defined(__AVR__)
  1091. # ifndef SERIAL_NUMBER_LENGTH
  1092. # define SERIAL_NUMBER_LENGTH (sizeof(hardware_id_t) * 2)
  1093. # endif
  1094. # define SERIAL_NUMBER_DESCRIPTOR_SIZE \
  1095. (sizeof(USB_Descriptor_Header_t) /* Descriptor header */ \
  1096. + (((SERIAL_NUMBER_LENGTH) + 1) * sizeof(wchar_t))) /* Length of serial number, with potential extra character as we're converting 2 nibbles at a time */
  1097. uint8_t SerialNumberString[SERIAL_NUMBER_DESCRIPTOR_SIZE] = {0};
  1098. void set_serial_number_descriptor(void) {
  1099. static bool is_set = false;
  1100. if (is_set) {
  1101. return;
  1102. }
  1103. is_set = true;
  1104. static const char hex_str[] = "0123456789ABCDEF";
  1105. hardware_id_t id = get_hardware_id();
  1106. USB_Descriptor_String_t* desc = (USB_Descriptor_String_t*)SerialNumberString;
  1107. // Copy across nibbles from the hardware ID as unicode hex characters
  1108. int length = MIN(sizeof(id) * 2, SERIAL_NUMBER_LENGTH);
  1109. uint8_t* p = (uint8_t*)&id;
  1110. for (int i = 0; i < length; i += 2) {
  1111. desc->UnicodeString[i + 0] = hex_str[p[i / 2] >> 4];
  1112. desc->UnicodeString[i + 1] = hex_str[p[i / 2] & 0xF];
  1113. }
  1114. desc->Header.Size = sizeof(USB_Descriptor_Header_t) + (length * sizeof(wchar_t)); // includes header, don't count null terminator
  1115. desc->Header.Type = DTYPE_String;
  1116. }
  1117. # endif // defined(SERIAL_NUMBER_USE_HARDWARE_ID) && SERIAL_NUMBER_USE_HARDWARE_ID == TRUE
  1118. #endif // defined(SERIAL_NUMBER)
  1119. /**
  1120. * This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
  1121. * documentation) by the application code so that the address and size of a requested descriptor can be given
  1122. * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
  1123. * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
  1124. * USB host.
  1125. */
  1126. uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const uint16_t wLength, const void** const DescriptorAddress) {
  1127. const uint8_t DescriptorType = (wValue >> 8);
  1128. const uint8_t DescriptorIndex = (wValue & 0xFF);
  1129. const void* Address = NULL;
  1130. uint16_t Size = NO_DESCRIPTOR;
  1131. switch (DescriptorType) {
  1132. case DTYPE_Device:
  1133. Address = &DeviceDescriptor;
  1134. Size = sizeof(USB_Descriptor_Device_t);
  1135. break;
  1136. case DTYPE_Configuration:
  1137. Address = &ConfigurationDescriptor;
  1138. Size = sizeof(USB_Descriptor_Configuration_t);
  1139. break;
  1140. case DTYPE_String:
  1141. switch (DescriptorIndex) {
  1142. case 0x00:
  1143. Address = &LanguageString;
  1144. Size = pgm_read_byte(&LanguageString.Header.Size);
  1145. break;
  1146. case 0x01:
  1147. Address = &ManufacturerString;
  1148. Size = pgm_read_byte(&ManufacturerString.Header.Size);
  1149. break;
  1150. case 0x02:
  1151. Address = &ProductString;
  1152. Size = pgm_read_byte(&ProductString.Header.Size);
  1153. break;
  1154. #ifdef HAS_SERIAL_NUMBER
  1155. case 0x03:
  1156. Address = (const USB_Descriptor_String_t*)&SerialNumberString;
  1157. # if defined(SERIAL_NUMBER)
  1158. Size = pgm_read_byte(&SerialNumberString.Header.Size);
  1159. # else
  1160. set_serial_number_descriptor();
  1161. Size = ((const USB_Descriptor_String_t*)SerialNumberString)->Header.Size;
  1162. # endif
  1163. break;
  1164. #endif // HAS_SERIAL_NUMBER
  1165. }
  1166. #ifdef OS_DETECTION_ENABLE
  1167. process_wlength(wLength);
  1168. #endif
  1169. break;
  1170. case HID_DTYPE_HID:
  1171. switch (wIndex) {
  1172. #ifndef KEYBOARD_SHARED_EP
  1173. case KEYBOARD_INTERFACE:
  1174. Address = &ConfigurationDescriptor.Keyboard_HID;
  1175. Size = sizeof(USB_HID_Descriptor_HID_t);
  1176. break;
  1177. #endif
  1178. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  1179. case MOUSE_INTERFACE:
  1180. Address = &ConfigurationDescriptor.Mouse_HID;
  1181. Size = sizeof(USB_HID_Descriptor_HID_t);
  1182. break;
  1183. #endif
  1184. #ifdef SHARED_EP_ENABLE
  1185. case SHARED_INTERFACE:
  1186. Address = &ConfigurationDescriptor.Shared_HID;
  1187. Size = sizeof(USB_HID_Descriptor_HID_t);
  1188. break;
  1189. #endif
  1190. #ifdef RAW_ENABLE
  1191. case RAW_INTERFACE:
  1192. Address = &ConfigurationDescriptor.Raw_HID;
  1193. Size = sizeof(USB_HID_Descriptor_HID_t);
  1194. break;
  1195. #endif
  1196. #ifdef CONSOLE_ENABLE
  1197. case CONSOLE_INTERFACE:
  1198. Address = &ConfigurationDescriptor.Console_HID;
  1199. Size = sizeof(USB_HID_Descriptor_HID_t);
  1200. break;
  1201. #endif
  1202. #if defined(JOYSTICK_ENABLE) && !defined(JOYSTICK_SHARED_EP)
  1203. case JOYSTICK_INTERFACE:
  1204. Address = &ConfigurationDescriptor.Joystick_HID;
  1205. Size = sizeof(USB_HID_Descriptor_HID_t);
  1206. break;
  1207. #endif
  1208. #if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
  1209. case DIGITIZER_INTERFACE:
  1210. Address = &ConfigurationDescriptor.Digitizer_HID;
  1211. Size = sizeof(USB_HID_Descriptor_HID_t);
  1212. break;
  1213. #endif
  1214. }
  1215. break;
  1216. case HID_DTYPE_Report:
  1217. switch (wIndex) {
  1218. #ifndef KEYBOARD_SHARED_EP
  1219. case KEYBOARD_INTERFACE:
  1220. Address = &KeyboardReport;
  1221. Size = sizeof(KeyboardReport);
  1222. break;
  1223. #endif
  1224. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  1225. case MOUSE_INTERFACE:
  1226. Address = &MouseReport;
  1227. Size = sizeof(MouseReport);
  1228. break;
  1229. #endif
  1230. #ifdef SHARED_EP_ENABLE
  1231. case SHARED_INTERFACE:
  1232. Address = &SharedReport;
  1233. Size = sizeof(SharedReport);
  1234. break;
  1235. #endif
  1236. #ifdef RAW_ENABLE
  1237. case RAW_INTERFACE:
  1238. Address = &RawReport;
  1239. Size = sizeof(RawReport);
  1240. break;
  1241. #endif
  1242. #ifdef CONSOLE_ENABLE
  1243. case CONSOLE_INTERFACE:
  1244. Address = &ConsoleReport;
  1245. Size = sizeof(ConsoleReport);
  1246. break;
  1247. #endif
  1248. #if defined(JOYSTICK_ENABLE) && !defined(JOYSTICK_SHARED_EP)
  1249. case JOYSTICK_INTERFACE:
  1250. Address = &JoystickReport;
  1251. Size = sizeof(JoystickReport);
  1252. break;
  1253. #endif
  1254. #if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
  1255. case DIGITIZER_INTERFACE:
  1256. Address = &DigitizerReport;
  1257. Size = sizeof(DigitizerReport);
  1258. break;
  1259. #endif
  1260. }
  1261. break;
  1262. }
  1263. *DescriptorAddress = Address;
  1264. return Size;
  1265. }