usb_descriptor.c 46 KB

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