usb_descriptor.c 41 KB

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