usb_descriptor.c 46 KB

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