usb_descriptor.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  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. // clang-format off
  41. /*
  42. * HID report descriptors
  43. */
  44. #ifdef KEYBOARD_SHARED_EP
  45. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  46. # define SHARED_REPORT_STARTED
  47. #else
  48. const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = {
  49. #endif
  50. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  51. HID_RI_USAGE(8, 0x06), // Keyboard
  52. HID_RI_COLLECTION(8, 0x01), // Application
  53. #ifdef KEYBOARD_SHARED_EP
  54. HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD),
  55. #endif
  56. // Modifiers (8 bits)
  57. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  58. HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control
  59. HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI
  60. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  61. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  62. HID_RI_REPORT_COUNT(8, 0x08),
  63. HID_RI_REPORT_SIZE(8, 0x01),
  64. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  65. // Reserved (1 byte)
  66. HID_RI_REPORT_COUNT(8, 0x01),
  67. HID_RI_REPORT_SIZE(8, 0x08),
  68. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  69. // Keycodes (6 bytes)
  70. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  71. HID_RI_USAGE_MINIMUM(8, 0x00),
  72. HID_RI_USAGE_MAXIMUM(8, 0xFF),
  73. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  74. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  75. HID_RI_REPORT_COUNT(8, 0x06),
  76. HID_RI_REPORT_SIZE(8, 0x08),
  77. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  78. // Status LEDs (5 bits)
  79. HID_RI_USAGE_PAGE(8, 0x08), // LED
  80. HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock
  81. HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana
  82. HID_RI_REPORT_COUNT(8, 0x05),
  83. HID_RI_REPORT_SIZE(8, 0x01),
  84. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  85. // LED padding (3 bits)
  86. HID_RI_REPORT_COUNT(8, 0x01),
  87. HID_RI_REPORT_SIZE(8, 0x03),
  88. HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
  89. HID_RI_END_COLLECTION(0),
  90. #ifndef KEYBOARD_SHARED_EP
  91. };
  92. #endif
  93. #ifdef MOUSE_ENABLE
  94. # ifndef MOUSE_SHARED_EP
  95. const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = {
  96. # elif !defined(SHARED_REPORT_STARTED)
  97. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  98. # define SHARED_REPORT_STARTED
  99. # endif
  100. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  101. HID_RI_USAGE(8, 0x02), // Mouse
  102. HID_RI_COLLECTION(8, 0x01), // Application
  103. # ifdef MOUSE_SHARED_EP
  104. HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
  105. # endif
  106. HID_RI_USAGE(8, 0x01), // Pointer
  107. HID_RI_COLLECTION(8, 0x00), // Physical
  108. // Buttons (8 bits)
  109. HID_RI_USAGE_PAGE(8, 0x09), // Button
  110. HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
  111. HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8
  112. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  113. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  114. HID_RI_REPORT_COUNT(8, 0x08),
  115. HID_RI_REPORT_SIZE(8, 0x01),
  116. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  117. // X/Y position (2 bytes)
  118. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  119. HID_RI_USAGE(8, 0x30), // X
  120. HID_RI_USAGE(8, 0x31), // Y
  121. HID_RI_LOGICAL_MINIMUM(8, -127),
  122. HID_RI_LOGICAL_MAXIMUM(8, 127),
  123. HID_RI_REPORT_COUNT(8, 0x02),
  124. HID_RI_REPORT_SIZE(8, 0x08),
  125. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  126. // Vertical wheel (1 byte)
  127. HID_RI_USAGE(8, 0x38), // Wheel
  128. HID_RI_LOGICAL_MINIMUM(8, -127),
  129. HID_RI_LOGICAL_MAXIMUM(8, 127),
  130. HID_RI_REPORT_COUNT(8, 0x01),
  131. HID_RI_REPORT_SIZE(8, 0x08),
  132. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  133. // Horizontal wheel (1 byte)
  134. HID_RI_USAGE_PAGE(8, 0x0C), // Consumer
  135. HID_RI_USAGE(16, 0x0238), // AC Pan
  136. HID_RI_LOGICAL_MINIMUM(8, -127),
  137. HID_RI_LOGICAL_MAXIMUM(8, 127),
  138. HID_RI_REPORT_COUNT(8, 0x01),
  139. HID_RI_REPORT_SIZE(8, 0x08),
  140. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  141. HID_RI_END_COLLECTION(0),
  142. HID_RI_END_COLLECTION(0),
  143. # ifndef MOUSE_SHARED_EP
  144. };
  145. # endif
  146. #endif
  147. #if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
  148. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  149. #endif
  150. #ifdef EXTRAKEY_ENABLE
  151. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  152. HID_RI_USAGE(8, 0x80), // System Control
  153. HID_RI_COLLECTION(8, 0x01), // Application
  154. HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
  155. HID_RI_USAGE_MINIMUM(8, 0x01), // Pointer
  156. HID_RI_USAGE_MAXIMUM(16, 0x00B7), // System Display LCD Autoscale
  157. HID_RI_LOGICAL_MINIMUM(8, 0x01),
  158. HID_RI_LOGICAL_MAXIMUM(16, 0x00B7),
  159. HID_RI_REPORT_COUNT(8, 1),
  160. HID_RI_REPORT_SIZE(8, 16),
  161. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  162. HID_RI_END_COLLECTION(0),
  163. HID_RI_USAGE_PAGE(8, 0x0C), // Consumer
  164. HID_RI_USAGE(8, 0x01), // Consumer Control
  165. HID_RI_COLLECTION(8, 0x01), // Application
  166. HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
  167. HID_RI_USAGE_MINIMUM(8, 0x01), // Consumer Control
  168. HID_RI_USAGE_MAXIMUM(16, 0x02A0), // AC Desktop Show All Applications
  169. HID_RI_LOGICAL_MINIMUM(8, 0x01),
  170. HID_RI_LOGICAL_MAXIMUM(16, 0x02A0),
  171. HID_RI_REPORT_COUNT(8, 1),
  172. HID_RI_REPORT_SIZE(8, 16),
  173. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  174. HID_RI_END_COLLECTION(0),
  175. #endif
  176. #ifdef NKRO_ENABLE
  177. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  178. HID_RI_USAGE(8, 0x06), // Keyboard
  179. HID_RI_COLLECTION(8, 0x01), // Application
  180. HID_RI_REPORT_ID(8, REPORT_ID_NKRO),
  181. // Modifiers (8 bits)
  182. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  183. HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control
  184. HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI
  185. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  186. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  187. HID_RI_REPORT_COUNT(8, 0x08),
  188. HID_RI_REPORT_SIZE(8, 0x01),
  189. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  190. // Keycodes
  191. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  192. HID_RI_USAGE_MINIMUM(8, 0x00),
  193. HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS * 8 - 1),
  194. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  195. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  196. HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS * 8),
  197. HID_RI_REPORT_SIZE(8, 0x01),
  198. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  199. // Status LEDs (5 bits)
  200. HID_RI_USAGE_PAGE(8, 0x08), // LED
  201. HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock
  202. HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana
  203. HID_RI_REPORT_COUNT(8, 0x05),
  204. HID_RI_REPORT_SIZE(8, 0x01),
  205. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  206. // LED padding (3 bits)
  207. HID_RI_REPORT_COUNT(8, 0x01),
  208. HID_RI_REPORT_SIZE(8, 0x03),
  209. HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
  210. HID_RI_END_COLLECTION(0),
  211. #endif
  212. #ifdef SHARED_EP_ENABLE
  213. };
  214. #endif
  215. #ifdef RAW_ENABLE
  216. const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] = {
  217. HID_RI_USAGE_PAGE(16, RAW_USAGE_PAGE), // Vendor Defined
  218. HID_RI_USAGE(8, RAW_USAGE_ID), // Vendor Defined
  219. HID_RI_COLLECTION(8, 0x01), // Application
  220. // Data to host
  221. HID_RI_USAGE(8, 0x62), // Vendor Defined
  222. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  223. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  224. HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
  225. HID_RI_REPORT_SIZE(8, 0x08),
  226. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  227. // Data from host
  228. HID_RI_USAGE(8, 0x63), // Vendor Defined
  229. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  230. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  231. HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
  232. HID_RI_REPORT_SIZE(8, 0x08),
  233. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  234. HID_RI_END_COLLECTION(0),
  235. };
  236. #endif
  237. #ifdef CONSOLE_ENABLE
  238. const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
  239. HID_RI_USAGE_PAGE(16, 0xFF31), // Vendor Defined (PJRC Teensy compatible)
  240. HID_RI_USAGE(8, 0x74), // Vendor Defined (PJRC Teensy compatible)
  241. HID_RI_COLLECTION(8, 0x01), // Application
  242. // Data to host
  243. HID_RI_USAGE(8, 0x75), // Vendor Defined
  244. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  245. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  246. HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
  247. HID_RI_REPORT_SIZE(8, 0x08),
  248. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  249. // Data from host
  250. HID_RI_USAGE(8, 0x76), // Vendor Defined
  251. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  252. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  253. HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
  254. HID_RI_REPORT_SIZE(8, 0x08),
  255. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  256. HID_RI_END_COLLECTION(0),
  257. };
  258. #endif
  259. #ifdef JOYSTICK_ENABLE
  260. # if JOYSTICK_AXES_COUNT == 0 && JOYSTICK_BUTTON_COUNT == 0
  261. # error Need at least one axis or button for joystick
  262. # endif
  263. const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] = {
  264. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  265. HID_RI_USAGE(8, 0x04), // Joystick
  266. HID_RI_COLLECTION(8, 0x01), // Application
  267. HID_RI_COLLECTION(8, 0x00), // Physical
  268. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  269. # if JOYSTICK_AXES_COUNT >= 1
  270. HID_RI_USAGE(8, 0x30), // X
  271. # endif
  272. # if JOYSTICK_AXES_COUNT >= 2
  273. HID_RI_USAGE(8, 0x31), // Y
  274. # endif
  275. # if JOYSTICK_AXES_COUNT >= 3
  276. HID_RI_USAGE(8, 0x32), // Z
  277. # endif
  278. # if JOYSTICK_AXES_COUNT >= 4
  279. HID_RI_USAGE(8, 0x33), // Rx
  280. # endif
  281. # if JOYSTICK_AXES_COUNT >= 5
  282. HID_RI_USAGE(8, 0x34), // Ry
  283. # endif
  284. # if JOYSTICK_AXES_COUNT >= 6
  285. HID_RI_USAGE(8, 0x35), // Rz
  286. # endif
  287. # if JOYSTICK_AXES_COUNT >= 1
  288. # if JOYSTICK_AXES_RESOLUTION == 8
  289. HID_RI_LOGICAL_MINIMUM(8, -JOYSTICK_RESOLUTION),
  290. HID_RI_LOGICAL_MAXIMUM(8, JOYSTICK_RESOLUTION),
  291. HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
  292. HID_RI_REPORT_SIZE(8, 0x08),
  293. # else
  294. HID_RI_LOGICAL_MINIMUM(16, -JOYSTICK_RESOLUTION),
  295. HID_RI_LOGICAL_MAXIMUM(16, JOYSTICK_RESOLUTION),
  296. HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
  297. HID_RI_REPORT_SIZE(8, 0x10),
  298. # endif
  299. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  300. # endif
  301. # if JOYSTICK_BUTTON_COUNT >= 1
  302. HID_RI_USAGE_PAGE(8, 0x09), // Button
  303. HID_RI_USAGE_MINIMUM(8, 0x01),
  304. HID_RI_USAGE_MAXIMUM(8, JOYSTICK_BUTTON_COUNT),
  305. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  306. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  307. HID_RI_REPORT_COUNT(8, JOYSTICK_BUTTON_COUNT),
  308. HID_RI_REPORT_SIZE(8, 0x01),
  309. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  310. # if (JOYSTICK_BUTTON_COUNT % 8) != 0
  311. HID_RI_REPORT_COUNT(8, 8 - (JOYSTICK_BUTTON_COUNT % 8)),
  312. HID_RI_REPORT_SIZE(8, 0x01),
  313. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  314. # endif
  315. # endif
  316. HID_RI_END_COLLECTION(0),
  317. HID_RI_END_COLLECTION(0)
  318. };
  319. #endif
  320. /*
  321. * Device descriptor
  322. */
  323. const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
  324. .Header = {
  325. .Size = sizeof(USB_Descriptor_Device_t),
  326. .Type = DTYPE_Device
  327. },
  328. .USBSpecification = VERSION_BCD(1, 1, 0),
  329. #if VIRTSER_ENABLE
  330. .Class = USB_CSCP_IADDeviceClass,
  331. .SubClass = USB_CSCP_IADDeviceSubclass,
  332. .Protocol = USB_CSCP_IADDeviceProtocol,
  333. #else
  334. .Class = USB_CSCP_NoDeviceClass,
  335. .SubClass = USB_CSCP_NoDeviceSubclass,
  336. .Protocol = USB_CSCP_NoDeviceProtocol,
  337. #endif
  338. .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
  339. // Specified in config.h
  340. .VendorID = VENDOR_ID,
  341. .ProductID = PRODUCT_ID,
  342. .ReleaseNumber = DEVICE_VER,
  343. .ManufacturerStrIndex = 0x01,
  344. .ProductStrIndex = 0x02,
  345. #if defined(SERIAL_NUMBER)
  346. .SerialNumStrIndex = 0x03,
  347. #else
  348. .SerialNumStrIndex = 0x00,
  349. #endif
  350. .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
  351. };
  352. #ifndef USB_MAX_POWER_CONSUMPTION
  353. # define USB_MAX_POWER_CONSUMPTION 500
  354. #endif
  355. #ifndef USB_POLLING_INTERVAL_MS
  356. # define USB_POLLING_INTERVAL_MS 10
  357. #endif
  358. /*
  359. * Configuration descriptors
  360. */
  361. const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
  362. .Config = {
  363. .Header = {
  364. .Size = sizeof(USB_Descriptor_Configuration_Header_t),
  365. .Type = DTYPE_Configuration
  366. },
  367. .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
  368. .TotalInterfaces = TOTAL_INTERFACES,
  369. .ConfigurationNumber = 1,
  370. .ConfigurationStrIndex = NO_DESCRIPTOR,
  371. .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
  372. .MaxPowerConsumption = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)
  373. },
  374. #ifndef KEYBOARD_SHARED_EP
  375. /*
  376. * Keyboard
  377. */
  378. .Keyboard_Interface = {
  379. .Header = {
  380. .Size = sizeof(USB_Descriptor_Interface_t),
  381. .Type = DTYPE_Interface
  382. },
  383. .InterfaceNumber = KEYBOARD_INTERFACE,
  384. .AlternateSetting = 0x00,
  385. .TotalEndpoints = 1,
  386. .Class = HID_CSCP_HIDClass,
  387. .SubClass = HID_CSCP_BootSubclass,
  388. .Protocol = HID_CSCP_KeyboardBootProtocol,
  389. .InterfaceStrIndex = NO_DESCRIPTOR
  390. },
  391. .Keyboard_HID = {
  392. .Header = {
  393. .Size = sizeof(USB_HID_Descriptor_HID_t),
  394. .Type = HID_DTYPE_HID
  395. },
  396. .HIDSpec = VERSION_BCD(1, 1, 1),
  397. .CountryCode = 0x00,
  398. .TotalReportDescriptors = 1,
  399. .HIDReportType = HID_DTYPE_Report,
  400. .HIDReportLength = sizeof(KeyboardReport)
  401. },
  402. .Keyboard_INEndpoint = {
  403. .Header = {
  404. .Size = sizeof(USB_Descriptor_Endpoint_t),
  405. .Type = DTYPE_Endpoint
  406. },
  407. .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
  408. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  409. .EndpointSize = KEYBOARD_EPSIZE,
  410. .PollingIntervalMS = USB_POLLING_INTERVAL_MS
  411. },
  412. #endif
  413. #ifdef RAW_ENABLE
  414. /*
  415. * Raw HID
  416. */
  417. .Raw_Interface = {
  418. .Header = {
  419. .Size = sizeof(USB_Descriptor_Interface_t),
  420. .Type = DTYPE_Interface
  421. },
  422. .InterfaceNumber = RAW_INTERFACE,
  423. .AlternateSetting = 0x00,
  424. .TotalEndpoints = 2,
  425. .Class = HID_CSCP_HIDClass,
  426. .SubClass = HID_CSCP_NonBootSubclass,
  427. .Protocol = HID_CSCP_NonBootProtocol,
  428. .InterfaceStrIndex = NO_DESCRIPTOR
  429. },
  430. .Raw_HID = {
  431. .Header = {
  432. .Size = sizeof(USB_HID_Descriptor_HID_t),
  433. .Type = HID_DTYPE_HID
  434. },
  435. .HIDSpec = VERSION_BCD(1, 1, 1),
  436. .CountryCode = 0x00,
  437. .TotalReportDescriptors = 1,
  438. .HIDReportType = HID_DTYPE_Report,
  439. .HIDReportLength = sizeof(RawReport)
  440. },
  441. .Raw_INEndpoint = {
  442. .Header = {
  443. .Size = sizeof(USB_Descriptor_Endpoint_t),
  444. .Type = DTYPE_Endpoint
  445. },
  446. .EndpointAddress = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
  447. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  448. .EndpointSize = RAW_EPSIZE,
  449. .PollingIntervalMS = 0x01
  450. },
  451. .Raw_OUTEndpoint = {
  452. .Header = {
  453. .Size = sizeof(USB_Descriptor_Endpoint_t),
  454. .Type = DTYPE_Endpoint
  455. },
  456. .EndpointAddress = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
  457. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  458. .EndpointSize = RAW_EPSIZE,
  459. .PollingIntervalMS = 0x01
  460. },
  461. #endif
  462. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  463. /*
  464. * Mouse
  465. */
  466. .Mouse_Interface = {
  467. .Header = {
  468. .Size = sizeof(USB_Descriptor_Interface_t),
  469. .Type = DTYPE_Interface
  470. },
  471. .InterfaceNumber = MOUSE_INTERFACE,
  472. .AlternateSetting = 0x00,
  473. .TotalEndpoints = 1,
  474. .Class = HID_CSCP_HIDClass,
  475. .SubClass = HID_CSCP_BootSubclass,
  476. .Protocol = HID_CSCP_MouseBootProtocol,
  477. .InterfaceStrIndex = NO_DESCRIPTOR
  478. },
  479. .Mouse_HID = {
  480. .Header = {
  481. .Size = sizeof(USB_HID_Descriptor_HID_t),
  482. .Type = HID_DTYPE_HID
  483. },
  484. .HIDSpec = VERSION_BCD(1, 1, 1),
  485. .CountryCode = 0x00,
  486. .TotalReportDescriptors = 1,
  487. .HIDReportType = HID_DTYPE_Report,
  488. .HIDReportLength = sizeof(MouseReport)
  489. },
  490. .Mouse_INEndpoint = {
  491. .Header = {
  492. .Size = sizeof(USB_Descriptor_Endpoint_t),
  493. .Type = DTYPE_Endpoint
  494. },
  495. .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
  496. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  497. .EndpointSize = MOUSE_EPSIZE,
  498. .PollingIntervalMS = USB_POLLING_INTERVAL_MS
  499. },
  500. #endif
  501. #ifdef SHARED_EP_ENABLE
  502. /*
  503. * Shared
  504. */
  505. .Shared_Interface = {
  506. .Header = {
  507. .Size = sizeof(USB_Descriptor_Interface_t),
  508. .Type = DTYPE_Interface
  509. },
  510. .InterfaceNumber = SHARED_INTERFACE,
  511. .AlternateSetting = 0x00,
  512. .TotalEndpoints = 1,
  513. .Class = HID_CSCP_HIDClass,
  514. # ifdef KEYBOARD_SHARED_EP
  515. .SubClass = HID_CSCP_BootSubclass,
  516. .Protocol = HID_CSCP_KeyboardBootProtocol,
  517. # else
  518. .SubClass = HID_CSCP_NonBootSubclass,
  519. .Protocol = HID_CSCP_NonBootProtocol,
  520. # endif
  521. .InterfaceStrIndex = NO_DESCRIPTOR
  522. },
  523. .Shared_HID = {
  524. .Header = {
  525. .Size = sizeof(USB_HID_Descriptor_HID_t),
  526. .Type = HID_DTYPE_HID
  527. },
  528. .HIDSpec = VERSION_BCD(1, 1, 1),
  529. .CountryCode = 0x00,
  530. .TotalReportDescriptors = 1,
  531. .HIDReportType = HID_DTYPE_Report,
  532. .HIDReportLength = sizeof(SharedReport)
  533. },
  534. .Shared_INEndpoint = {
  535. .Header = {
  536. .Size = sizeof(USB_Descriptor_Endpoint_t),
  537. .Type = DTYPE_Endpoint
  538. },
  539. .EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM),
  540. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  541. .EndpointSize = SHARED_EPSIZE,
  542. .PollingIntervalMS = USB_POLLING_INTERVAL_MS
  543. },
  544. #endif
  545. #ifdef CONSOLE_ENABLE
  546. /*
  547. * Console
  548. */
  549. .Console_Interface = {
  550. .Header = {
  551. .Size = sizeof(USB_Descriptor_Interface_t),
  552. .Type = DTYPE_Interface
  553. },
  554. .InterfaceNumber = CONSOLE_INTERFACE,
  555. .AlternateSetting = 0x00,
  556. .TotalEndpoints = 2,
  557. .Class = HID_CSCP_HIDClass,
  558. .SubClass = HID_CSCP_NonBootSubclass,
  559. .Protocol = HID_CSCP_NonBootProtocol,
  560. .InterfaceStrIndex = NO_DESCRIPTOR
  561. },
  562. .Console_HID = {
  563. .Header = {
  564. .Size = sizeof(USB_HID_Descriptor_HID_t),
  565. .Type = HID_DTYPE_HID
  566. },
  567. .HIDSpec = VERSION_BCD(1, 1, 1),
  568. .CountryCode = 0x00,
  569. .TotalReportDescriptors = 1,
  570. .HIDReportType = HID_DTYPE_Report,
  571. .HIDReportLength = sizeof(ConsoleReport)
  572. },
  573. .Console_INEndpoint = {
  574. .Header = {
  575. .Size = sizeof(USB_Descriptor_Endpoint_t),
  576. .Type = DTYPE_Endpoint
  577. },
  578. .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
  579. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  580. .EndpointSize = CONSOLE_EPSIZE,
  581. .PollingIntervalMS = 0x01
  582. },
  583. .Console_OUTEndpoint = {
  584. .Header = {
  585. .Size = sizeof(USB_Descriptor_Endpoint_t),
  586. .Type = DTYPE_Endpoint
  587. },
  588. .EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM),
  589. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  590. .EndpointSize = CONSOLE_EPSIZE,
  591. .PollingIntervalMS = 0x01
  592. },
  593. #endif
  594. #ifdef MIDI_ENABLE
  595. /*
  596. * MIDI
  597. */
  598. .Audio_Interface_Association = {
  599. .Header = {
  600. .Size = sizeof(USB_Descriptor_Interface_Association_t),
  601. .Type = DTYPE_InterfaceAssociation
  602. },
  603. .FirstInterfaceIndex = AC_INTERFACE,
  604. .TotalInterfaces = 2,
  605. .Class = AUDIO_CSCP_AudioClass,
  606. .SubClass = AUDIO_CSCP_ControlSubclass,
  607. .Protocol = AUDIO_CSCP_ControlProtocol,
  608. .IADStrIndex = NO_DESCRIPTOR,
  609. },
  610. .Audio_ControlInterface = {
  611. .Header = {
  612. .Size = sizeof(USB_Descriptor_Interface_t),
  613. .Type = DTYPE_Interface
  614. },
  615. .InterfaceNumber = AC_INTERFACE,
  616. .AlternateSetting = 0,
  617. .TotalEndpoints = 0,
  618. .Class = AUDIO_CSCP_AudioClass,
  619. .SubClass = AUDIO_CSCP_ControlSubclass,
  620. .Protocol = AUDIO_CSCP_ControlProtocol,
  621. .InterfaceStrIndex = NO_DESCRIPTOR
  622. },
  623. .Audio_ControlInterface_SPC = {
  624. .Header = {
  625. .Size = sizeof(USB_Audio_Descriptor_Interface_AC_t),
  626. .Type = AUDIO_DTYPE_CSInterface
  627. },
  628. .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
  629. .ACSpecification = VERSION_BCD(1, 0, 0),
  630. .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
  631. .InCollection = 1,
  632. .InterfaceNumber = AS_INTERFACE,
  633. },
  634. .Audio_StreamInterface = {
  635. .Header = {
  636. .Size = sizeof(USB_Descriptor_Interface_t),
  637. .Type = DTYPE_Interface
  638. },
  639. .InterfaceNumber = AS_INTERFACE,
  640. .AlternateSetting = 0,
  641. .TotalEndpoints = 2,
  642. .Class = AUDIO_CSCP_AudioClass,
  643. .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
  644. .Protocol = AUDIO_CSCP_StreamingProtocol,
  645. .InterfaceStrIndex = NO_DESCRIPTOR
  646. },
  647. .Audio_StreamInterface_SPC = {
  648. .Header = {
  649. .Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t),
  650. .Type = AUDIO_DTYPE_CSInterface
  651. },
  652. .Subtype = AUDIO_DSUBTYPE_CSInterface_General,
  653. .AudioSpecification = VERSION_BCD(1, 0, 0),
  654. .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)
  655. },
  656. .MIDI_In_Jack_Emb = {
  657. .Header = {
  658. .Size = sizeof(USB_MIDI_Descriptor_InputJack_t),
  659. .Type = AUDIO_DTYPE_CSInterface
  660. },
  661. .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
  662. .JackType = MIDI_JACKTYPE_Embedded,
  663. .JackID = 0x01,
  664. .JackStrIndex = NO_DESCRIPTOR
  665. },
  666. .MIDI_In_Jack_Ext = {
  667. .Header = {
  668. .Size = sizeof(USB_MIDI_Descriptor_InputJack_t),
  669. .Type = AUDIO_DTYPE_CSInterface
  670. },
  671. .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
  672. .JackType = MIDI_JACKTYPE_External,
  673. .JackID = 0x02,
  674. .JackStrIndex = NO_DESCRIPTOR
  675. },
  676. .MIDI_Out_Jack_Emb = {
  677. .Header = {
  678. .Size = sizeof(USB_MIDI_Descriptor_OutputJack_t),
  679. .Type = AUDIO_DTYPE_CSInterface
  680. },
  681. .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
  682. .JackType = MIDI_JACKTYPE_Embedded,
  683. .JackID = 0x03,
  684. .NumberOfPins = 1,
  685. .SourceJackID = {0x02},
  686. .SourcePinID = {0x01},
  687. .JackStrIndex = NO_DESCRIPTOR
  688. },
  689. .MIDI_Out_Jack_Ext = {
  690. .Header = {
  691. .Size = sizeof(USB_MIDI_Descriptor_OutputJack_t),
  692. .Type = AUDIO_DTYPE_CSInterface
  693. },
  694. .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
  695. .JackType = MIDI_JACKTYPE_External,
  696. .JackID = 0x04,
  697. .NumberOfPins = 1,
  698. .SourceJackID = {0x01},
  699. .SourcePinID = {0x01},
  700. .JackStrIndex = NO_DESCRIPTOR
  701. },
  702. .MIDI_In_Jack_Endpoint = {
  703. .Endpoint = {
  704. .Header = {
  705. .Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t),
  706. .Type = DTYPE_Endpoint
  707. },
  708. .EndpointAddress = (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM),
  709. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  710. .EndpointSize = MIDI_STREAM_EPSIZE,
  711. .PollingIntervalMS = 0x05
  712. },
  713. .Refresh = 0,
  714. .SyncEndpointNumber = 0
  715. },
  716. .MIDI_In_Jack_Endpoint_SPC = {
  717. .Header = {
  718. .Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t),
  719. .Type = AUDIO_DTYPE_CSEndpoint
  720. },
  721. .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
  722. .TotalEmbeddedJacks = 0x01,
  723. .AssociatedJackID = {0x01}
  724. },
  725. .MIDI_Out_Jack_Endpoint = {
  726. .Endpoint = {
  727. .Header = {
  728. .Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t),
  729. .Type = DTYPE_Endpoint
  730. },
  731. .EndpointAddress = (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM),
  732. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  733. .EndpointSize = MIDI_STREAM_EPSIZE,
  734. .PollingIntervalMS = 0x05
  735. },
  736. .Refresh = 0,
  737. .SyncEndpointNumber = 0
  738. },
  739. .MIDI_Out_Jack_Endpoint_SPC = {
  740. .Header = {
  741. .Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t),
  742. .Type = AUDIO_DTYPE_CSEndpoint
  743. },
  744. .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
  745. .TotalEmbeddedJacks = 0x01,
  746. .AssociatedJackID = {0x03}
  747. },
  748. #endif
  749. #ifdef VIRTSER_ENABLE
  750. /*
  751. * Virtual Serial
  752. */
  753. .CDC_Interface_Association = {
  754. .Header = {
  755. .Size = sizeof(USB_Descriptor_Interface_Association_t),
  756. .Type = DTYPE_InterfaceAssociation
  757. },
  758. .FirstInterfaceIndex = CCI_INTERFACE,
  759. .TotalInterfaces = 2,
  760. .Class = CDC_CSCP_CDCClass,
  761. .SubClass = CDC_CSCP_ACMSubclass,
  762. .Protocol = CDC_CSCP_ATCommandProtocol,
  763. .IADStrIndex = NO_DESCRIPTOR,
  764. },
  765. .CDC_CCI_Interface = {
  766. .Header = {
  767. .Size = sizeof(USB_Descriptor_Interface_t),
  768. .Type = DTYPE_Interface
  769. },
  770. .InterfaceNumber = CCI_INTERFACE,
  771. .AlternateSetting = 0,
  772. .TotalEndpoints = 1,
  773. .Class = CDC_CSCP_CDCClass,
  774. .SubClass = CDC_CSCP_ACMSubclass,
  775. .Protocol = CDC_CSCP_ATCommandProtocol,
  776. .InterfaceStrIndex = NO_DESCRIPTOR
  777. },
  778. .CDC_Functional_Header = {
  779. .Header = {
  780. .Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t),
  781. .Type = CDC_DTYPE_CSInterface
  782. },
  783. .Subtype = 0x00,
  784. .CDCSpecification = VERSION_BCD(1, 1, 0),
  785. },
  786. .CDC_Functional_ACM = {
  787. .Header = {
  788. .Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t),
  789. .Type = CDC_DTYPE_CSInterface
  790. },
  791. .Subtype = 0x02,
  792. .Capabilities = 0x02,
  793. },
  794. .CDC_Functional_Union = {
  795. .Header = {
  796. .Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t),
  797. .Type = CDC_DTYPE_CSInterface
  798. },
  799. .Subtype = 0x06,
  800. .MasterInterfaceNumber = CCI_INTERFACE,
  801. .SlaveInterfaceNumber = CDI_INTERFACE,
  802. },
  803. .CDC_NotificationEndpoint = {
  804. .Header = {
  805. .Size = sizeof(USB_Descriptor_Endpoint_t),
  806. .Type = DTYPE_Endpoint
  807. },
  808. .EndpointAddress = (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM),
  809. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  810. .EndpointSize = CDC_NOTIFICATION_EPSIZE,
  811. .PollingIntervalMS = 0xFF
  812. },
  813. .CDC_DCI_Interface = {
  814. .Header = {
  815. .Size = sizeof(USB_Descriptor_Interface_t),
  816. .Type = DTYPE_Interface
  817. },
  818. .InterfaceNumber = CDI_INTERFACE,
  819. .AlternateSetting = 0,
  820. .TotalEndpoints = 2,
  821. .Class = CDC_CSCP_CDCDataClass,
  822. .SubClass = CDC_CSCP_NoDataSubclass,
  823. .Protocol = CDC_CSCP_NoDataProtocol,
  824. .InterfaceStrIndex = NO_DESCRIPTOR
  825. },
  826. .CDC_DataOutEndpoint = {
  827. .Header = {
  828. .Size = sizeof(USB_Descriptor_Endpoint_t),
  829. .Type = DTYPE_Endpoint
  830. },
  831. .EndpointAddress = (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM),
  832. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  833. .EndpointSize = CDC_EPSIZE,
  834. .PollingIntervalMS = 0x05
  835. },
  836. .CDC_DataInEndpoint = {
  837. .Header = {
  838. .Size = sizeof(USB_Descriptor_Endpoint_t),
  839. .Type = DTYPE_Endpoint
  840. },
  841. .EndpointAddress = (ENDPOINT_DIR_IN | CDC_IN_EPNUM),
  842. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  843. .EndpointSize = CDC_EPSIZE,
  844. .PollingIntervalMS = 0x05
  845. },
  846. #endif
  847. /*
  848. * Joystick
  849. */
  850. #ifdef JOYSTICK_ENABLE
  851. .Joystick_Interface = {
  852. .Header = {
  853. .Size = sizeof(USB_Descriptor_Interface_t),
  854. .Type = DTYPE_Interface
  855. },
  856. .InterfaceNumber = JOYSTICK_INTERFACE,
  857. .AlternateSetting = 0x00,
  858. .TotalEndpoints = 1,
  859. .Class = HID_CSCP_HIDClass,
  860. .SubClass = HID_CSCP_NonBootSubclass,
  861. .Protocol = HID_CSCP_NonBootProtocol,
  862. .InterfaceStrIndex = NO_DESCRIPTOR
  863. },
  864. .Joystick_HID = {
  865. .Header = {
  866. .Size = sizeof(USB_HID_Descriptor_HID_t),
  867. .Type = HID_DTYPE_HID
  868. },
  869. .HIDSpec = VERSION_BCD(1, 1, 1),
  870. .CountryCode = 0x00,
  871. .TotalReportDescriptors = 1,
  872. .HIDReportType = HID_DTYPE_Report,
  873. .HIDReportLength = sizeof(JoystickReport)
  874. },
  875. .Joystick_INEndpoint = {
  876. .Header = {
  877. .Size = sizeof(USB_Descriptor_Endpoint_t),
  878. .Type = DTYPE_Endpoint
  879. },
  880. .EndpointAddress = (ENDPOINT_DIR_IN | JOYSTICK_IN_EPNUM),
  881. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  882. .EndpointSize = JOYSTICK_EPSIZE,
  883. .PollingIntervalMS = USB_POLLING_INTERVAL_MS
  884. }
  885. #endif
  886. };
  887. /*
  888. * String descriptors
  889. */
  890. const USB_Descriptor_String_t PROGMEM LanguageString = {
  891. .Header = {
  892. .Size = USB_STRING_LEN(1),
  893. .Type = DTYPE_String
  894. },
  895. .UnicodeString = {LANGUAGE_ID_ENG}
  896. };
  897. const USB_Descriptor_String_t PROGMEM ManufacturerString = {
  898. .Header = {
  899. .Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER)) - 1), // Subtract 1 for null terminator
  900. .Type = DTYPE_String
  901. },
  902. .UnicodeString = LSTR(MANUFACTURER)
  903. };
  904. const USB_Descriptor_String_t PROGMEM ProductString = {
  905. .Header = {
  906. .Size = USB_STRING_LEN(sizeof(STR(PRODUCT)) - 1), // Subtract 1 for null terminator
  907. .Type = DTYPE_String
  908. },
  909. .UnicodeString = LSTR(PRODUCT)
  910. };
  911. #if defined(SERIAL_NUMBER)
  912. const USB_Descriptor_String_t PROGMEM SerialNumberString = {
  913. .Header = {
  914. .Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1), // Subtract 1 for null terminator
  915. .Type = DTYPE_String
  916. },
  917. .UnicodeString = LSTR(SERIAL_NUMBER)
  918. };
  919. #endif
  920. // clang-format on
  921. /**
  922. * This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
  923. * documentation) by the application code so that the address and size of a requested descriptor can be given
  924. * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
  925. * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
  926. * USB host.
  927. */
  928. uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress) {
  929. const uint8_t DescriptorType = (wValue >> 8);
  930. const uint8_t DescriptorIndex = (wValue & 0xFF);
  931. const void* Address = NULL;
  932. uint16_t Size = NO_DESCRIPTOR;
  933. switch (DescriptorType) {
  934. case DTYPE_Device:
  935. Address = &DeviceDescriptor;
  936. Size = sizeof(USB_Descriptor_Device_t);
  937. break;
  938. case DTYPE_Configuration:
  939. Address = &ConfigurationDescriptor;
  940. Size = sizeof(USB_Descriptor_Configuration_t);
  941. break;
  942. case DTYPE_String:
  943. switch (DescriptorIndex) {
  944. case 0x00:
  945. Address = &LanguageString;
  946. Size = pgm_read_byte(&LanguageString.Header.Size);
  947. break;
  948. case 0x01:
  949. Address = &ManufacturerString;
  950. Size = pgm_read_byte(&ManufacturerString.Header.Size);
  951. break;
  952. case 0x02:
  953. Address = &ProductString;
  954. Size = pgm_read_byte(&ProductString.Header.Size);
  955. break;
  956. #if defined(SERIAL_NUMBER)
  957. case 0x03:
  958. Address = &SerialNumberString;
  959. Size = pgm_read_byte(&SerialNumberString.Header.Size);
  960. break;
  961. #endif
  962. }
  963. break;
  964. case HID_DTYPE_HID:
  965. switch (wIndex) {
  966. #ifndef KEYBOARD_SHARED_EP
  967. case KEYBOARD_INTERFACE:
  968. Address = &ConfigurationDescriptor.Keyboard_HID;
  969. Size = sizeof(USB_HID_Descriptor_HID_t);
  970. break;
  971. #endif
  972. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  973. case MOUSE_INTERFACE:
  974. Address = &ConfigurationDescriptor.Mouse_HID;
  975. Size = sizeof(USB_HID_Descriptor_HID_t);
  976. break;
  977. #endif
  978. #ifdef SHARED_EP_ENABLE
  979. case SHARED_INTERFACE:
  980. Address = &ConfigurationDescriptor.Shared_HID;
  981. Size = sizeof(USB_HID_Descriptor_HID_t);
  982. break;
  983. #endif
  984. #ifdef RAW_ENABLE
  985. case RAW_INTERFACE:
  986. Address = &ConfigurationDescriptor.Raw_HID;
  987. Size = sizeof(USB_HID_Descriptor_HID_t);
  988. break;
  989. #endif
  990. #ifdef CONSOLE_ENABLE
  991. case CONSOLE_INTERFACE:
  992. Address = &ConfigurationDescriptor.Console_HID;
  993. Size = sizeof(USB_HID_Descriptor_HID_t);
  994. break;
  995. #endif
  996. #ifdef JOYSTICK_ENABLE
  997. case JOYSTICK_INTERFACE:
  998. Address = &ConfigurationDescriptor.Joystick_HID;
  999. Size = sizeof(USB_HID_Descriptor_HID_t);
  1000. break;
  1001. #endif
  1002. }
  1003. break;
  1004. case HID_DTYPE_Report:
  1005. switch (wIndex) {
  1006. #ifndef KEYBOARD_SHARED_EP
  1007. case KEYBOARD_INTERFACE:
  1008. Address = &KeyboardReport;
  1009. Size = sizeof(KeyboardReport);
  1010. break;
  1011. #endif
  1012. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  1013. case MOUSE_INTERFACE:
  1014. Address = &MouseReport;
  1015. Size = sizeof(MouseReport);
  1016. break;
  1017. #endif
  1018. #ifdef SHARED_EP_ENABLE
  1019. case SHARED_INTERFACE:
  1020. Address = &SharedReport;
  1021. Size = sizeof(SharedReport);
  1022. break;
  1023. #endif
  1024. #ifdef RAW_ENABLE
  1025. case RAW_INTERFACE:
  1026. Address = &RawReport;
  1027. Size = sizeof(RawReport);
  1028. break;
  1029. #endif
  1030. #ifdef CONSOLE_ENABLE
  1031. case CONSOLE_INTERFACE:
  1032. Address = &ConsoleReport;
  1033. Size = sizeof(ConsoleReport);
  1034. break;
  1035. #endif
  1036. #ifdef JOYSTICK_ENABLE
  1037. case JOYSTICK_INTERFACE:
  1038. Address = &JoystickReport;
  1039. Size = sizeof(JoystickReport);
  1040. break;
  1041. #endif
  1042. }
  1043. break;
  1044. }
  1045. *DescriptorAddress = Address;
  1046. return Size;
  1047. }