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 (5 bits)
  109. HID_RI_USAGE_PAGE(8, 0x09), // Button
  110. HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
  111. HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5
  112. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  113. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  114. HID_RI_REPORT_COUNT(8, 0x05),
  115. HID_RI_REPORT_SIZE(8, 0x01),
  116. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  117. // Button padding (3 bits)
  118. HID_RI_REPORT_COUNT(8, 0x01),
  119. HID_RI_REPORT_SIZE(8, 0x03),
  120. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  121. // X/Y position (2 bytes)
  122. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  123. HID_RI_USAGE(8, 0x30), // X
  124. HID_RI_USAGE(8, 0x31), // Y
  125. HID_RI_LOGICAL_MINIMUM(8, -127),
  126. HID_RI_LOGICAL_MAXIMUM(8, 127),
  127. HID_RI_REPORT_COUNT(8, 0x02),
  128. HID_RI_REPORT_SIZE(8, 0x08),
  129. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  130. // Vertical wheel (1 byte)
  131. HID_RI_USAGE(8, 0x38), // Wheel
  132. HID_RI_LOGICAL_MINIMUM(8, -127),
  133. HID_RI_LOGICAL_MAXIMUM(8, 127),
  134. HID_RI_REPORT_COUNT(8, 0x01),
  135. HID_RI_REPORT_SIZE(8, 0x08),
  136. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  137. // Horizontal wheel (1 byte)
  138. HID_RI_USAGE_PAGE(8, 0x0C), // Consumer
  139. HID_RI_USAGE(16, 0x0238), // AC Pan
  140. HID_RI_LOGICAL_MINIMUM(8, -127),
  141. HID_RI_LOGICAL_MAXIMUM(8, 127),
  142. HID_RI_REPORT_COUNT(8, 0x01),
  143. HID_RI_REPORT_SIZE(8, 0x08),
  144. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  145. HID_RI_END_COLLECTION(0),
  146. HID_RI_END_COLLECTION(0),
  147. # ifndef MOUSE_SHARED_EP
  148. };
  149. # endif
  150. #endif
  151. #if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
  152. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  153. #endif
  154. #ifdef EXTRAKEY_ENABLE
  155. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  156. HID_RI_USAGE(8, 0x80), // System Control
  157. HID_RI_COLLECTION(8, 0x01), // Application
  158. HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
  159. HID_RI_USAGE_MINIMUM(8, 0x01), // Pointer
  160. HID_RI_USAGE_MAXIMUM(16, 0x00B7), // System Display LCD Autoscale
  161. HID_RI_LOGICAL_MINIMUM(8, 0x01),
  162. HID_RI_LOGICAL_MAXIMUM(16, 0x00B7),
  163. HID_RI_REPORT_COUNT(8, 1),
  164. HID_RI_REPORT_SIZE(8, 16),
  165. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  166. HID_RI_END_COLLECTION(0),
  167. HID_RI_USAGE_PAGE(8, 0x0C), // Consumer
  168. HID_RI_USAGE(8, 0x01), // Consumer Control
  169. HID_RI_COLLECTION(8, 0x01), // Application
  170. HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
  171. HID_RI_USAGE_MINIMUM(8, 0x01), // Consumer Control
  172. HID_RI_USAGE_MAXIMUM(16, 0x02A0), // AC Desktop Show All Applications
  173. HID_RI_LOGICAL_MINIMUM(8, 0x01),
  174. HID_RI_LOGICAL_MAXIMUM(16, 0x02A0),
  175. HID_RI_REPORT_COUNT(8, 1),
  176. HID_RI_REPORT_SIZE(8, 16),
  177. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  178. HID_RI_END_COLLECTION(0),
  179. #endif
  180. #ifdef NKRO_ENABLE
  181. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  182. HID_RI_USAGE(8, 0x06), // Keyboard
  183. HID_RI_COLLECTION(8, 0x01), // Application
  184. HID_RI_REPORT_ID(8, REPORT_ID_NKRO),
  185. // Modifiers (8 bits)
  186. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  187. HID_RI_USAGE_MINIMUM(8, 0xE0), // Keyboard Left Control
  188. HID_RI_USAGE_MAXIMUM(8, 0xE7), // Keyboard Right GUI
  189. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  190. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  191. HID_RI_REPORT_COUNT(8, 0x08),
  192. HID_RI_REPORT_SIZE(8, 0x01),
  193. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  194. // Keycodes
  195. HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad
  196. HID_RI_USAGE_MINIMUM(8, 0x00),
  197. HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS * 8 - 1),
  198. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  199. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  200. HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS * 8),
  201. HID_RI_REPORT_SIZE(8, 0x01),
  202. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  203. // Status LEDs (5 bits)
  204. HID_RI_USAGE_PAGE(8, 0x08), // LED
  205. HID_RI_USAGE_MINIMUM(8, 0x01), // Num Lock
  206. HID_RI_USAGE_MAXIMUM(8, 0x05), // Kana
  207. HID_RI_REPORT_COUNT(8, 0x05),
  208. HID_RI_REPORT_SIZE(8, 0x01),
  209. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  210. // LED padding (3 bits)
  211. HID_RI_REPORT_COUNT(8, 0x01),
  212. HID_RI_REPORT_SIZE(8, 0x03),
  213. HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
  214. HID_RI_END_COLLECTION(0),
  215. #endif
  216. #ifdef SHARED_EP_ENABLE
  217. };
  218. #endif
  219. #ifdef RAW_ENABLE
  220. const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] = {
  221. HID_RI_USAGE_PAGE(16, RAW_USAGE_PAGE), // Vendor Defined
  222. HID_RI_USAGE(8, RAW_USAGE_ID), // Vendor Defined
  223. HID_RI_COLLECTION(8, 0x01), // Application
  224. // Data to host
  225. HID_RI_USAGE(8, 0x62), // Vendor Defined
  226. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  227. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  228. HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
  229. HID_RI_REPORT_SIZE(8, 0x08),
  230. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  231. // Data from host
  232. HID_RI_USAGE(8, 0x63), // Vendor Defined
  233. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  234. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  235. HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
  236. HID_RI_REPORT_SIZE(8, 0x08),
  237. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  238. HID_RI_END_COLLECTION(0),
  239. };
  240. #endif
  241. #ifdef CONSOLE_ENABLE
  242. const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
  243. HID_RI_USAGE_PAGE(16, 0xFF31), // Vendor Defined (PJRC Teensy compatible)
  244. HID_RI_USAGE(8, 0x74), // Vendor Defined (PJRC Teensy compatible)
  245. HID_RI_COLLECTION(8, 0x01), // Application
  246. // Data to host
  247. HID_RI_USAGE(8, 0x75), // Vendor Defined
  248. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  249. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  250. HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
  251. HID_RI_REPORT_SIZE(8, 0x08),
  252. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  253. // Data from host
  254. HID_RI_USAGE(8, 0x76), // Vendor Defined
  255. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  256. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  257. HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
  258. HID_RI_REPORT_SIZE(8, 0x08),
  259. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  260. HID_RI_END_COLLECTION(0),
  261. };
  262. #endif
  263. #ifdef JOYSTICK_ENABLE
  264. # if JOYSTICK_AXES_COUNT == 0 && JOYSTICK_BUTTON_COUNT == 0
  265. # error Need at least one axis or button for joystick
  266. # endif
  267. const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] = {
  268. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  269. HID_RI_USAGE(8, 0x04), // Joystick
  270. HID_RI_COLLECTION(8, 0x01), // Application
  271. HID_RI_COLLECTION(8, 0x00), // Physical
  272. HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
  273. # if JOYSTICK_AXES_COUNT >= 1
  274. HID_RI_USAGE(8, 0x30), // X
  275. # endif
  276. # if JOYSTICK_AXES_COUNT >= 2
  277. HID_RI_USAGE(8, 0x31), // Y
  278. # endif
  279. # if JOYSTICK_AXES_COUNT >= 3
  280. HID_RI_USAGE(8, 0x32), // Z
  281. # endif
  282. # if JOYSTICK_AXES_COUNT >= 4
  283. HID_RI_USAGE(8, 0x33), // Rx
  284. # endif
  285. # if JOYSTICK_AXES_COUNT >= 5
  286. HID_RI_USAGE(8, 0x34), // Ry
  287. # endif
  288. # if JOYSTICK_AXES_COUNT >= 6
  289. HID_RI_USAGE(8, 0x35), // Rz
  290. # endif
  291. # if JOYSTICK_AXES_COUNT >= 1
  292. # if JOYSTICK_AXES_RESOLUTION == 8
  293. HID_RI_LOGICAL_MINIMUM(8, -JOYSTICK_RESOLUTION),
  294. HID_RI_LOGICAL_MAXIMUM(8, JOYSTICK_RESOLUTION),
  295. HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
  296. HID_RI_REPORT_SIZE(8, 0x08),
  297. # else
  298. HID_RI_LOGICAL_MINIMUM(16, -JOYSTICK_RESOLUTION),
  299. HID_RI_LOGICAL_MAXIMUM(16, JOYSTICK_RESOLUTION),
  300. HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
  301. HID_RI_REPORT_SIZE(8, 0x10),
  302. # endif
  303. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  304. # endif
  305. # if JOYSTICK_BUTTON_COUNT >= 1
  306. HID_RI_USAGE_PAGE(8, 0x09), // Button
  307. HID_RI_USAGE_MINIMUM(8, 0x01),
  308. HID_RI_USAGE_MAXIMUM(8, JOYSTICK_BUTTON_COUNT),
  309. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  310. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  311. HID_RI_REPORT_COUNT(8, JOYSTICK_BUTTON_COUNT),
  312. HID_RI_REPORT_SIZE(8, 0x01),
  313. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  314. # if (JOYSTICK_BUTTON_COUNT % 8) != 0
  315. HID_RI_REPORT_COUNT(8, 8 - (JOYSTICK_BUTTON_COUNT % 8)),
  316. HID_RI_REPORT_SIZE(8, 0x01),
  317. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  318. # endif
  319. # endif
  320. HID_RI_END_COLLECTION(0),
  321. HID_RI_END_COLLECTION(0)
  322. };
  323. #endif
  324. /*
  325. * Device descriptor
  326. */
  327. const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
  328. .Header = {
  329. .Size = sizeof(USB_Descriptor_Device_t),
  330. .Type = DTYPE_Device
  331. },
  332. .USBSpecification = VERSION_BCD(1, 1, 0),
  333. #if VIRTSER_ENABLE
  334. .Class = USB_CSCP_IADDeviceClass,
  335. .SubClass = USB_CSCP_IADDeviceSubclass,
  336. .Protocol = USB_CSCP_IADDeviceProtocol,
  337. #else
  338. .Class = USB_CSCP_NoDeviceClass,
  339. .SubClass = USB_CSCP_NoDeviceSubclass,
  340. .Protocol = USB_CSCP_NoDeviceProtocol,
  341. #endif
  342. .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
  343. // Specified in config.h
  344. .VendorID = VENDOR_ID,
  345. .ProductID = PRODUCT_ID,
  346. .ReleaseNumber = DEVICE_VER,
  347. .ManufacturerStrIndex = 0x01,
  348. .ProductStrIndex = 0x02,
  349. .SerialNumStrIndex = 0x03,
  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. #ifndef SERIAL_NUMBER
  912. # define SERIAL_NUMBER 0
  913. #endif
  914. const USB_Descriptor_String_t PROGMEM SerialNumberString = {
  915. .Header = {
  916. .Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1), // Subtract 1 for null terminator
  917. .Type = DTYPE_String
  918. },
  919. .UnicodeString = LSTR(SERIAL_NUMBER)
  920. };
  921. // clang-format on
  922. /**
  923. * This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
  924. * documentation) by the application code so that the address and size of a requested descriptor can be given
  925. * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
  926. * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
  927. * USB host.
  928. */
  929. uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress) {
  930. const uint8_t DescriptorType = (wValue >> 8);
  931. const uint8_t DescriptorIndex = (wValue & 0xFF);
  932. const void* Address = NULL;
  933. uint16_t Size = NO_DESCRIPTOR;
  934. switch (DescriptorType) {
  935. case DTYPE_Device:
  936. Address = &DeviceDescriptor;
  937. Size = sizeof(USB_Descriptor_Device_t);
  938. break;
  939. case DTYPE_Configuration:
  940. Address = &ConfigurationDescriptor;
  941. Size = sizeof(USB_Descriptor_Configuration_t);
  942. break;
  943. case DTYPE_String:
  944. switch (DescriptorIndex) {
  945. case 0x00:
  946. Address = &LanguageString;
  947. Size = pgm_read_byte(&LanguageString.Header.Size);
  948. break;
  949. case 0x01:
  950. Address = &ManufacturerString;
  951. Size = pgm_read_byte(&ManufacturerString.Header.Size);
  952. break;
  953. case 0x02:
  954. Address = &ProductString;
  955. Size = pgm_read_byte(&ProductString.Header.Size);
  956. break;
  957. case 0x03:
  958. Address = &SerialNumberString;
  959. Size = pgm_read_byte(&SerialNumberString.Header.Size);
  960. break;
  961. }
  962. break;
  963. case HID_DTYPE_HID:
  964. switch (wIndex) {
  965. #ifndef KEYBOARD_SHARED_EP
  966. case KEYBOARD_INTERFACE:
  967. Address = &ConfigurationDescriptor.Keyboard_HID;
  968. Size = sizeof(USB_HID_Descriptor_HID_t);
  969. break;
  970. #endif
  971. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  972. case MOUSE_INTERFACE:
  973. Address = &ConfigurationDescriptor.Mouse_HID;
  974. Size = sizeof(USB_HID_Descriptor_HID_t);
  975. break;
  976. #endif
  977. #ifdef SHARED_EP_ENABLE
  978. case SHARED_INTERFACE:
  979. Address = &ConfigurationDescriptor.Shared_HID;
  980. Size = sizeof(USB_HID_Descriptor_HID_t);
  981. break;
  982. #endif
  983. #ifdef RAW_ENABLE
  984. case RAW_INTERFACE:
  985. Address = &ConfigurationDescriptor.Raw_HID;
  986. Size = sizeof(USB_HID_Descriptor_HID_t);
  987. break;
  988. #endif
  989. #ifdef CONSOLE_ENABLE
  990. case CONSOLE_INTERFACE:
  991. Address = &ConfigurationDescriptor.Console_HID;
  992. Size = sizeof(USB_HID_Descriptor_HID_t);
  993. break;
  994. #endif
  995. #ifdef JOYSTICK_ENABLE
  996. case JOYSTICK_INTERFACE:
  997. Address = &ConfigurationDescriptor.Joystick_HID;
  998. Size = sizeof(USB_HID_Descriptor_HID_t);
  999. break;
  1000. #endif
  1001. }
  1002. break;
  1003. case HID_DTYPE_Report:
  1004. switch (wIndex) {
  1005. #ifndef KEYBOARD_SHARED_EP
  1006. case KEYBOARD_INTERFACE:
  1007. Address = &KeyboardReport;
  1008. Size = sizeof(KeyboardReport);
  1009. break;
  1010. #endif
  1011. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  1012. case MOUSE_INTERFACE:
  1013. Address = &MouseReport;
  1014. Size = sizeof(MouseReport);
  1015. break;
  1016. #endif
  1017. #ifdef SHARED_EP_ENABLE
  1018. case SHARED_INTERFACE:
  1019. Address = &SharedReport;
  1020. Size = sizeof(SharedReport);
  1021. break;
  1022. #endif
  1023. #ifdef RAW_ENABLE
  1024. case RAW_INTERFACE:
  1025. Address = &RawReport;
  1026. Size = sizeof(RawReport);
  1027. break;
  1028. #endif
  1029. #ifdef CONSOLE_ENABLE
  1030. case CONSOLE_INTERFACE:
  1031. Address = &ConsoleReport;
  1032. Size = sizeof(ConsoleReport);
  1033. break;
  1034. #endif
  1035. #ifdef JOYSTICK_ENABLE
  1036. case JOYSTICK_INTERFACE:
  1037. Address = &JoystickReport;
  1038. Size = sizeof(JoystickReport);
  1039. break;
  1040. #endif
  1041. }
  1042. break;
  1043. }
  1044. *DescriptorAddress = Address;
  1045. return Size;
  1046. }