usb_descriptor.c 45 KB

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