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.

953 lines
39KB

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