Teensy 4.1 core updated for C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. /* USB Serial Example for Teensy USB Development Board
  2. * http://www.pjrc.com/teensy/usb_serial.html
  3. * Copyright (c) 2008 PJRC.COM, LLC
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. */
  23. #include "usb_common.h"
  24. #include "usb_private.h"
  25. /**************************************************************************
  26. *
  27. * Endpoint Buffer Configuration
  28. *
  29. **************************************************************************/
  30. static const uint8_t PROGMEM endpoint_config_table[] = {
  31. EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER,
  32. EP_TYPE_INTERRUPT_OUT, EP_SIZE(DEBUG_RX_SIZE) | DEBUG_RX_BUFFER,
  33. EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
  34. EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER,
  35. EP_TYPE_INTERRUPT_IN, EP_SIZE(JOYSTICK_SIZE) | JOYSTICK_BUFFER,
  36. EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYMEDIA_SIZE) | KEYMEDIA_BUFFER,
  37. };
  38. /**************************************************************************
  39. *
  40. * Descriptor Data
  41. *
  42. **************************************************************************/
  43. // Descriptors are the data that your computer reads when it auto-detects
  44. // this USB device (called "enumeration" in USB lingo). The most commonly
  45. // changed items are editable at the top of this file. Changing things
  46. // in here should only be done by those who've read chapter 9 of the USB
  47. // spec and relevant portions of any USB class specifications!
  48. static const uint8_t PROGMEM device_descriptor[] = {
  49. 18, // bLength
  50. 1, // bDescriptorType
  51. 0x00, 0x02, // bcdUSB
  52. 0, // bDeviceClass
  53. 0, // bDeviceSubClass
  54. 0, // bDeviceProtocol
  55. ENDPOINT0_SIZE, // bMaxPacketSize0
  56. LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
  57. LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
  58. #if defined(__AVR_ATmega32U4__)
  59. 0x71, 0x02,
  60. #elif defined(__AVR_AT90USB1286__)
  61. 0x72, 0x02,
  62. #else
  63. 0x05, 0x01, // bcdDevice
  64. #endif
  65. 0, // iManufacturer
  66. 1, // iProduct
  67. 0, // iSerialNumber
  68. 1 // bNumConfigurations
  69. };
  70. // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
  71. static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
  72. 0x05, 0x01, // Usage Page (Generic Desktop),
  73. 0x09, 0x06, // Usage (Keyboard),
  74. 0xA1, 0x01, // Collection (Application),
  75. 0x75, 0x01, // Report Size (1),
  76. 0x95, 0x08, // Report Count (8),
  77. 0x05, 0x07, // Usage Page (Key Codes),
  78. 0x19, 0xE0, // Usage Minimum (224),
  79. 0x29, 0xE7, // Usage Maximum (231),
  80. 0x15, 0x00, // Logical Minimum (0),
  81. 0x25, 0x01, // Logical Maximum (1),
  82. 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
  83. 0x95, 0x01, // Report Count (1),
  84. 0x75, 0x08, // Report Size (8),
  85. 0x81, 0x03, // Input (Constant), ;Reserved byte
  86. 0x95, 0x05, // Report Count (5),
  87. 0x75, 0x01, // Report Size (1),
  88. 0x05, 0x08, // Usage Page (LEDs),
  89. 0x19, 0x01, // Usage Minimum (1),
  90. 0x29, 0x05, // Usage Maximum (5),
  91. 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
  92. 0x95, 0x01, // Report Count (1),
  93. 0x75, 0x03, // Report Size (3),
  94. 0x91, 0x03, // Output (Constant), ;LED report padding
  95. 0x95, 0x06, // Report Count (6),
  96. 0x75, 0x08, // Report Size (8),
  97. 0x15, 0x00, // Logical Minimum (0),
  98. 0x25, 0x7F, // Logical Maximum(104),
  99. 0x05, 0x07, // Usage Page (Key Codes),
  100. 0x19, 0x00, // Usage Minimum (0),
  101. 0x29, 0x7F, // Usage Maximum (104),
  102. 0x81, 0x00, // Input (Data, Array), ;Normal keys
  103. 0xc0 // End Collection
  104. };
  105. static const uint8_t PROGMEM keymedia_hid_report_desc[] = {
  106. 0x05, 0x0C, // Usage Page (Consumer)
  107. 0x09, 0x01, // Usage (Consumer Controls)
  108. 0xA1, 0x01, // Collection (Application)
  109. 0x75, 0x0A, // Report Size (10)
  110. 0x95, 0x04, // Report Count (4)
  111. 0x19, 0x00, // Usage Minimum (0)
  112. 0x2A, 0x9C, 0x02, // Usage Maximum (0x29C)
  113. 0x15, 0x00, // Logical Minimum (0)
  114. 0x26, 0x9C, 0x02, // Logical Maximum (0x29C)
  115. 0x81, 0x00, // Input (Data, Array)
  116. 0x05, 0x01, // Usage Page (Generic Desktop)
  117. 0x75, 0x08, // Report Size (8)
  118. 0x95, 0x03, // Report Count (3)
  119. 0x19, 0x00, // Usage Minimum (0)
  120. 0x29, 0xB7, // Usage Maximum (0xB7)
  121. 0x15, 0x00, // Logical Minimum (0)
  122. 0x26, 0xB7, 0x00, // Logical Maximum (0xB7)
  123. 0x81, 0x00, // Input (Data, Array)
  124. 0xC0 // End Collection
  125. };
  126. // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
  127. static const uint8_t PROGMEM mouse_hid_report_desc[] = {
  128. 0x05, 0x01, // Usage Page (Generic Desktop)
  129. 0x09, 0x02, // Usage (Mouse)
  130. 0xA1, 0x01, // Collection (Application)
  131. 0x05, 0x09, // Usage Page (Button)
  132. 0x19, 0x01, // Usage Minimum (Button #1)
  133. 0x29, 0x08, // Usage Maximum (Button #8)
  134. 0x15, 0x00, // Logical Minimum (0)
  135. 0x25, 0x01, // Logical Maximum (1)
  136. 0x95, 0x08, // Report Count (8)
  137. 0x75, 0x01, // Report Size (1)
  138. 0x81, 0x02, // Input (Data, Variable, Absolute)
  139. 0x05, 0x01, // Usage Page (Generic Desktop)
  140. 0x09, 0x30, // Usage (X)
  141. 0x09, 0x31, // Usage (Y)
  142. 0x09, 0x38, // Usage (Wheel)
  143. 0x15, 0x81, // Logical Minimum (-127)
  144. 0x25, 0x7F, // Logical Maximum (127)
  145. 0x75, 0x08, // Report Size (8),
  146. 0x95, 0x03, // Report Count (3),
  147. 0x81, 0x06, // Input (Data, Variable, Relative)
  148. 0x05, 0x0C, // Usage Page (Consumer)
  149. 0x0A, 0x38, 0x02, // Usage (AC Pan)
  150. 0x15, 0x81, // Logical Minimum (-127)
  151. 0x25, 0x7F, // Logical Maximum (127)
  152. 0x75, 0x08, // Report Size (8),
  153. 0x95, 0x01, // Report Count (1),
  154. 0x81, 0x06, // Input (Data, Variable, Relative)
  155. 0xC0 // End Collection
  156. };
  157. #ifdef JOYSTICK_INTERFACE
  158. static const uint8_t PROGMEM joystick_hid_report_desc[] = {
  159. 0x05, 0x01, // Usage Page (Generic Desktop)
  160. 0x09, 0x04, // Usage (Joystick)
  161. 0xA1, 0x01, // Collection (Application)
  162. 0x15, 0x00, // Logical Minimum (0)
  163. 0x25, 0x01, // Logical Maximum (1)
  164. 0x75, 0x01, // Report Size (1)
  165. 0x95, 0x20, // Report Count (32)
  166. 0x05, 0x09, // Usage Page (Button)
  167. 0x19, 0x01, // Usage Minimum (Button #1)
  168. 0x29, 0x20, // Usage Maximum (Button #32)
  169. 0x81, 0x02, // Input (variable,absolute)
  170. 0x15, 0x00, // Logical Minimum (0)
  171. 0x25, 0x07, // Logical Maximum (7)
  172. 0x35, 0x00, // Physical Minimum (0)
  173. 0x46, 0x3B, 0x01, // Physical Maximum (315)
  174. 0x75, 0x04, // Report Size (4)
  175. 0x95, 0x01, // Report Count (1)
  176. 0x65, 0x14, // Unit (20)
  177. 0x05, 0x01, // Usage Page (Generic Desktop)
  178. 0x09, 0x39, // Usage (Hat switch)
  179. 0x81, 0x42, // Input (variable,absolute,null_state)
  180. 0x05, 0x01, // Usage Page (Generic Desktop)
  181. 0x09, 0x01, // Usage (Pointer)
  182. 0xA1, 0x00, // Collection ()
  183. 0x15, 0x00, // Logical Minimum (0)
  184. 0x26, 0xFF, 0x03, // Logical Maximum (1023)
  185. 0x75, 0x0A, // Report Size (10)
  186. 0x95, 0x04, // Report Count (4)
  187. 0x09, 0x30, // Usage (X)
  188. 0x09, 0x31, // Usage (Y)
  189. 0x09, 0x32, // Usage (Z)
  190. 0x09, 0x35, // Usage (Rz)
  191. 0x81, 0x02, // Input (variable,absolute)
  192. 0xC0, // End Collection
  193. 0x15, 0x00, // Logical Minimum (0)
  194. 0x26, 0xFF, 0x03, // Logical Maximum (1023)
  195. 0x75, 0x0A, // Report Size (10)
  196. 0x95, 0x02, // Report Count (2)
  197. 0x09, 0x36, // Usage (Slider)
  198. 0x09, 0x36, // Usage (Slider)
  199. 0x81, 0x02, // Input (variable,absolute)
  200. 0xC0 // End Collection
  201. };
  202. #endif
  203. static const uint8_t PROGMEM debug_hid_report_desc[] = {
  204. 0x06, 0xC9, 0xFF, // Usage Page 0xFFC9 (vendor defined)
  205. 0x09, 0x04, // Usage 0x04
  206. 0xA1, 0x5C, // Collection 0x5C
  207. 0x75, 0x08, // report size = 8 bits (global)
  208. 0x15, 0x00, // logical minimum = 0 (global)
  209. 0x26, 0xFF, 0x00, // logical maximum = 255 (global)
  210. 0x95, DEBUG_TX_SIZE, // report count (global)
  211. 0x09, 0x75, // usage (local)
  212. 0x81, 0x02, // Input
  213. 0x95, DEBUG_RX_SIZE, // report count (global)
  214. 0x09, 0x76, // usage (local)
  215. 0x91, 0x02, // Output
  216. 0x95, 0x04, // report count (global)
  217. 0x09, 0x76, // usage (local)
  218. 0xB1, 0x02, // Feature
  219. 0xC0 // end collection
  220. };
  221. #define KEYBOARD_HID_DESC_OFFSET ( 9 + 9 )
  222. #define MOUSE_HID_DESC_OFFSET ( 9 + 9+9+7 + 9 )
  223. #define DEBUG_HID_DESC_OFFSET ( 9 + 9+9+7 + 9+9+7 + 9 )
  224. #define JOYSTICK_HID_DESC_OFFSET ( 9 + 9+9+7 + 9+9+7 + 9+9+7+7 + 9 )
  225. #define KEYMEDIA_HID_DESC_OFFSET ( 9 + 9+9+7 + 9+9+7 + 9+9+7+7 + 9+9+7 + 9 )
  226. #define CONFIG1_DESC_SIZE ( 9 + 9+9+7 + 9+9+7 + 9+9+7+7 + 9+9+7 + 9+9+7 )
  227. static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
  228. // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
  229. 9, // bLength;
  230. 2, // bDescriptorType;
  231. LSB(CONFIG1_DESC_SIZE), // wTotalLength
  232. MSB(CONFIG1_DESC_SIZE),
  233. NUM_INTERFACE, // bNumInterfaces
  234. 1, // bConfigurationValue
  235. 0, // iConfiguration
  236. 0xC0, // bmAttributes
  237. 50, // bMaxPower
  238. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  239. 9, // bLength
  240. 4, // bDescriptorType
  241. KEYBOARD_INTERFACE, // bInterfaceNumber
  242. 0, // bAlternateSetting
  243. 1, // bNumEndpoints
  244. 0x03, // bInterfaceClass (0x03 = HID)
  245. 0x01, // bInterfaceSubClass (0x01 = Boot)
  246. 0x01, // bInterfaceProtocol (0x01 = Keyboard)
  247. 0, // iInterface
  248. // HID interface descriptor, HID 1.11 spec, section 6.2.1
  249. 9, // bLength
  250. 0x21, // bDescriptorType
  251. 0x11, 0x01, // bcdHID
  252. 0, // bCountryCode
  253. 1, // bNumDescriptors
  254. 0x22, // bDescriptorType
  255. sizeof(keyboard_hid_report_desc), // wDescriptorLength
  256. 0,
  257. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  258. 7, // bLength
  259. 5, // bDescriptorType
  260. KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress
  261. 0x03, // bmAttributes (0x03=intr)
  262. KEYBOARD_SIZE, 0, // wMaxPacketSize
  263. KEYBOARD_INTERVAL, // bInterval
  264. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  265. 9, // bLength
  266. 4, // bDescriptorType
  267. MOUSE_INTERFACE, // bInterfaceNumber
  268. 0, // bAlternateSetting
  269. 1, // bNumEndpoints
  270. 0x03, // bInterfaceClass (0x03 = HID)
  271. 0x01, // bInterfaceSubClass (0x01 = Boot)
  272. 0x02, // bInterfaceProtocol (0x02 = Mouse)
  273. 0, // iInterface
  274. // HID interface descriptor, HID 1.11 spec, section 6.2.1
  275. 9, // bLength
  276. 0x21, // bDescriptorType
  277. 0x11, 0x01, // bcdHID
  278. 0, // bCountryCode
  279. 1, // bNumDescriptors
  280. 0x22, // bDescriptorType
  281. sizeof(mouse_hid_report_desc), // wDescriptorLength
  282. 0,
  283. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  284. 7, // bLength
  285. 5, // bDescriptorType
  286. MOUSE_ENDPOINT | 0x80, // bEndpointAddress
  287. 0x03, // bmAttributes (0x03=intr)
  288. MOUSE_SIZE, 0, // wMaxPacketSize
  289. MOUSE_INTERVAL, // bInterval
  290. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  291. 9, // bLength
  292. 4, // bDescriptorType
  293. DEBUG_INTERFACE, // bInterfaceNumber
  294. 0, // bAlternateSetting
  295. 2, // bNumEndpoints
  296. 0x03, // bInterfaceClass (0x03 = HID)
  297. 0x00, // bInterfaceSubClass
  298. 0x00, // bInterfaceProtocol
  299. 0, // iInterface
  300. // HID interface descriptor, HID 1.11 spec, section 6.2.1
  301. 9, // bLength
  302. 0x21, // bDescriptorType
  303. 0x11, 0x01, // bcdHID
  304. 0, // bCountryCode
  305. 1, // bNumDescriptors
  306. 0x22, // bDescriptorType
  307. sizeof(debug_hid_report_desc), // wDescriptorLength
  308. 0,
  309. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  310. 7, // bLength
  311. 5, // bDescriptorType
  312. DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress
  313. 0x03, // bmAttributes (0x03=intr)
  314. DEBUG_TX_SIZE, 0, // wMaxPacketSize
  315. DEBUG_TX_INTERVAL, // bInterval
  316. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  317. 7, // bLength
  318. 5, // bDescriptorType
  319. DEBUG_RX_ENDPOINT, // bEndpointAddress
  320. 0x03, // bmAttributes (0x03=intr)
  321. DEBUG_RX_SIZE, 0, // wMaxPacketSize
  322. DEBUG_RX_INTERVAL, // bInterval
  323. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  324. 9, // bLength
  325. 4, // bDescriptorType
  326. JOYSTICK_INTERFACE, // bInterfaceNumber
  327. 0, // bAlternateSetting
  328. 1, // bNumEndpoints
  329. 0x03, // bInterfaceClass (0x03 = HID)
  330. 0x00, // bInterfaceSubClass
  331. 0x00, // bInterfaceProtocol
  332. 0, // iInterface
  333. // HID interface descriptor, HID 1.11 spec, section 6.2.1
  334. 9, // bLength
  335. 0x21, // bDescriptorType
  336. 0x11, 0x01, // bcdHID
  337. 0, // bCountryCode
  338. 1, // bNumDescriptors
  339. 0x22, // bDescriptorType
  340. sizeof(joystick_hid_report_desc), // wDescriptorLength
  341. 0,
  342. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  343. 7, // bLength
  344. 5, // bDescriptorType
  345. JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress
  346. 0x03, // bmAttributes (0x03=intr)
  347. 12, 0, // wMaxPacketSize
  348. JOYSTICK_INTERVAL, // bInterval
  349. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  350. 9, // bLength
  351. 4, // bDescriptorType
  352. KEYMEDIA_INTERFACE, // bInterfaceNumber
  353. 0, // bAlternateSetting
  354. 1, // bNumEndpoints
  355. 0x03, // bInterfaceClass (0x03 = HID)
  356. 0x00, // bInterfaceSubClass
  357. 0x00, // bInterfaceProtocol
  358. 0, // iInterface
  359. // HID interface descriptor, HID 1.11 spec, section 6.2.1
  360. 9, // bLength
  361. 0x21, // bDescriptorType
  362. 0x11, 0x01, // bcdHID
  363. 0, // bCountryCode
  364. 1, // bNumDescriptors
  365. 0x22, // bDescriptorType
  366. LSB(sizeof(keymedia_hid_report_desc)), // wDescriptorLength
  367. MSB(sizeof(keymedia_hid_report_desc)),
  368. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  369. 7, // bLength
  370. 5, // bDescriptorType
  371. KEYMEDIA_ENDPOINT | 0x80, // bEndpointAddress
  372. 0x03, // bmAttributes (0x03=intr)
  373. KEYMEDIA_SIZE, 0, // wMaxPacketSize
  374. KEYMEDIA_INTERVAL, // bInterval
  375. };
  376. // If you're desperate for a little extra code memory, these strings
  377. // can be completely removed if iManufacturer, iProduct, iSerialNumber
  378. // in the device desciptor are changed to zeros.
  379. struct usb_string_descriptor_struct {
  380. uint8_t bLength;
  381. uint8_t bDescriptorType;
  382. int16_t wString[];
  383. };
  384. static const struct usb_string_descriptor_struct PROGMEM string0 = {
  385. 4,
  386. 3,
  387. {0x0409}
  388. };
  389. static const struct usb_string_descriptor_struct PROGMEM string1 = {
  390. sizeof(STR_PRODUCT),
  391. 3,
  392. STR_PRODUCT
  393. };
  394. // This table defines which descriptor data is sent for each specific
  395. // request from the host (in wValue and wIndex).
  396. static const struct descriptor_list_struct {
  397. uint16_t wValue;
  398. uint16_t wIndex;
  399. const uint8_t *addr;
  400. uint8_t length;
  401. } PROGMEM descriptor_list[] = {
  402. {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
  403. {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
  404. {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
  405. {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
  406. {0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
  407. {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
  408. {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
  409. {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
  410. {0x2200, JOYSTICK_INTERFACE, joystick_hid_report_desc, sizeof(joystick_hid_report_desc)},
  411. {0x2100, JOYSTICK_INTERFACE, config1_descriptor+JOYSTICK_HID_DESC_OFFSET, 9},
  412. {0x2200, KEYMEDIA_INTERFACE, keymedia_hid_report_desc, sizeof(keymedia_hid_report_desc)},
  413. {0x2100, KEYMEDIA_INTERFACE, config1_descriptor+KEYMEDIA_HID_DESC_OFFSET, 9},
  414. {0x0300, 0x0000, (const uint8_t *)&string0, 4},
  415. {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_PRODUCT)},
  416. };
  417. #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
  418. /**************************************************************************
  419. *
  420. * Variables - these are the only non-stack RAM usage
  421. *
  422. **************************************************************************/
  423. // zero when we are not configured, non-zero when enumerated
  424. volatile uint8_t usb_configuration USBSTATE;
  425. volatile uint8_t usb_suspended USBSTATE;
  426. // the time remaining before we transmit any partially full
  427. // packet, or send a zero length packet.
  428. volatile uint8_t debug_flush_timer USBSTATE;
  429. // byte0: which modifier keys are currently pressed
  430. // 1=left ctrl, 2=left shift, 4=left alt, 8=left gui
  431. // 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
  432. // byte1: media keys (TODO: document these)
  433. // bytes2-7: which keys are currently pressed, up to 6 keys may be down at once
  434. uint8_t keyboard_report_data[8] USBSTATE;
  435. // protocol setting from the host. We use exactly the same report
  436. // either way, so this variable only stores the setting since we
  437. // are required to be able to report which setting is in use.
  438. static uint8_t keyboard_protocol USBSTATE;
  439. // the idle configuration, how often we send the report to the
  440. // host (ms * 4) even when it hasn't changed
  441. static uint8_t keyboard_idle_config USBSTATE;
  442. // count until idle timeout
  443. uint8_t keyboard_idle_count USBSTATE;
  444. // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
  445. volatile uint8_t keyboard_leds USBSTATE;
  446. // which buttons are currently pressed
  447. uint8_t mouse_buttons USBSTATE;
  448. // protocol setting from the host. We use exactly the same report
  449. // either way, so this variable only stores the setting since we
  450. // are required to be able to report which setting is in use.
  451. static uint8_t mouse_protocol USBSTATE;
  452. // joystick data
  453. uint8_t joystick_report_data[12] USBSTATE;
  454. // keyboard media keys data
  455. uint8_t keymedia_report_data[8] USBSTATE;
  456. uint16_t keymedia_consumer_keys[4] USBSTATE;
  457. uint8_t keymedia_system_keys[3] USBSTATE;
  458. /**************************************************************************
  459. *
  460. * Public Functions - these are the API intended for the user
  461. *
  462. **************************************************************************/
  463. // initialize USB serial
  464. void usb_init(void)
  465. {
  466. uint8_t u;
  467. u = USBCON;
  468. if ((u & (1<<USBE)) && !(u & (1<<FRZCLK))) return;
  469. HW_CONFIG();
  470. USB_FREEZE(); // enable USB
  471. PLL_CONFIG(); // config PLL
  472. while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
  473. USB_CONFIG(); // start USB clock
  474. UDCON = 0; // enable attach resistor
  475. usb_configuration = 0;
  476. usb_suspended = 0;
  477. debug_flush_timer = 0;
  478. keyboard_report_data[0] = 0;
  479. keyboard_report_data[1] = 0;
  480. keyboard_report_data[2] = 0;
  481. keyboard_report_data[3] = 0;
  482. keyboard_report_data[4] = 0;
  483. keyboard_report_data[5] = 0;
  484. keyboard_report_data[6] = 0;
  485. keyboard_report_data[7] = 0;
  486. keyboard_protocol = 1;
  487. keyboard_idle_config = 125;
  488. keyboard_idle_count = 0;
  489. keyboard_leds = 0;
  490. mouse_buttons = 0;
  491. mouse_protocol = 1;
  492. joystick_report_data[0] = 0;
  493. joystick_report_data[1] = 0;
  494. joystick_report_data[2] = 0;
  495. joystick_report_data[3] = 0;
  496. joystick_report_data[4] = 0x0F;
  497. joystick_report_data[5] = 0x20;
  498. joystick_report_data[6] = 0x80;
  499. joystick_report_data[7] = 0x00;
  500. joystick_report_data[8] = 0x02;
  501. joystick_report_data[9] = 0x08;
  502. joystick_report_data[10] = 0x20;
  503. joystick_report_data[11] = 0x80;
  504. keymedia_report_data[0] = 0;
  505. keymedia_report_data[1] = 0;
  506. keymedia_report_data[2] = 0;
  507. keymedia_report_data[3] = 0;
  508. keymedia_report_data[4] = 0;
  509. keymedia_report_data[5] = 0;
  510. keymedia_report_data[6] = 0;
  511. keymedia_report_data[7] = 0;
  512. keymedia_consumer_keys[0] = 0;
  513. keymedia_consumer_keys[1] = 0;
  514. keymedia_consumer_keys[2] = 0;
  515. keymedia_consumer_keys[3] = 0;
  516. keymedia_system_keys[0] = 0;
  517. keymedia_system_keys[1] = 0;
  518. keymedia_system_keys[2] = 0;
  519. UDINT = 0;
  520. UDIEN = (1<<EORSTE)|(1<<SOFE);
  521. //sei(); // init() in wiring.c does this
  522. }
  523. void usb_shutdown(void)
  524. {
  525. UDIEN = 0; // disable interrupts
  526. UDCON = 1; // disconnect attach resistor
  527. USBCON = 0; // shut off USB periperal
  528. PLLCSR = 0; // shut off PLL
  529. usb_configuration = 0;
  530. usb_suspended = 1;
  531. }
  532. // Public API functions moved to usb_api.cpp
  533. /**************************************************************************
  534. *
  535. * Private Functions - not intended for general user consumption....
  536. *
  537. **************************************************************************/
  538. // USB Device Interrupt - handle all device-level events
  539. // the transmit buffer flushing is triggered by the start of frame
  540. //
  541. ISR(USB_GEN_vect)
  542. {
  543. uint8_t intbits, t, i;
  544. static uint8_t div4=0;
  545. intbits = UDINT;
  546. UDINT = 0;
  547. if (intbits & (1<<EORSTI)) {
  548. UENUM = 0;
  549. UECONX = 1;
  550. UECFG0X = EP_TYPE_CONTROL;
  551. UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
  552. UEIENX = (1<<RXSTPE);
  553. usb_configuration = 0;
  554. }
  555. if ((intbits & (1<<SOFI)) && usb_configuration) {
  556. t = debug_flush_timer;
  557. if (t) {
  558. debug_flush_timer = -- t;
  559. if (!t) {
  560. UENUM = DEBUG_TX_ENDPOINT;
  561. while ((UEINTX & (1<<RWAL))) {
  562. UEDATX = 0;
  563. }
  564. UEINTX = 0x3A;
  565. }
  566. }
  567. if (keyboard_idle_config && (++div4 & 3) == 0) {
  568. UENUM = KEYBOARD_ENDPOINT;
  569. if (UEINTX & (1<<RWAL)) {
  570. keyboard_idle_count++;
  571. if (keyboard_idle_count == keyboard_idle_config) {
  572. keyboard_idle_count = 0;
  573. //len = keyboard_protocol ? sizeof(keyboard_keys) : 8;
  574. for (i=0; i < 8; i++) {
  575. UEDATX = keyboard_report_data[i];
  576. }
  577. UEINTX = 0x3A;
  578. }
  579. }
  580. }
  581. }
  582. if (intbits & (1<<SUSPI)) {
  583. // USB Suspend (inactivity for 3ms)
  584. UDIEN = (1<<WAKEUPE);
  585. usb_configuration = 0;
  586. usb_suspended = 1;
  587. #if (F_CPU >= 8000000L)
  588. // WAKEUPI does not work with USB clock freeze
  589. // when CPU is running less than 8 MHz.
  590. // Is this a hardware bug?
  591. USB_FREEZE(); // shut off USB
  592. PLLCSR = 0; // shut off PLL
  593. #endif
  594. // to properly meet the USB spec, current must
  595. // reduce to less than 2.5 mA, which means using
  596. // powerdown mode, but that breaks the Arduino
  597. // user's paradigm....
  598. }
  599. if (usb_suspended && (intbits & (1<<WAKEUPI))) {
  600. // USB Resume (pretty much any activity)
  601. #if (F_CPU >= 8000000L)
  602. PLL_CONFIG();
  603. while (!(PLLCSR & (1<<PLOCK))) ;
  604. USB_CONFIG();
  605. #endif
  606. UDIEN = (1<<EORSTE)|(1<<SOFE)|(1<<SUSPE);
  607. usb_suspended = 0;
  608. return;
  609. }
  610. }
  611. // Misc functions to wait for ready and send/receive packets
  612. static inline void usb_wait_in_ready(void)
  613. {
  614. while (!(UEINTX & (1<<TXINI))) ;
  615. }
  616. static inline void usb_send_in(void)
  617. {
  618. UEINTX = ~(1<<TXINI);
  619. }
  620. static inline void usb_wait_receive_out(void)
  621. {
  622. while (!(UEINTX & (1<<RXOUTI))) ;
  623. }
  624. static inline void usb_ack_out(void)
  625. {
  626. UEINTX = ~(1<<RXOUTI);
  627. }
  628. // USB Endpoint Interrupt - endpoint 0 is handled here. The
  629. // other endpoints are manipulated by the user-callable
  630. // functions, and the start-of-frame interrupt.
  631. //
  632. ISR(USB_COM_vect)
  633. {
  634. uint8_t intbits;
  635. const uint8_t *list;
  636. const uint8_t *cfg;
  637. uint8_t i, n, len;
  638. uint8_t bmRequestType;
  639. uint8_t bRequest;
  640. uint16_t wValue;
  641. uint16_t wIndex;
  642. uint16_t wLength;
  643. uint16_t desc_val;
  644. const uint8_t *desc_addr;
  645. uint8_t desc_length;
  646. UENUM = 0;
  647. intbits = UEINTX;
  648. if (intbits & (1<<RXSTPI)) {
  649. bmRequestType = UEDATX;
  650. bRequest = UEDATX;
  651. read_word_lsbfirst(wValue, UEDATX);
  652. read_word_lsbfirst(wIndex, UEDATX);
  653. read_word_lsbfirst(wLength, UEDATX);
  654. UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
  655. if (bRequest == GET_DESCRIPTOR) {
  656. list = (const uint8_t *)descriptor_list;
  657. for (i=0; ; i++) {
  658. if (i >= NUM_DESC_LIST) {
  659. UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
  660. return;
  661. }
  662. pgm_read_word_postinc(desc_val, list);
  663. if (desc_val != wValue) {
  664. list += sizeof(struct descriptor_list_struct)-2;
  665. continue;
  666. }
  667. pgm_read_word_postinc(desc_val, list);
  668. if (desc_val != wIndex) {
  669. list += sizeof(struct descriptor_list_struct)-4;
  670. continue;
  671. }
  672. pgm_read_word_postinc(desc_addr, list);
  673. desc_length = pgm_read_byte(list);
  674. break;
  675. }
  676. len = (wLength < 256) ? wLength : 255;
  677. if (len > desc_length) len = desc_length;
  678. list = desc_addr;
  679. do {
  680. // wait for host ready for IN packet
  681. do {
  682. i = UEINTX;
  683. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  684. if (i & (1<<RXOUTI)) return; // abort
  685. // send IN packet
  686. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  687. for (i = n; i; i--) {
  688. pgm_read_byte_postinc(UEDATX, list);
  689. }
  690. len -= n;
  691. usb_send_in();
  692. } while (len || n == ENDPOINT0_SIZE);
  693. return;
  694. }
  695. if (bRequest == SET_ADDRESS) {
  696. usb_send_in();
  697. usb_wait_in_ready();
  698. UDADDR = wValue | (1<<ADDEN);
  699. return;
  700. }
  701. if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
  702. usb_configuration = wValue;
  703. debug_flush_timer = 0;
  704. usb_send_in();
  705. cfg = endpoint_config_table;
  706. for (i=1; i<7; i++) {
  707. UENUM = i;
  708. UECONX = 1;
  709. pgm_read_byte_postinc(UECFG0X, cfg);
  710. pgm_read_byte_postinc(UECFG1X, cfg);
  711. }
  712. UERST = 0x1E;
  713. UERST = 0;
  714. return;
  715. }
  716. if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
  717. usb_wait_in_ready();
  718. UEDATX = usb_configuration;
  719. usb_send_in();
  720. return;
  721. }
  722. if (bRequest == GET_STATUS) {
  723. usb_wait_in_ready();
  724. i = 0;
  725. if (bmRequestType == 0x82) {
  726. UENUM = wIndex;
  727. if (UECONX & (1<<STALLRQ)) i = 1;
  728. UENUM = 0;
  729. }
  730. UEDATX = i;
  731. UEDATX = 0;
  732. usb_send_in();
  733. return;
  734. }
  735. if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
  736. && bmRequestType == 0x02 && wValue == 0) {
  737. i = wIndex & 0x7F;
  738. if (i >= 1 && i <= NUM_ENDPOINTS) {
  739. usb_send_in();
  740. UENUM = i;
  741. if (bRequest == SET_FEATURE) {
  742. UECONX = (1<<STALLRQ)|(1<<EPEN);
  743. } else {
  744. UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
  745. UERST = (1 << i);
  746. UERST = 0;
  747. }
  748. return;
  749. }
  750. }
  751. if (wIndex == KEYBOARD_INTERFACE) {
  752. if (bmRequestType == 0xA1) {
  753. if (bRequest == HID_GET_REPORT) {
  754. usb_wait_in_ready();
  755. //len = keyboard_protocol ? sizeof(keyboard_keys) : 8;
  756. for (i=0; i < 8; i++) {
  757. UEDATX = keyboard_report_data[i];
  758. }
  759. usb_send_in();
  760. return;
  761. }
  762. if (bRequest == HID_GET_IDLE) {
  763. usb_wait_in_ready();
  764. UEDATX = keyboard_idle_config;
  765. usb_send_in();
  766. return;
  767. }
  768. if (bRequest == HID_GET_PROTOCOL) {
  769. usb_wait_in_ready();
  770. UEDATX = keyboard_protocol;
  771. usb_send_in();
  772. return;
  773. }
  774. }
  775. if (bmRequestType == 0x21) {
  776. if (bRequest == HID_SET_REPORT) {
  777. usb_wait_receive_out();
  778. keyboard_leds = UEDATX;
  779. usb_ack_out();
  780. usb_send_in();
  781. return;
  782. }
  783. if (bRequest == HID_SET_IDLE) {
  784. keyboard_idle_config = (wValue >> 8);
  785. keyboard_idle_count = 0;
  786. //usb_wait_in_ready();
  787. usb_send_in();
  788. return;
  789. }
  790. if (bRequest == HID_SET_PROTOCOL) {
  791. keyboard_protocol = wValue;
  792. //usb_wait_in_ready();
  793. usb_send_in();
  794. return;
  795. }
  796. }
  797. }
  798. if (wIndex == MOUSE_INTERFACE) {
  799. if (bmRequestType == 0xA1) {
  800. if (bRequest == HID_GET_REPORT) {
  801. usb_wait_in_ready();
  802. UEDATX = mouse_buttons;
  803. UEDATX = 0;
  804. UEDATX = 0;
  805. UEDATX = 0;
  806. UEDATX = 0;
  807. usb_send_in();
  808. return;
  809. }
  810. if (bRequest == HID_GET_PROTOCOL) {
  811. usb_wait_in_ready();
  812. UEDATX = mouse_protocol;
  813. usb_send_in();
  814. return;
  815. }
  816. }
  817. if (bmRequestType == 0x21) {
  818. if (bRequest == HID_SET_PROTOCOL) {
  819. mouse_protocol = wValue;
  820. usb_send_in();
  821. return;
  822. }
  823. }
  824. }
  825. if (wIndex == JOYSTICK_INTERFACE) {
  826. if (bmRequestType == 0xA1) {
  827. if (bRequest == HID_GET_REPORT) {
  828. usb_wait_in_ready();
  829. for (i=0; i<12; i++) {
  830. UEDATX = joystick_report_data[i];
  831. }
  832. usb_send_in();
  833. return;
  834. }
  835. }
  836. }
  837. if (wIndex == KEYMEDIA_INTERFACE) {
  838. if (bmRequestType == 0xA1) {
  839. if (bRequest == HID_GET_REPORT) {
  840. usb_wait_in_ready();
  841. for (i=0; i<8; i++) {
  842. UEDATX = keymedia_report_data[i];
  843. }
  844. usb_send_in();
  845. return;
  846. }
  847. }
  848. }
  849. if (wIndex == DEBUG_INTERFACE) {
  850. if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
  851. len = wLength;
  852. do {
  853. // wait for host ready for IN packet
  854. do {
  855. i = UEINTX;
  856. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  857. if (i & (1<<RXOUTI)) return; // abort
  858. // send IN packet
  859. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  860. for (i = n; i; i--) {
  861. UEDATX = 0;
  862. }
  863. len -= n;
  864. usb_send_in();
  865. } while (len || n == ENDPOINT0_SIZE);
  866. return;
  867. }
  868. if (bRequest == HID_SET_REPORT && bmRequestType == 0x21) {
  869. if (wValue == 0x0300 && wLength == 0x0004) {
  870. uint8_t b1, b2, b3, b4;
  871. usb_wait_receive_out();
  872. b1 = UEDATX;
  873. b2 = UEDATX;
  874. b3 = UEDATX;
  875. b4 = UEDATX;
  876. usb_ack_out();
  877. usb_send_in();
  878. if (b1 == 0xA9 && b2 == 0x45 && b3 == 0xC2 && b4 == 0x6B)
  879. _reboot_Teensyduino_();
  880. if (b1 == 0x8B && b2 == 0xC5 && b3 == 0x1D && b4 == 0x70)
  881. _restart_Teensyduino_();
  882. }
  883. }
  884. }
  885. if (bRequest == 0xC9 && bmRequestType == 0x40) {
  886. usb_send_in();
  887. usb_wait_in_ready();
  888. _restart_Teensyduino_();
  889. }
  890. }
  891. UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
  892. }