usb_descriptor.c 41 KB

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