usb_descriptor.c 46 KB

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