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 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. /* USB Serial for Teensy USB Development Board
  2. * http://www.pjrc.com/teensy/
  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(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
  32. EP_TYPE_INTERRUPT_IN, EP_SIZE(CDC_ACM_SIZE) | CDC_ACM_BUFFER,
  33. EP_TYPE_BULK_OUT, EP_SIZE(CDC_RX_SIZE) | CDC_RX_BUFFER,
  34. EP_TYPE_BULK_IN, EP_SIZE(CDC_TX_SIZE) | CDC_TX_BUFFER,
  35. EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER,
  36. EP_TYPE_INTERRUPT_IN, EP_SIZE(JOYSTICK_SIZE) | JOYSTICK_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. 0xEF, // bDeviceClass
  53. 0x02, // bDeviceSubClass
  54. 0x01, // 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. 0x02, 0x01, // bcdDevice
  64. #endif
  65. 1, // iManufacturer
  66. 2, // iProduct
  67. 3, // 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, 0x08, // Report Count (8),
  84. 0x75, 0x01, // Report Size (1),
  85. 0x15, 0x00, // Logical Minimum (0),
  86. 0x25, 0x01, // Logical Maximum (1),
  87. 0x05, 0x0C, // Usage Page (Consumer),
  88. 0x09, 0xE9, // Usage (Volume Increment),
  89. 0x09, 0xEA, // Usage (Volume Decrement),
  90. 0x09, 0xE2, // Usage (Mute),
  91. 0x09, 0xCD, // Usage (Play/Pause),
  92. 0x09, 0xB5, // Usage (Scan Next Track),
  93. 0x09, 0xB6, // Usage (Scan Previous Track),
  94. 0x09, 0xB7, // Usage (Stop),
  95. 0x09, 0xB8, // Usage (Eject),
  96. 0x81, 0x02, // Input (Data, Variable, Absolute), ;Media keys
  97. 0x95, 0x05, // Report Count (5),
  98. 0x75, 0x01, // Report Size (1),
  99. 0x05, 0x08, // Usage Page (LEDs),
  100. 0x19, 0x01, // Usage Minimum (1),
  101. 0x29, 0x05, // Usage Maximum (5),
  102. 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
  103. 0x95, 0x01, // Report Count (1),
  104. 0x75, 0x03, // Report Size (3),
  105. 0x91, 0x03, // Output (Constant), ;LED report padding
  106. 0x95, 0x06, // Report Count (6),
  107. 0x75, 0x08, // Report Size (8),
  108. 0x15, 0x00, // Logical Minimum (0),
  109. 0x25, 0x7F, // Logical Maximum(104),
  110. 0x05, 0x07, // Usage Page (Key Codes),
  111. 0x19, 0x00, // Usage Minimum (0),
  112. 0x29, 0x7F, // Usage Maximum (104),
  113. 0x81, 0x00, // Input (Data, Array), ;Normal keys
  114. 0xc0 // End Collection
  115. };
  116. // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
  117. static const uint8_t PROGMEM mouse_hid_report_desc[] = {
  118. 0x05, 0x01, // Usage Page (Generic Desktop)
  119. 0x09, 0x02, // Usage (Mouse)
  120. 0xA1, 0x01, // Collection (Application)
  121. 0x05, 0x09, // Usage Page (Button)
  122. 0x19, 0x01, // Usage Minimum (Button #1)
  123. 0x29, 0x08, // Usage Maximum (Button #8)
  124. 0x15, 0x00, // Logical Minimum (0)
  125. 0x25, 0x01, // Logical Maximum (1)
  126. 0x95, 0x08, // Report Count (8)
  127. 0x75, 0x01, // Report Size (1)
  128. 0x81, 0x02, // Input (Data, Variable, Absolute)
  129. 0x05, 0x01, // Usage Page (Generic Desktop)
  130. 0x09, 0x30, // Usage (X)
  131. 0x09, 0x31, // Usage (Y)
  132. 0x09, 0x38, // Usage (Wheel)
  133. 0x15, 0x81, // Logical Minimum (-127)
  134. 0x25, 0x7F, // Logical Maximum (127)
  135. 0x75, 0x08, // Report Size (8),
  136. 0x95, 0x03, // Report Count (3),
  137. 0x81, 0x06, // Input (Data, Variable, Relative)
  138. 0x05, 0x0C, // Usage Page (Consumer)
  139. 0x0A, 0x38, 0x02, // Usage (AC Pan)
  140. 0x15, 0x81, // Logical Minimum (-127)
  141. 0x25, 0x7F, // Logical Maximum (127)
  142. 0x75, 0x08, // Report Size (8),
  143. 0x95, 0x01, // Report Count (1),
  144. 0x81, 0x06, // Input (Data, Variable, Relative)
  145. 0xC0 // End Collection
  146. };
  147. static const uint8_t PROGMEM joystick_hid_report_desc[] = {
  148. 0x05, 0x01, // Usage Page (Generic Desktop)
  149. 0x09, 0x04, // Usage (Joystick)
  150. 0xA1, 0x01, // Collection (Application)
  151. 0x15, 0x00, // Logical Minimum (0)
  152. 0x25, 0x01, // Logical Maximum (1)
  153. 0x75, 0x01, // Report Size (1)
  154. 0x95, 0x20, // Report Count (32)
  155. 0x05, 0x09, // Usage Page (Button)
  156. 0x19, 0x01, // Usage Minimum (Button #1)
  157. 0x29, 0x20, // Usage Maximum (Button #32)
  158. 0x81, 0x02, // Input (variable,absolute)
  159. 0x15, 0x00, // Logical Minimum (0)
  160. 0x25, 0x07, // Logical Maximum (7)
  161. 0x35, 0x00, // Physical Minimum (0)
  162. 0x46, 0x3B, 0x01, // Physical Maximum (315)
  163. 0x75, 0x04, // Report Size (4)
  164. 0x95, 0x01, // Report Count (1)
  165. 0x65, 0x14, // Unit (20)
  166. 0x05, 0x01, // Usage Page (Generic Desktop)
  167. 0x09, 0x39, // Usage (Hat switch)
  168. 0x81, 0x42, // Input (variable,absolute,null_state)
  169. 0x05, 0x01, // Usage Page (Generic Desktop)
  170. 0x09, 0x01, // Usage (Pointer)
  171. 0xA1, 0x00, // Collection ()
  172. 0x15, 0x00, // Logical Minimum (0)
  173. 0x26, 0xFF, 0x03, // Logical Maximum (1023)
  174. 0x75, 0x0A, // Report Size (10)
  175. 0x95, 0x04, // Report Count (4)
  176. 0x09, 0x30, // Usage (X)
  177. 0x09, 0x31, // Usage (Y)
  178. 0x09, 0x32, // Usage (Z)
  179. 0x09, 0x35, // Usage (Rz)
  180. 0x81, 0x02, // Input (variable,absolute)
  181. 0xC0, // End Collection
  182. 0x15, 0x00, // Logical Minimum (0)
  183. 0x26, 0xFF, 0x03, // Logical Maximum (1023)
  184. 0x75, 0x0A, // Report Size (10)
  185. 0x95, 0x02, // Report Count (2)
  186. 0x09, 0x36, // Usage (Slider)
  187. 0x09, 0x36, // Usage (Slider)
  188. 0x81, 0x02, // Input (variable,absolute)
  189. 0xC0 // End Collection
  190. };
  191. #define KEYBOARD_HID_DESC_OFFSET ( 9+8 + 9+5+5+4+5+7+9+7+7 + 9 )
  192. #define MOUSE_HID_DESC_OFFSET ( 9+8 + 9+5+5+4+5+7+9+7+7 + 9+9+7 + 9 )
  193. #define JOYSTICK_HID_DESC_OFFSET ( 9+8 + 9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9 )
  194. #define CONFIG1_DESC_SIZE ( 9+8 + 9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9+9+7 )
  195. static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
  196. // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
  197. 9, // bLength;
  198. 2, // bDescriptorType;
  199. LSB(CONFIG1_DESC_SIZE), // wTotalLength
  200. MSB(CONFIG1_DESC_SIZE),
  201. 5, // bNumInterfaces
  202. 1, // bConfigurationValue
  203. 0, // iConfiguration
  204. 0xC0, // bmAttributes
  205. 50, // bMaxPower
  206. // interface association descriptor, USB ECN, Table 9-Z
  207. 8, // bLength
  208. 11, // bDescriptorType
  209. 0, // bFirstInterface
  210. 2, // bInterfaceCount
  211. 0x02, // bFunctionClass
  212. 0x02, // bFunctionSubClass
  213. 0x01, // bFunctionProtocol
  214. 4, // iFunction
  215. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  216. 9, // bLength
  217. 4, // bDescriptorType
  218. 0, // bInterfaceNumber
  219. 0, // bAlternateSetting
  220. 1, // bNumEndpoints
  221. 0x02, // bInterfaceClass
  222. 0x02, // bInterfaceSubClass
  223. 0x01, // bInterfaceProtocol
  224. 0, // iInterface
  225. // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
  226. 5, // bFunctionLength
  227. 0x24, // bDescriptorType
  228. 0x00, // bDescriptorSubtype
  229. 0x10, 0x01, // bcdCDC
  230. // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
  231. 5, // bFunctionLength
  232. 0x24, // bDescriptorType
  233. 0x01, // bDescriptorSubtype
  234. 0x00, // bmCapabilities
  235. 1, // bDataInterface
  236. // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
  237. 4, // bFunctionLength
  238. 0x24, // bDescriptorType
  239. 0x02, // bDescriptorSubtype
  240. 0x06, // bmCapabilities
  241. // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
  242. 5, // bFunctionLength
  243. 0x24, // bDescriptorType
  244. 0x06, // bDescriptorSubtype
  245. 0, // bMasterInterface
  246. 1, // bSlaveInterface0
  247. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  248. 7, // bLength
  249. 5, // bDescriptorType
  250. CDC_ACM_ENDPOINT | 0x80, // bEndpointAddress
  251. 0x03, // bmAttributes (0x03=intr)
  252. CDC_ACM_SIZE, 0, // wMaxPacketSize
  253. 64, // bInterval
  254. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  255. 9, // bLength
  256. 4, // bDescriptorType
  257. 1, // bInterfaceNumber
  258. 0, // bAlternateSetting
  259. 2, // bNumEndpoints
  260. 0x0A, // bInterfaceClass
  261. 0x00, // bInterfaceSubClass
  262. 0x00, // bInterfaceProtocol
  263. 0, // iInterface
  264. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  265. 7, // bLength
  266. 5, // bDescriptorType
  267. CDC_RX_ENDPOINT, // bEndpointAddress
  268. 0x02, // bmAttributes (0x02=bulk)
  269. CDC_RX_SIZE, 0, // wMaxPacketSize
  270. 0, // bInterval
  271. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  272. 7, // bLength
  273. 5, // bDescriptorType
  274. CDC_TX_ENDPOINT | 0x80, // bEndpointAddress
  275. 0x02, // bmAttributes (0x02=bulk)
  276. CDC_TX_SIZE, 0, // wMaxPacketSize
  277. 0, // bInterval
  278. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  279. 9, // bLength
  280. 4, // bDescriptorType
  281. KEYBOARD_INTERFACE, // bInterfaceNumber
  282. 0, // bAlternateSetting
  283. 1, // bNumEndpoints
  284. 0x03, // bInterfaceClass (0x03 = HID)
  285. 0x01, // bInterfaceSubClass (0x01 = Boot)
  286. 0x01, // bInterfaceProtocol (0x01 = Keyboard)
  287. 0, // iInterface
  288. // HID interface descriptor, HID 1.11 spec, section 6.2.1
  289. 9, // bLength
  290. 0x21, // bDescriptorType
  291. 0x11, 0x01, // bcdHID
  292. 0, // bCountryCode
  293. 1, // bNumDescriptors
  294. 0x22, // bDescriptorType
  295. sizeof(keyboard_hid_report_desc), // wDescriptorLength
  296. 0,
  297. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  298. 7, // bLength
  299. 5, // bDescriptorType
  300. KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress
  301. 0x03, // bmAttributes (0x03=intr)
  302. KEYBOARD_SIZE, 0, // wMaxPacketSize
  303. KEYBOARD_INTERVAL, // bInterval
  304. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  305. 9, // bLength
  306. 4, // bDescriptorType
  307. MOUSE_INTERFACE, // bInterfaceNumber
  308. 0, // bAlternateSetting
  309. 1, // bNumEndpoints
  310. 0x03, // bInterfaceClass (0x03 = HID)
  311. 0x01, // bInterfaceSubClass (0x01 = Boot)
  312. 0x02, // bInterfaceProtocol (0x02 = Mouse)
  313. 0, // iInterface
  314. // HID interface descriptor, HID 1.11 spec, section 6.2.1
  315. 9, // bLength
  316. 0x21, // bDescriptorType
  317. 0x11, 0x01, // bcdHID
  318. 0, // bCountryCode
  319. 1, // bNumDescriptors
  320. 0x22, // bDescriptorType
  321. sizeof(mouse_hid_report_desc), // wDescriptorLength
  322. 0,
  323. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  324. 7, // bLength
  325. 5, // bDescriptorType
  326. MOUSE_ENDPOINT | 0x80, // bEndpointAddress
  327. 0x03, // bmAttributes (0x03=intr)
  328. MOUSE_SIZE, 0, // wMaxPacketSize
  329. MOUSE_INTERVAL, // bInterval
  330. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  331. 9, // bLength
  332. 4, // bDescriptorType
  333. JOYSTICK_INTERFACE, // bInterfaceNumber
  334. 0, // bAlternateSetting
  335. 1, // bNumEndpoints
  336. 0x03, // bInterfaceClass (0x03 = HID)
  337. 0x00, // bInterfaceSubClass
  338. 0x00, // bInterfaceProtocol
  339. 0, // iInterface
  340. // HID interface descriptor, HID 1.11 spec, section 6.2.1
  341. 9, // bLength
  342. 0x21, // bDescriptorType
  343. 0x11, 0x01, // bcdHID
  344. 0, // bCountryCode
  345. 1, // bNumDescriptors
  346. 0x22, // bDescriptorType
  347. sizeof(joystick_hid_report_desc), // wDescriptorLength
  348. 0,
  349. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  350. 7, // bLength
  351. 5, // bDescriptorType
  352. JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress
  353. 0x03, // bmAttributes (0x03=intr)
  354. 12, 0, // wMaxPacketSize
  355. JOYSTICK_INTERVAL // bInterval
  356. };
  357. // If you're desperate for a little extra code memory, these strings
  358. // can be completely removed if iManufacturer, iProduct, iSerialNumber
  359. // in the device desciptor are changed to zeros.
  360. struct usb_string_descriptor_struct {
  361. uint8_t bLength;
  362. uint8_t bDescriptorType;
  363. int16_t wString[];
  364. };
  365. static const struct usb_string_descriptor_struct PROGMEM string0 = {
  366. 4,
  367. 3,
  368. {0x0409}
  369. };
  370. static const struct usb_string_descriptor_struct PROGMEM string1 = {
  371. sizeof(STR_MANUFACTURER),
  372. 3,
  373. STR_MANUFACTURER
  374. };
  375. static const struct usb_string_descriptor_struct PROGMEM string2 = {
  376. sizeof(STR_PRODUCT),
  377. 3,
  378. STR_PRODUCT
  379. };
  380. static const struct usb_string_descriptor_struct PROGMEM string3 = {
  381. sizeof(STR_SERIAL_NUMBER),
  382. 3,
  383. STR_SERIAL_NUMBER
  384. };
  385. static const struct usb_string_descriptor_struct PROGMEM string4 = {
  386. sizeof(STR_SERIAL),
  387. 3,
  388. STR_SERIAL
  389. };
  390. // This table defines which descriptor data is sent for each specific
  391. // request from the host (in wValue and wIndex).
  392. static const struct descriptor_list_struct {
  393. uint16_t wValue;
  394. uint16_t wIndex;
  395. const uint8_t *addr;
  396. uint8_t length;
  397. } PROGMEM descriptor_list[] = {
  398. {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
  399. {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
  400. {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
  401. {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
  402. {0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
  403. {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
  404. {0x2200, JOYSTICK_INTERFACE, joystick_hid_report_desc, sizeof(joystick_hid_report_desc)},
  405. {0x2100, JOYSTICK_INTERFACE, config1_descriptor+JOYSTICK_HID_DESC_OFFSET, 9},
  406. {0x0300, 0x0000, (const uint8_t *)&string0, 4},
  407. {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
  408. {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)},
  409. {0x0303, 0x0409, (const uint8_t *)&string3, sizeof(STR_SERIAL_NUMBER)},
  410. {0x0304, 0x0409, (const uint8_t *)&string4, sizeof(STR_SERIAL)},
  411. };
  412. #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
  413. /**************************************************************************
  414. *
  415. * Variables - these are the only non-stack RAM usage
  416. *
  417. **************************************************************************/
  418. // zero when we are not configured, non-zero when enumerated
  419. volatile uint8_t usb_configuration USBSTATE;
  420. volatile uint8_t usb_suspended USBSTATE;
  421. // the time remaining before we transmit any partially full
  422. // packet, or send a zero length packet.
  423. volatile uint8_t transmit_flush_timer=0;
  424. volatile uint8_t reboot_timer=0;
  425. uint8_t transmit_previous_timeout=0;
  426. // serial port settings (baud rate, control signals, etc) set
  427. // by the PC. These are ignored, but kept in RAM because the
  428. // CDC spec requires a read that returns the current settings.
  429. volatile uint8_t cdc_line_coding[7]={0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x08};
  430. volatile uint8_t cdc_line_rtsdtr USBSTATE;
  431. // byte0: which modifier keys are currently pressed
  432. // 1=left ctrl, 2=left shift, 4=left alt, 8=left gui
  433. // 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
  434. // byte1: media keys (TODO: document these)
  435. // bytes2-7: which keys are currently pressed, up to 6 keys may be down at once
  436. uint8_t keyboard_report_data[8] USBSTATE;
  437. // protocol setting from the host. We use exactly the same report
  438. // either way, so this variable only stores the setting since we
  439. // are required to be able to report which setting is in use.
  440. static uint8_t keyboard_protocol USBSTATE;
  441. // the idle configuration, how often we send the report to the
  442. // host (ms * 4) even when it hasn't changed
  443. static uint8_t keyboard_idle_config USBSTATE;
  444. // count until idle timeout
  445. uint8_t keyboard_idle_count USBSTATE;
  446. // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
  447. volatile uint8_t keyboard_leds USBSTATE;
  448. // which buttons are currently pressed
  449. uint8_t mouse_buttons USBSTATE;
  450. // protocol setting from the host. We use exactly the same report
  451. // either way, so this variable only stores the setting since we
  452. // are required to be able to report which setting is in use.
  453. static uint8_t mouse_protocol USBSTATE;
  454. // joystick data
  455. uint8_t joystick_report_data[12] USBSTATE;
  456. /**************************************************************************
  457. *
  458. * Public Functions - these are the API intended for the user
  459. *
  460. **************************************************************************/
  461. // initialize USB serial
  462. void usb_init(void)
  463. {
  464. uint8_t u;
  465. u = USBCON;
  466. if ((u & (1<<USBE)) && !(u & (1<<FRZCLK))) return;
  467. HW_CONFIG();
  468. USB_FREEZE(); // enable USB
  469. PLL_CONFIG(); // config PLL
  470. while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
  471. USB_CONFIG(); // start USB clock
  472. UDCON = 0; // enable attach resistor
  473. usb_configuration = 0;
  474. usb_suspended = 0;
  475. cdc_line_rtsdtr = 0;
  476. keyboard_report_data[0] = 0;
  477. keyboard_report_data[1] = 0;
  478. keyboard_report_data[2] = 0;
  479. keyboard_report_data[3] = 0;
  480. keyboard_report_data[4] = 0;
  481. keyboard_report_data[5] = 0;
  482. keyboard_report_data[6] = 0;
  483. keyboard_report_data[7] = 0;
  484. keyboard_protocol = 1;
  485. keyboard_idle_config = 125;
  486. keyboard_idle_count = 0;
  487. keyboard_leds = 0;
  488. mouse_buttons = 0;
  489. mouse_protocol = 1;
  490. joystick_report_data[0] = 0;
  491. joystick_report_data[1] = 0;
  492. joystick_report_data[2] = 0;
  493. joystick_report_data[3] = 0;
  494. joystick_report_data[4] = 0x0F;
  495. joystick_report_data[5] = 0x20;
  496. joystick_report_data[6] = 0x80;
  497. joystick_report_data[7] = 0x00;
  498. joystick_report_data[8] = 0x02;
  499. joystick_report_data[9] = 0x08;
  500. joystick_report_data[10] = 0x20;
  501. joystick_report_data[11] = 0x80;
  502. UDINT = 0;
  503. UDIEN = (1<<EORSTE)|(1<<SOFE)|(1<<SUSPE);
  504. }
  505. void usb_shutdown(void)
  506. {
  507. UDIEN = 0; // disable interrupts
  508. UDCON = 1; // disconnect attach resistor
  509. USBCON = 0; // shut off USB periperal
  510. PLLCSR = 0; // shut off PLL
  511. usb_configuration = 0;
  512. usb_suspended = 1;
  513. }
  514. // Public API functions moved to usb_api.cpp
  515. /**************************************************************************
  516. *
  517. * Private Functions - not intended for general user consumption....
  518. *
  519. **************************************************************************/
  520. // USB Device Interrupt - handle all device-level events
  521. // the transmit buffer flushing is triggered by the start of frame
  522. //
  523. ISR(USB_GEN_vect)
  524. {
  525. uint8_t intbits, t, i;
  526. static uint8_t div4=0;
  527. intbits = UDINT;
  528. UDINT = 0;
  529. if (intbits & (1<<EORSTI)) {
  530. // USB Reset
  531. UENUM = 0;
  532. UECONX = 1;
  533. UECFG0X = EP_TYPE_CONTROL;
  534. UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
  535. UEIENX = (1<<RXSTPE);
  536. usb_configuration = 0;
  537. cdc_line_rtsdtr = 0;
  538. }
  539. if (intbits & (1<<SOFI)) {
  540. // Start Of Frame
  541. if (usb_configuration) {
  542. t = transmit_flush_timer;
  543. if (t) {
  544. transmit_flush_timer = --t;
  545. if (!t) {
  546. UENUM = CDC_TX_ENDPOINT;
  547. UEINTX = 0x3A;
  548. }
  549. }
  550. t = reboot_timer;
  551. if (t) {
  552. reboot_timer = --t;
  553. if (!t) _reboot_Teensyduino_();
  554. }
  555. if (keyboard_idle_config && (++div4 & 3) == 0) {
  556. UENUM = KEYBOARD_ENDPOINT;
  557. if (UEINTX & (1<<RWAL)) {
  558. keyboard_idle_count++;
  559. if (keyboard_idle_count == keyboard_idle_config) {
  560. keyboard_idle_count = 0;
  561. //len = keyboard_protocol ? sizeof(keyboard_keys) : 8;
  562. for (i=0; i < 8; i++) {
  563. UEDATX = keyboard_report_data[i];
  564. }
  565. UEINTX = 0x3A;
  566. }
  567. }
  568. }
  569. }
  570. }
  571. // in active state
  572. if (intbits & (1<<SUSPI)) {
  573. // USB Suspend (inactivity for 3ms)
  574. UDIEN = (1<<WAKEUPE);
  575. usb_configuration = 0;
  576. usb_suspended = 1;
  577. #if (F_CPU >= 8000000L)
  578. // WAKEUPI does not work with USB clock freeze
  579. // when CPU is running less than 8 MHz.
  580. // Is this a hardware bug?
  581. USB_FREEZE(); // shut off USB
  582. PLLCSR = 0; // shut off PLL
  583. #endif
  584. // to properly meet the USB spec, current must
  585. // reduce to less than 2.5 mA, which means using
  586. // powerdown mode, but that breaks the Arduino
  587. // user's paradigm....
  588. }
  589. if (usb_suspended && (intbits & (1<<WAKEUPI))) {
  590. // USB Resume (pretty much any activity)
  591. #if (F_CPU >= 8000000L)
  592. PLL_CONFIG();
  593. while (!(PLLCSR & (1<<PLOCK))) ;
  594. USB_CONFIG();
  595. #endif
  596. UDIEN = (1<<EORSTE)|(1<<SOFE)|(1<<SUSPE);
  597. usb_suspended = 0;
  598. return;
  599. }
  600. }
  601. // Misc functions to wait for ready and send/receive packets
  602. static inline void usb_wait_in_ready(void)
  603. {
  604. while (!(UEINTX & (1<<TXINI))) ;
  605. }
  606. static inline void usb_send_in(void)
  607. {
  608. UEINTX = ~(1<<TXINI);
  609. }
  610. static inline void usb_wait_receive_out(void)
  611. {
  612. while (!(UEINTX & (1<<RXOUTI))) ;
  613. }
  614. static inline void usb_ack_out(void)
  615. {
  616. UEINTX = ~(1<<RXOUTI);
  617. }
  618. // USB Endpoint Interrupt - endpoint 0 is handled here. The
  619. // other endpoints are manipulated by the user-callable
  620. // functions, and the start-of-frame interrupt.
  621. //
  622. ISR(USB_COM_vect)
  623. {
  624. uint8_t intbits;
  625. const uint8_t *list;
  626. const uint8_t *cfg;
  627. uint8_t i, n, len;
  628. volatile uint8_t *p;
  629. uint8_t bmRequestType;
  630. uint8_t bRequest;
  631. uint16_t wValue;
  632. uint16_t wIndex;
  633. uint16_t wLength;
  634. uint16_t desc_val;
  635. const uint8_t *desc_addr;
  636. uint8_t desc_length;
  637. UENUM = 0;
  638. intbits = UEINTX;
  639. if (intbits & (1<<RXSTPI)) {
  640. bmRequestType = UEDATX;
  641. bRequest = UEDATX;
  642. read_word_lsbfirst(wValue, UEDATX);
  643. read_word_lsbfirst(wIndex, UEDATX);
  644. read_word_lsbfirst(wLength, UEDATX);
  645. UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
  646. if (bRequest == GET_DESCRIPTOR) {
  647. list = (const uint8_t *)descriptor_list;
  648. for (i=0; ; i++) {
  649. if (i >= NUM_DESC_LIST) {
  650. UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
  651. return;
  652. }
  653. pgm_read_word_postinc(desc_val, list);
  654. if (desc_val != wValue) {
  655. list += sizeof(struct descriptor_list_struct)-2;
  656. continue;
  657. }
  658. pgm_read_word_postinc(desc_val, list);
  659. if (desc_val != wIndex) {
  660. list += sizeof(struct descriptor_list_struct)-4;
  661. continue;
  662. }
  663. pgm_read_word_postinc(desc_addr, list);
  664. desc_length = pgm_read_byte(list);
  665. break;
  666. }
  667. len = (wLength < 256) ? wLength : 255;
  668. if (len > desc_length) len = desc_length;
  669. list = desc_addr;
  670. do {
  671. // wait for host ready for IN packet
  672. do {
  673. i = UEINTX;
  674. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  675. if (i & (1<<RXOUTI)) return; // abort
  676. // send IN packet
  677. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  678. for (i = n; i; i--) {
  679. pgm_read_byte_postinc(UEDATX, list);
  680. }
  681. len -= n;
  682. usb_send_in();
  683. } while (len || n == ENDPOINT0_SIZE);
  684. return;
  685. }
  686. if (bRequest == SET_ADDRESS) {
  687. usb_send_in();
  688. usb_wait_in_ready();
  689. UDADDR = wValue | (1<<ADDEN);
  690. return;
  691. }
  692. if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
  693. usb_configuration = wValue;
  694. cdc_line_rtsdtr = 0;
  695. transmit_flush_timer = 0;
  696. usb_send_in();
  697. cfg = endpoint_config_table;
  698. for (i=1; i<7; i++) {
  699. UENUM = i;
  700. //pgm_read_byte_postinc(en, cfg);
  701. //UECONX = en;
  702. UECONX = 1;
  703. //if (en) {
  704. pgm_read_byte_postinc(UECFG0X, cfg);
  705. pgm_read_byte_postinc(UECFG1X, cfg);
  706. //}
  707. }
  708. UERST = 0x1E;
  709. UERST = 0;
  710. return;
  711. }
  712. if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
  713. usb_wait_in_ready();
  714. UEDATX = usb_configuration;
  715. usb_send_in();
  716. return;
  717. }
  718. if (bRequest == CDC_GET_LINE_CODING /* 0x21 */ && bmRequestType == 0xA1) {
  719. usb_wait_in_ready();
  720. p = cdc_line_coding;
  721. for (i=0; i<7; i++) {
  722. UEDATX = *p++;
  723. }
  724. usb_send_in();
  725. return;
  726. }
  727. if (bRequest == CDC_SET_LINE_CODING /* 0x20 */ && bmRequestType == 0x21) {
  728. usb_wait_receive_out();
  729. p = cdc_line_coding;
  730. for (i=0; i<7; i++) {
  731. *p++ = UEDATX;
  732. }
  733. usb_ack_out();
  734. usb_send_in();
  735. if (*(long *)cdc_line_coding == 134L) reboot_timer = 15;
  736. if (*(long *)cdc_line_coding == 150L) {
  737. UENUM = CDC_TX_ENDPOINT;
  738. while (UESTA0X & 0x03) {
  739. UEINTX = 0xFF;
  740. while (UEINTX & 0x04) /* TODO: timeout? */ ;
  741. }
  742. _restart_Teensyduino_();
  743. }
  744. return;
  745. }
  746. if (bRequest == CDC_SET_CONTROL_LINE_STATE /* 0x22 */ && bmRequestType == 0x21) {
  747. cdc_line_rtsdtr = wValue;
  748. usb_wait_in_ready();
  749. usb_send_in();
  750. return;
  751. }
  752. if (bRequest == CDC_SEND_BREAK /* 0x23 */ && bmRequestType == 0x21) {
  753. usb_wait_in_ready();
  754. usb_send_in();
  755. return;
  756. }
  757. if (bRequest == GET_STATUS) {
  758. usb_wait_in_ready();
  759. i = 0;
  760. if (bmRequestType == 0x82) {
  761. UENUM = wIndex;
  762. if (UECONX & (1<<STALLRQ)) i = 1;
  763. UENUM = 0;
  764. }
  765. UEDATX = i;
  766. UEDATX = 0;
  767. usb_send_in();
  768. return;
  769. }
  770. if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
  771. && bmRequestType == 0x02 && wValue == 0) {
  772. i = wIndex & 0x7F;
  773. if (i >= 1 && i <= MAX_ENDPOINT) {
  774. usb_send_in();
  775. UENUM = i;
  776. if (bRequest == SET_FEATURE) {
  777. UECONX = (1<<STALLRQ)|(1<<EPEN);
  778. } else {
  779. UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
  780. UERST = (1 << i);
  781. UERST = 0;
  782. }
  783. return;
  784. }
  785. }
  786. if (wIndex == KEYBOARD_INTERFACE) {
  787. if (bmRequestType == 0xA1) {
  788. if (bRequest == HID_GET_REPORT) {
  789. usb_wait_in_ready();
  790. //len = keyboard_protocol ? sizeof(keyboard_keys) : 8;
  791. for (i=0; i < 8; i++) {
  792. UEDATX = keyboard_report_data[i];
  793. }
  794. usb_send_in();
  795. return;
  796. }
  797. if (bRequest == HID_GET_IDLE) {
  798. usb_wait_in_ready();
  799. UEDATX = keyboard_idle_config;
  800. usb_send_in();
  801. return;
  802. }
  803. if (bRequest == HID_GET_PROTOCOL) {
  804. usb_wait_in_ready();
  805. UEDATX = keyboard_protocol;
  806. usb_send_in();
  807. return;
  808. }
  809. }
  810. if (bmRequestType == 0x21) {
  811. if (bRequest == HID_SET_REPORT) {
  812. usb_wait_receive_out();
  813. keyboard_leds = UEDATX;
  814. usb_ack_out();
  815. usb_send_in();
  816. return;
  817. }
  818. if (bRequest == HID_SET_IDLE) {
  819. keyboard_idle_config = (wValue >> 8);
  820. keyboard_idle_count = 0;
  821. //usb_wait_in_ready();
  822. usb_send_in();
  823. return;
  824. }
  825. if (bRequest == HID_SET_PROTOCOL) {
  826. keyboard_protocol = wValue;
  827. //usb_wait_in_ready();
  828. usb_send_in();
  829. return;
  830. }
  831. }
  832. }
  833. if (wIndex == MOUSE_INTERFACE) {
  834. if (bmRequestType == 0xA1) {
  835. if (bRequest == HID_GET_REPORT) {
  836. usb_wait_in_ready();
  837. UEDATX = mouse_buttons;
  838. UEDATX = 0;
  839. UEDATX = 0;
  840. UEDATX = 0;
  841. UEDATX = 0;
  842. usb_send_in();
  843. return;
  844. }
  845. if (bRequest == HID_GET_PROTOCOL) {
  846. usb_wait_in_ready();
  847. UEDATX = mouse_protocol;
  848. usb_send_in();
  849. return;
  850. }
  851. }
  852. if (bmRequestType == 0x21) {
  853. if (bRequest == HID_SET_PROTOCOL) {
  854. mouse_protocol = wValue;
  855. usb_send_in();
  856. return;
  857. }
  858. }
  859. }
  860. if (wIndex == JOYSTICK_INTERFACE) {
  861. if (bmRequestType == 0xA1) {
  862. if (bRequest == HID_GET_REPORT) {
  863. usb_wait_in_ready();
  864. for (i=0; i<12; i++) {
  865. UEDATX = joystick_report_data[i];
  866. }
  867. usb_send_in();
  868. return;
  869. }
  870. }
  871. }
  872. }
  873. UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
  874. }