usb_descriptor.c 46 KB

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