usb_descriptor.c 46 KB

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