usb_descriptor.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  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. #ifndef USB_MAX_POWER_CONSUMPTION
  37. #define USB_MAX_POWER_CONSUMPTION 500
  38. #endif
  39. /*******************************************************************************
  40. * HID Report Descriptors
  41. ******************************************************************************/
  42. #ifdef KEYBOARD_SHARED_EP
  43. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  44. #define SHARED_REPORT_STARTED
  45. #else
  46. const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = {
  47. #endif
  48. HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
  49. HID_RI_USAGE(8, 0x06), /* Keyboard */
  50. HID_RI_COLLECTION(8, 0x01), /* Application */
  51. # ifdef KEYBOARD_SHARED_EP
  52. HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD),
  53. # endif
  54. HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
  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. HID_RI_REPORT_COUNT(8, 0x01),
  63. HID_RI_REPORT_SIZE(8, 0x08),
  64. HID_RI_INPUT(8, HID_IOF_CONSTANT), /* reserved */
  65. HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
  66. HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
  67. HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
  68. HID_RI_REPORT_COUNT(8, 0x05),
  69. HID_RI_REPORT_SIZE(8, 0x01),
  70. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  71. HID_RI_REPORT_COUNT(8, 0x01),
  72. HID_RI_REPORT_SIZE(8, 0x03),
  73. HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
  74. HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
  75. HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
  76. HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
  77. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  78. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  79. HID_RI_REPORT_COUNT(8, 0x06),
  80. HID_RI_REPORT_SIZE(8, 0x08),
  81. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  82. HID_RI_END_COLLECTION(0),
  83. #ifndef KEYBOARD_SHARED_EP
  84. };
  85. #endif
  86. #if defined(MOUSE_ENABLE)
  87. # if !defined(MOUSE_SHARED_EP)
  88. const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = {
  89. # elif !defined(SHARED_REPORT_STARTED)
  90. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  91. #define SHARED_REPORT_STARTED
  92. # endif
  93. HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
  94. HID_RI_USAGE(8, 0x02), /* Mouse */
  95. HID_RI_COLLECTION(8, 0x01), /* Application */
  96. # ifdef MOUSE_SHARED_EP
  97. HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
  98. # endif
  99. HID_RI_USAGE(8, 0x01), /* Pointer */
  100. HID_RI_COLLECTION(8, 0x00), /* Physical */
  101. HID_RI_USAGE_PAGE(8, 0x09), /* Button */
  102. HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */
  103. HID_RI_USAGE_MAXIMUM(8, 0x05), /* Button 5 */
  104. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  105. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  106. HID_RI_REPORT_COUNT(8, 0x05),
  107. HID_RI_REPORT_SIZE(8, 0x01),
  108. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  109. HID_RI_REPORT_COUNT(8, 0x01),
  110. HID_RI_REPORT_SIZE(8, 0x03),
  111. HID_RI_INPUT(8, HID_IOF_CONSTANT),
  112. HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
  113. HID_RI_USAGE(8, 0x30), /* Usage X */
  114. HID_RI_USAGE(8, 0x31), /* Usage Y */
  115. HID_RI_LOGICAL_MINIMUM(8, -127),
  116. HID_RI_LOGICAL_MAXIMUM(8, 127),
  117. HID_RI_REPORT_COUNT(8, 0x02),
  118. HID_RI_REPORT_SIZE(8, 0x08),
  119. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  120. HID_RI_USAGE(8, 0x38), /* Wheel */
  121. HID_RI_LOGICAL_MINIMUM(8, -127),
  122. HID_RI_LOGICAL_MAXIMUM(8, 127),
  123. HID_RI_REPORT_COUNT(8, 0x01),
  124. HID_RI_REPORT_SIZE(8, 0x08),
  125. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  126. HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
  127. HID_RI_USAGE(16, 0x0238), /* AC Pan (Horizontal wheel) */
  128. HID_RI_LOGICAL_MINIMUM(8, -127),
  129. HID_RI_LOGICAL_MAXIMUM(8, 127),
  130. HID_RI_REPORT_COUNT(8, 0x01),
  131. HID_RI_REPORT_SIZE(8, 0x08),
  132. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
  133. HID_RI_END_COLLECTION(0),
  134. HID_RI_END_COLLECTION(0),
  135. # ifndef MOUSE_SHARED_EP
  136. };
  137. # endif
  138. #endif
  139. #if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
  140. const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
  141. #endif
  142. # ifdef EXTRAKEY_ENABLE
  143. HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
  144. HID_RI_USAGE(8, 0x80), /* System Control */
  145. HID_RI_COLLECTION(8, 0x01), /* Application */
  146. HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
  147. HID_RI_LOGICAL_MINIMUM(16, 0x0001),
  148. HID_RI_LOGICAL_MAXIMUM(16, 0x0003),
  149. HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
  150. HID_RI_USAGE_MAXIMUM(16, 0x0083), /* System Wake Up */
  151. HID_RI_REPORT_SIZE(8, 16),
  152. HID_RI_REPORT_COUNT(8, 1),
  153. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  154. HID_RI_END_COLLECTION(0),
  155. HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
  156. HID_RI_USAGE(8, 0x01), /* Consumer Control */
  157. HID_RI_COLLECTION(8, 0x01), /* Application */
  158. HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
  159. HID_RI_LOGICAL_MINIMUM(16, 0x0001),
  160. HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
  161. HID_RI_USAGE_MINIMUM(16, 0x0001), /* +10 */
  162. HID_RI_USAGE_MAXIMUM(16, 0x029C), /* AC Distribute Vertically */
  163. HID_RI_REPORT_SIZE(8, 16),
  164. HID_RI_REPORT_COUNT(8, 1),
  165. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
  166. HID_RI_END_COLLECTION(0),
  167. # endif
  168. # ifdef NKRO_ENABLE
  169. HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
  170. HID_RI_USAGE(8, 0x06), /* Keyboard */
  171. HID_RI_COLLECTION(8, 0x01), /* Application */
  172. HID_RI_REPORT_ID(8, REPORT_ID_NKRO),
  173. HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
  174. HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
  175. HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
  176. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  177. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  178. HID_RI_REPORT_COUNT(8, 0x08),
  179. HID_RI_REPORT_SIZE(8, 0x01),
  180. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  181. HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
  182. HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
  183. HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
  184. HID_RI_REPORT_COUNT(8, 0x05),
  185. HID_RI_REPORT_SIZE(8, 0x01),
  186. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  187. HID_RI_REPORT_COUNT(8, 0x01),
  188. HID_RI_REPORT_SIZE(8, 0x03),
  189. HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
  190. HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
  191. HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
  192. HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS*8-1),
  193. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  194. HID_RI_LOGICAL_MAXIMUM(8, 0x01),
  195. HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS*8),
  196. HID_RI_REPORT_SIZE(8, 0x01),
  197. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  198. HID_RI_END_COLLECTION(0),
  199. # endif
  200. #ifdef SHARED_EP_ENABLE
  201. };
  202. #endif
  203. #ifdef RAW_ENABLE
  204. const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] =
  205. {
  206. HID_RI_USAGE_PAGE(16, 0xFF60), /* Vendor Page 0xFF60 */
  207. HID_RI_USAGE(8, 0x61), /* Vendor Usage 0x61 */
  208. HID_RI_COLLECTION(8, 0x01), /* Application */
  209. HID_RI_USAGE(8, 0x62), /* Vendor Usage 0x62 */
  210. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  211. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  212. HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
  213. HID_RI_REPORT_SIZE(8, 0x08),
  214. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  215. HID_RI_USAGE(8, 0x63), /* Vendor Usage 0x63 */
  216. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  217. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  218. HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
  219. HID_RI_REPORT_SIZE(8, 0x08),
  220. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  221. HID_RI_END_COLLECTION(0),
  222. };
  223. #endif
  224. #ifdef CONSOLE_ENABLE
  225. const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
  226. {
  227. HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */
  228. HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */
  229. HID_RI_COLLECTION(8, 0x01), /* Application */
  230. HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
  231. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  232. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  233. HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
  234. HID_RI_REPORT_SIZE(8, 0x08),
  235. HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  236. HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
  237. HID_RI_LOGICAL_MINIMUM(8, 0x00),
  238. HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
  239. HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
  240. HID_RI_REPORT_SIZE(8, 0x08),
  241. HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
  242. HID_RI_END_COLLECTION(0),
  243. };
  244. #endif
  245. /*******************************************************************************
  246. * Device Descriptors
  247. ******************************************************************************/
  248. const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
  249. {
  250. .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
  251. .USBSpecification = VERSION_BCD(1,1,0),
  252. #if VIRTSER_ENABLE
  253. .Class = USB_CSCP_IADDeviceClass,
  254. .SubClass = USB_CSCP_IADDeviceSubclass,
  255. .Protocol = USB_CSCP_IADDeviceProtocol,
  256. #else
  257. .Class = USB_CSCP_NoDeviceClass,
  258. .SubClass = USB_CSCP_NoDeviceSubclass,
  259. .Protocol = USB_CSCP_NoDeviceProtocol,
  260. #endif
  261. .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
  262. /* specified in config.h */
  263. .VendorID = VENDOR_ID,
  264. .ProductID = PRODUCT_ID,
  265. .ReleaseNumber = DEVICE_VER,
  266. .ManufacturerStrIndex = 0x01,
  267. .ProductStrIndex = 0x02,
  268. .SerialNumStrIndex = 0x03,
  269. .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
  270. };
  271. /*******************************************************************************
  272. * Configuration Descriptors
  273. ******************************************************************************/
  274. const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
  275. {
  276. .Config =
  277. {
  278. .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
  279. .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
  280. .TotalInterfaces = TOTAL_INTERFACES,
  281. .ConfigurationNumber = 1,
  282. .ConfigurationStrIndex = NO_DESCRIPTOR,
  283. .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
  284. .MaxPowerConsumption = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)
  285. },
  286. /*
  287. * Keyboard
  288. */
  289. #ifndef KEYBOARD_SHARED_EP
  290. .Keyboard_Interface =
  291. {
  292. .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
  293. .InterfaceNumber = KEYBOARD_INTERFACE,
  294. .AlternateSetting = 0x00,
  295. .TotalEndpoints = 1,
  296. .Class = HID_CSCP_HIDClass,
  297. .SubClass = HID_CSCP_BootSubclass,
  298. .Protocol = HID_CSCP_KeyboardBootProtocol,
  299. .InterfaceStrIndex = NO_DESCRIPTOR
  300. },
  301. .Keyboard_HID =
  302. {
  303. .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
  304. .HIDSpec = VERSION_BCD(1,1,1),
  305. .CountryCode = 0x00,
  306. .TotalReportDescriptors = 1,
  307. .HIDReportType = HID_DTYPE_Report,
  308. .HIDReportLength = sizeof(KeyboardReport)
  309. },
  310. .Keyboard_INEndpoint =
  311. {
  312. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  313. .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
  314. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  315. .EndpointSize = KEYBOARD_EPSIZE,
  316. .PollingIntervalMS = 0x0A
  317. },
  318. #endif
  319. /*
  320. * Mouse
  321. */
  322. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  323. .Mouse_Interface =
  324. {
  325. .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
  326. .InterfaceNumber = MOUSE_INTERFACE,
  327. .AlternateSetting = 0x00,
  328. .TotalEndpoints = 1,
  329. .Class = HID_CSCP_HIDClass,
  330. .SubClass = HID_CSCP_BootSubclass,
  331. .Protocol = HID_CSCP_MouseBootProtocol,
  332. .InterfaceStrIndex = NO_DESCRIPTOR
  333. },
  334. .Mouse_HID =
  335. {
  336. .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
  337. .HIDSpec = VERSION_BCD(1,1,1),
  338. .CountryCode = 0x00,
  339. .TotalReportDescriptors = 1,
  340. .HIDReportType = HID_DTYPE_Report,
  341. .HIDReportLength = sizeof(MouseReport)
  342. },
  343. .Mouse_INEndpoint =
  344. {
  345. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  346. .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
  347. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  348. .EndpointSize = MOUSE_EPSIZE,
  349. .PollingIntervalMS = 0x0A
  350. },
  351. #endif
  352. /*
  353. * Shared
  354. */
  355. #ifdef SHARED_EP_ENABLE
  356. .Shared_Interface =
  357. {
  358. .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
  359. .InterfaceNumber = SHARED_INTERFACE,
  360. .AlternateSetting = 0x00,
  361. .TotalEndpoints = 1,
  362. .Class = HID_CSCP_HIDClass,
  363. # ifdef KEYBOARD_SHARED_EP
  364. .SubClass = HID_CSCP_BootSubclass,
  365. .Protocol = HID_CSCP_KeyboardBootProtocol,
  366. # else
  367. .SubClass = HID_CSCP_NonBootSubclass,
  368. .Protocol = HID_CSCP_NonBootProtocol,
  369. #endif
  370. .InterfaceStrIndex = NO_DESCRIPTOR
  371. },
  372. .Shared_HID =
  373. {
  374. .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
  375. .HIDSpec = VERSION_BCD(1,1,1),
  376. .CountryCode = 0x00,
  377. .TotalReportDescriptors = 1,
  378. .HIDReportType = HID_DTYPE_Report,
  379. .HIDReportLength = sizeof(SharedReport)
  380. },
  381. .Shared_INEndpoint =
  382. {
  383. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  384. .EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM),
  385. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  386. .EndpointSize = SHARED_EPSIZE,
  387. .PollingIntervalMS = 0x0A
  388. },
  389. #endif
  390. /*
  391. * Raw
  392. */
  393. #ifdef RAW_ENABLE
  394. .Raw_Interface =
  395. {
  396. .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
  397. .InterfaceNumber = RAW_INTERFACE,
  398. .AlternateSetting = 0x00,
  399. .TotalEndpoints = 2,
  400. .Class = HID_CSCP_HIDClass,
  401. .SubClass = HID_CSCP_NonBootSubclass,
  402. .Protocol = HID_CSCP_NonBootProtocol,
  403. .InterfaceStrIndex = NO_DESCRIPTOR
  404. },
  405. .Raw_HID =
  406. {
  407. .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
  408. .HIDSpec = VERSION_BCD(1,1,1),
  409. .CountryCode = 0x00,
  410. .TotalReportDescriptors = 1,
  411. .HIDReportType = HID_DTYPE_Report,
  412. .HIDReportLength = sizeof(RawReport)
  413. },
  414. .Raw_INEndpoint =
  415. {
  416. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  417. .EndpointAddress = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
  418. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  419. .EndpointSize = RAW_EPSIZE,
  420. .PollingIntervalMS = 0x01
  421. },
  422. .Raw_OUTEndpoint =
  423. {
  424. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  425. .EndpointAddress = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
  426. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  427. .EndpointSize = RAW_EPSIZE,
  428. .PollingIntervalMS = 0x01
  429. },
  430. #endif
  431. /*
  432. * Console
  433. */
  434. #ifdef CONSOLE_ENABLE
  435. .Console_Interface =
  436. {
  437. .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
  438. .InterfaceNumber = CONSOLE_INTERFACE,
  439. .AlternateSetting = 0x00,
  440. .TotalEndpoints = 2,
  441. .Class = HID_CSCP_HIDClass,
  442. .SubClass = HID_CSCP_NonBootSubclass,
  443. .Protocol = HID_CSCP_NonBootProtocol,
  444. .InterfaceStrIndex = NO_DESCRIPTOR
  445. },
  446. .Console_HID =
  447. {
  448. .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
  449. .HIDSpec = VERSION_BCD(1,1,1),
  450. .CountryCode = 0x00,
  451. .TotalReportDescriptors = 1,
  452. .HIDReportType = HID_DTYPE_Report,
  453. .HIDReportLength = sizeof(ConsoleReport)
  454. },
  455. .Console_INEndpoint =
  456. {
  457. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  458. .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
  459. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  460. .EndpointSize = CONSOLE_EPSIZE,
  461. .PollingIntervalMS = 0x01
  462. },
  463. .Console_OUTEndpoint =
  464. {
  465. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  466. .EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM),
  467. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  468. .EndpointSize = CONSOLE_EPSIZE,
  469. .PollingIntervalMS = 0x01
  470. },
  471. #endif
  472. #ifdef MIDI_ENABLE
  473. .Audio_Interface_Association =
  474. {
  475. .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
  476. .FirstInterfaceIndex = AC_INTERFACE,
  477. .TotalInterfaces = 2,
  478. .Class = AUDIO_CSCP_AudioClass,
  479. .SubClass = AUDIO_CSCP_ControlSubclass,
  480. .Protocol = AUDIO_CSCP_ControlProtocol,
  481. .IADStrIndex = NO_DESCRIPTOR,
  482. },
  483. .Audio_ControlInterface =
  484. {
  485. .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
  486. .InterfaceNumber = AC_INTERFACE,
  487. .AlternateSetting = 0,
  488. .TotalEndpoints = 0,
  489. .Class = AUDIO_CSCP_AudioClass,
  490. .SubClass = AUDIO_CSCP_ControlSubclass,
  491. .Protocol = AUDIO_CSCP_ControlProtocol,
  492. .InterfaceStrIndex = NO_DESCRIPTOR
  493. },
  494. .Audio_ControlInterface_SPC =
  495. {
  496. .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
  497. .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
  498. .ACSpecification = VERSION_BCD(1,0,0),
  499. .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
  500. .InCollection = 1,
  501. .InterfaceNumber = AS_INTERFACE,
  502. },
  503. .Audio_StreamInterface =
  504. {
  505. .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
  506. .InterfaceNumber = AS_INTERFACE,
  507. .AlternateSetting = 0,
  508. .TotalEndpoints = 2,
  509. .Class = AUDIO_CSCP_AudioClass,
  510. .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
  511. .Protocol = AUDIO_CSCP_StreamingProtocol,
  512. .InterfaceStrIndex = NO_DESCRIPTOR
  513. },
  514. .Audio_StreamInterface_SPC =
  515. {
  516. .Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
  517. .Subtype = AUDIO_DSUBTYPE_CSInterface_General,
  518. .AudioSpecification = VERSION_BCD(1,0,0),
  519. .TotalLength = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC)
  520. + sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t)
  521. - offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)
  522. },
  523. .MIDI_In_Jack_Emb =
  524. {
  525. .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
  526. .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
  527. .JackType = MIDI_JACKTYPE_Embedded,
  528. .JackID = 0x01,
  529. .JackStrIndex = NO_DESCRIPTOR
  530. },
  531. .MIDI_In_Jack_Ext =
  532. {
  533. .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
  534. .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
  535. .JackType = MIDI_JACKTYPE_External,
  536. .JackID = 0x02,
  537. .JackStrIndex = NO_DESCRIPTOR
  538. },
  539. .MIDI_Out_Jack_Emb =
  540. {
  541. .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
  542. .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
  543. .JackType = MIDI_JACKTYPE_Embedded,
  544. .JackID = 0x03,
  545. .NumberOfPins = 1,
  546. .SourceJackID = {0x02},
  547. .SourcePinID = {0x01},
  548. .JackStrIndex = NO_DESCRIPTOR
  549. },
  550. .MIDI_Out_Jack_Ext =
  551. {
  552. .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
  553. .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
  554. .JackType = MIDI_JACKTYPE_External,
  555. .JackID = 0x04,
  556. .NumberOfPins = 1,
  557. .SourceJackID = {0x01},
  558. .SourcePinID = {0x01},
  559. .JackStrIndex = NO_DESCRIPTOR
  560. },
  561. .MIDI_In_Jack_Endpoint =
  562. {
  563. .Endpoint =
  564. {
  565. .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
  566. .EndpointAddress = MIDI_STREAM_OUT_EPADDR,
  567. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  568. .EndpointSize = MIDI_STREAM_EPSIZE,
  569. .PollingIntervalMS = 0x05
  570. },
  571. .Refresh = 0,
  572. .SyncEndpointNumber = 0
  573. },
  574. .MIDI_In_Jack_Endpoint_SPC =
  575. {
  576. .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
  577. .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
  578. .TotalEmbeddedJacks = 0x01,
  579. .AssociatedJackID = {0x01}
  580. },
  581. .MIDI_Out_Jack_Endpoint =
  582. {
  583. .Endpoint =
  584. {
  585. .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
  586. .EndpointAddress = MIDI_STREAM_IN_EPADDR,
  587. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  588. .EndpointSize = MIDI_STREAM_EPSIZE,
  589. .PollingIntervalMS = 0x05
  590. },
  591. .Refresh = 0,
  592. .SyncEndpointNumber = 0
  593. },
  594. .MIDI_Out_Jack_Endpoint_SPC =
  595. {
  596. .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
  597. .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
  598. .TotalEmbeddedJacks = 0x01,
  599. .AssociatedJackID = {0x03}
  600. },
  601. #endif
  602. #ifdef VIRTSER_ENABLE
  603. .CDC_Interface_Association =
  604. {
  605. .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
  606. .FirstInterfaceIndex = CCI_INTERFACE,
  607. .TotalInterfaces = 2,
  608. .Class = CDC_CSCP_CDCClass,
  609. .SubClass = CDC_CSCP_ACMSubclass,
  610. .Protocol = CDC_CSCP_ATCommandProtocol,
  611. .IADStrIndex = NO_DESCRIPTOR,
  612. },
  613. .CDC_CCI_Interface =
  614. {
  615. .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
  616. .InterfaceNumber = CCI_INTERFACE,
  617. .AlternateSetting = 0,
  618. .TotalEndpoints = 1,
  619. .Class = CDC_CSCP_CDCClass,
  620. .SubClass = CDC_CSCP_ACMSubclass,
  621. .Protocol = CDC_CSCP_ATCommandProtocol,
  622. .InterfaceStrIndex = NO_DESCRIPTOR
  623. },
  624. .CDC_Functional_Header =
  625. {
  626. .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
  627. .Subtype = 0x00,
  628. .CDCSpecification = VERSION_BCD(1,1,0),
  629. },
  630. .CDC_Functional_ACM =
  631. {
  632. .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
  633. .Subtype = 0x02,
  634. .Capabilities = 0x02,
  635. },
  636. .CDC_Functional_Union =
  637. {
  638. .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
  639. .Subtype = 0x06,
  640. .MasterInterfaceNumber = CCI_INTERFACE,
  641. .SlaveInterfaceNumber = CDI_INTERFACE,
  642. },
  643. .CDC_NotificationEndpoint =
  644. {
  645. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  646. .EndpointAddress = CDC_NOTIFICATION_EPADDR,
  647. .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  648. .EndpointSize = CDC_NOTIFICATION_EPSIZE,
  649. .PollingIntervalMS = 0xFF
  650. },
  651. .CDC_DCI_Interface =
  652. {
  653. .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
  654. .InterfaceNumber = CDI_INTERFACE,
  655. .AlternateSetting = 0,
  656. .TotalEndpoints = 2,
  657. .Class = CDC_CSCP_CDCDataClass,
  658. .SubClass = CDC_CSCP_NoDataSubclass,
  659. .Protocol = CDC_CSCP_NoDataProtocol,
  660. .InterfaceStrIndex = NO_DESCRIPTOR
  661. },
  662. .CDC_DataOutEndpoint =
  663. {
  664. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  665. .EndpointAddress = CDC_OUT_EPADDR,
  666. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  667. .EndpointSize = CDC_EPSIZE,
  668. .PollingIntervalMS = 0x05
  669. },
  670. .CDC_DataInEndpoint =
  671. {
  672. .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
  673. .EndpointAddress = CDC_IN_EPADDR,
  674. .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
  675. .EndpointSize = CDC_EPSIZE,
  676. .PollingIntervalMS = 0x05
  677. },
  678. #endif
  679. };
  680. /*******************************************************************************
  681. * String Descriptors
  682. ******************************************************************************/
  683. const USB_Descriptor_String_t PROGMEM LanguageString =
  684. {
  685. .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
  686. .UnicodeString = {LANGUAGE_ID_ENG}
  687. };
  688. const USB_Descriptor_String_t PROGMEM ManufacturerString =
  689. {
  690. /* subtract 1 for null terminator */
  691. .Header = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String},
  692. .UnicodeString = LSTR(MANUFACTURER)
  693. };
  694. const USB_Descriptor_String_t PROGMEM ProductString =
  695. {
  696. /* subtract 1 for null terminator */
  697. .Header = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String},
  698. .UnicodeString = LSTR(PRODUCT)
  699. };
  700. #ifndef SERIAL_NUMBER
  701. #define SERIAL_NUMBER 0
  702. #endif
  703. const USB_Descriptor_String_t PROGMEM SerialNumberString =
  704. {
  705. /* subtract 1 for null terminator */
  706. .Header = {.Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER))-1), .Type = DTYPE_String},
  707. .UnicodeString = LSTR(SERIAL_NUMBER)
  708. };
  709. /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
  710. * documentation) by the application code so that the address and size of a requested descriptor can be given
  711. * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
  712. * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
  713. * USB host.
  714. */
  715. uint16_t get_usb_descriptor(const uint16_t wValue,
  716. const uint16_t wIndex,
  717. const void** const DescriptorAddress)
  718. {
  719. const uint8_t DescriptorType = (wValue >> 8);
  720. const uint8_t DescriptorIndex = (wValue & 0xFF);
  721. const void* Address = NULL;
  722. uint16_t Size = NO_DESCRIPTOR;
  723. switch (DescriptorType)
  724. {
  725. case DTYPE_Device:
  726. Address = &DeviceDescriptor;
  727. Size = sizeof(USB_Descriptor_Device_t);
  728. break;
  729. case DTYPE_Configuration:
  730. Address = &ConfigurationDescriptor;
  731. Size = sizeof(USB_Descriptor_Configuration_t);
  732. break;
  733. case DTYPE_String:
  734. switch (DescriptorIndex )
  735. {
  736. case 0x00:
  737. Address = &LanguageString;
  738. Size = pgm_read_byte(&LanguageString.Header.Size);
  739. break;
  740. case 0x01:
  741. Address = &ManufacturerString;
  742. Size = pgm_read_byte(&ManufacturerString.Header.Size);
  743. break;
  744. case 0x02:
  745. Address = &ProductString;
  746. Size = pgm_read_byte(&ProductString.Header.Size);
  747. break;
  748. case 0x03:
  749. Address = &SerialNumberString;
  750. Size = pgm_read_byte(&SerialNumberString.Header.Size);
  751. break;
  752. }
  753. break;
  754. case HID_DTYPE_HID:
  755. switch (wIndex) {
  756. #ifndef KEYBOARD_SHARED_EP
  757. case KEYBOARD_INTERFACE:
  758. Address = &ConfigurationDescriptor.Keyboard_HID;
  759. Size = sizeof(USB_HID_Descriptor_HID_t);
  760. break;
  761. #endif
  762. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  763. case MOUSE_INTERFACE:
  764. Address = &ConfigurationDescriptor.Mouse_HID;
  765. Size = sizeof(USB_HID_Descriptor_HID_t);
  766. break;
  767. #endif
  768. #ifdef SHARED_EP_ENABLE
  769. case SHARED_INTERFACE:
  770. Address = &ConfigurationDescriptor.Shared_HID;
  771. Size = sizeof(USB_HID_Descriptor_HID_t);
  772. break;
  773. #endif
  774. #ifdef RAW_ENABLE
  775. case RAW_INTERFACE:
  776. Address = &ConfigurationDescriptor.Raw_HID;
  777. Size = sizeof(USB_HID_Descriptor_HID_t);
  778. break;
  779. #endif
  780. #ifdef CONSOLE_ENABLE
  781. case CONSOLE_INTERFACE:
  782. Address = &ConfigurationDescriptor.Console_HID;
  783. Size = sizeof(USB_HID_Descriptor_HID_t);
  784. break;
  785. #endif
  786. }
  787. break;
  788. case HID_DTYPE_Report:
  789. switch (wIndex) {
  790. #ifndef KEYBOARD_SHARED_EP
  791. case KEYBOARD_INTERFACE:
  792. Address = &KeyboardReport;
  793. Size = sizeof(KeyboardReport);
  794. break;
  795. #endif
  796. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  797. case MOUSE_INTERFACE:
  798. Address = &MouseReport;
  799. Size = sizeof(MouseReport);
  800. break;
  801. #endif
  802. #ifdef SHARED_EP_ENABLE
  803. case SHARED_INTERFACE:
  804. Address = &SharedReport;
  805. Size = sizeof(SharedReport);
  806. break;
  807. #endif
  808. #ifdef RAW_ENABLE
  809. case RAW_INTERFACE:
  810. Address = &RawReport;
  811. Size = sizeof(RawReport);
  812. break;
  813. #endif
  814. #ifdef CONSOLE_ENABLE
  815. case CONSOLE_INTERFACE:
  816. Address = &ConsoleReport;
  817. Size = sizeof(ConsoleReport);
  818. break;
  819. #endif
  820. }
  821. break;
  822. }
  823. *DescriptorAddress = Address;
  824. return Size;
  825. }