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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

usb.c 33KB

13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. /* USB Keyboard Plus Debug Channel Example for Teensy USB Development Board
  2. * http://www.pjrc.com/teensy/usb_keyboard.html
  3. * Copyright (c) 2009 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 <stdint.h>
  24. #include <stdbool.h>
  25. #include <avr/io.h>
  26. #include <avr/pgmspace.h>
  27. #include <avr/interrupt.h>
  28. #include "usb.h"
  29. #include "usb_keyboard.h"
  30. #include "usb_mouse.h"
  31. #include "usb_debug.h"
  32. #include "usb_extra.h"
  33. #include "led.h"
  34. #include "print.h"
  35. #include "util.h"
  36. #ifdef SLEEP_LED_ENABLE
  37. #include "sleep_led.h"
  38. #endif
  39. #include "suspend.h"
  40. #include "action_util.h"
  41. /**************************************************************************
  42. *
  43. * Configurable Options
  44. *
  45. **************************************************************************/
  46. // You can change these to give your code its own name.
  47. #ifndef MANUFACTURER
  48. # define STR_MANUFACTURER L"t.m.k."
  49. #else
  50. # define STR_MANUFACTURER LSTR(MANUFACTURER)
  51. #endif
  52. #ifndef PRODUCT
  53. # define STR_PRODUCT L"t.m.k. keyboard"
  54. #else
  55. # define STR_PRODUCT LSTR(PRODUCT)
  56. #endif
  57. // Mac OS-X and Linux automatically load the correct drivers. On
  58. // Windows, even though the driver is supplied by Microsoft, an
  59. // INF file is needed to load the driver. These numbers need to
  60. // match the INF file.
  61. #ifndef VENDOR_ID
  62. # define VENDOR_ID 0xFEED
  63. #endif
  64. #ifndef PRODUCT_ID
  65. # define PRODUCT_ID 0xBABE
  66. #endif
  67. #ifndef DEVICE_VER
  68. # define DEVICE_VER 0x0100
  69. #endif
  70. // USB devices are supposed to implment a halt feature, which is
  71. // rarely (if ever) used. If you comment this line out, the halt
  72. // code will be removed, saving 102 bytes of space (gcc 4.3.0).
  73. // This is not strictly USB compliant, but works with all major
  74. // operating systems.
  75. #define SUPPORT_ENDPOINT_HALT
  76. /**************************************************************************
  77. *
  78. * Endpoint Buffer Configuration
  79. *
  80. **************************************************************************/
  81. #define ENDPOINT0_SIZE 32
  82. bool remote_wakeup = false;
  83. bool suspend = false;
  84. // 0:control endpoint is enabled automatically by controller.
  85. static const uint8_t PROGMEM endpoint_config_table[] = {
  86. // enable, UECFG0X(type, direction), UECFG1X(size, bank, allocation)
  87. 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KBD_SIZE) | KBD_BUFFER, // 1
  88. #ifdef MOUSE_ENABLE
  89. 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER, // 2
  90. #else
  91. 0, // 2
  92. #endif
  93. #ifdef CONSOLE_ENABLE
  94. 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3
  95. #else
  96. 0,
  97. #endif
  98. #ifdef EXTRAKEY_ENABLE
  99. 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4
  100. #else
  101. 0, // 4
  102. #endif
  103. #ifdef NKRO_ENABLE
  104. 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KBD2_SIZE) | KBD2_BUFFER, // 5
  105. #else
  106. 0, // 5
  107. #endif
  108. 0, // 6
  109. };
  110. /**************************************************************************
  111. *
  112. * Descriptor Data
  113. *
  114. **************************************************************************/
  115. // Descriptors are the data that your computer reads when it auto-detects
  116. // this USB device (called "enumeration" in USB lingo). The most commonly
  117. // changed items are editable at the top of this file. Changing things
  118. // in here should only be done by those who've read chapter 9 of the USB
  119. // spec and relevant portions of any USB class specifications!
  120. static const uint8_t PROGMEM device_descriptor[] = {
  121. 18, // bLength
  122. 1, // bDescriptorType
  123. 0x00, 0x02, // bcdUSB
  124. 0, // bDeviceClass
  125. 0, // bDeviceSubClass
  126. 0, // bDeviceProtocol
  127. ENDPOINT0_SIZE, // bMaxPacketSize0
  128. LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
  129. LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
  130. LSB(DEVICE_VER), MSB(DEVICE_VER), // bcdDevice
  131. 1, // iManufacturer
  132. 2, // iProduct
  133. 0, // iSerialNumber
  134. 1 // bNumConfigurations
  135. };
  136. // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
  137. static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
  138. 0x05, 0x01, // Usage Page (Generic Desktop),
  139. 0x09, 0x06, // Usage (Keyboard),
  140. 0xA1, 0x01, // Collection (Application),
  141. 0x75, 0x01, // Report Size (1),
  142. 0x95, 0x08, // Report Count (8),
  143. 0x05, 0x07, // Usage Page (Key Codes),
  144. 0x19, 0xE0, // Usage Minimum (224),
  145. 0x29, 0xE7, // Usage Maximum (231),
  146. 0x15, 0x00, // Logical Minimum (0),
  147. 0x25, 0x01, // Logical Maximum (1),
  148. 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
  149. 0x95, 0x01, // Report Count (1),
  150. 0x75, 0x08, // Report Size (8),
  151. 0x81, 0x03, // Input (Constant), ;Reserved byte
  152. 0x95, 0x05, // Report Count (5),
  153. 0x75, 0x01, // Report Size (1),
  154. 0x05, 0x08, // Usage Page (LEDs),
  155. 0x19, 0x01, // Usage Minimum (1),
  156. 0x29, 0x05, // Usage Maximum (5),
  157. 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
  158. 0x95, 0x01, // Report Count (1),
  159. 0x75, 0x03, // Report Size (3),
  160. 0x91, 0x03, // Output (Constant), ;LED report padding
  161. 0x95, KBD_REPORT_KEYS, // Report Count (),
  162. 0x75, 0x08, // Report Size (8),
  163. 0x15, 0x00, // Logical Minimum (0),
  164. 0x25, 0xFF, // Logical Maximum(255),
  165. 0x05, 0x07, // Usage Page (Key Codes),
  166. 0x19, 0x00, // Usage Minimum (0),
  167. 0x29, 0xFF, // Usage Maximum (255),
  168. 0x81, 0x00, // Input (Data, Array),
  169. 0xc0 // End Collection
  170. };
  171. #ifdef NKRO_ENABLE
  172. static const uint8_t PROGMEM keyboard2_hid_report_desc[] = {
  173. 0x05, 0x01, // Usage Page (Generic Desktop),
  174. 0x09, 0x06, // Usage (Keyboard),
  175. 0xA1, 0x01, // Collection (Application),
  176. // bitmap of modifiers
  177. 0x75, 0x01, // Report Size (1),
  178. 0x95, 0x08, // Report Count (8),
  179. 0x05, 0x07, // Usage Page (Key Codes),
  180. 0x19, 0xE0, // Usage Minimum (224),
  181. 0x29, 0xE7, // Usage Maximum (231),
  182. 0x15, 0x00, // Logical Minimum (0),
  183. 0x25, 0x01, // Logical Maximum (1),
  184. 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
  185. // LED output report
  186. 0x95, 0x05, // Report Count (5),
  187. 0x75, 0x01, // Report Size (1),
  188. 0x05, 0x08, // Usage Page (LEDs),
  189. 0x19, 0x01, // Usage Minimum (1),
  190. 0x29, 0x05, // Usage Maximum (5),
  191. 0x91, 0x02, // Output (Data, Variable, Absolute),
  192. 0x95, 0x01, // Report Count (1),
  193. 0x75, 0x03, // Report Size (3),
  194. 0x91, 0x03, // Output (Constant),
  195. // bitmap of keys
  196. 0x95, KBD2_REPORT_KEYS*8, // Report Count (),
  197. 0x75, 0x01, // Report Size (1),
  198. 0x15, 0x00, // Logical Minimum (0),
  199. 0x25, 0x01, // Logical Maximum(1),
  200. 0x05, 0x07, // Usage Page (Key Codes),
  201. 0x19, 0x00, // Usage Minimum (0),
  202. 0x29, KBD2_REPORT_KEYS*8-1, // Usage Maximum (),
  203. 0x81, 0x02, // Input (Data, Variable, Absolute),
  204. 0xc0 // End Collection
  205. };
  206. #endif
  207. #ifdef MOUSE_ENABLE
  208. // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
  209. // http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
  210. // http://www.keil.com/forum/15671/
  211. // http://www.microsoft.com/whdc/device/input/wheel.mspx
  212. static const uint8_t PROGMEM mouse_hid_report_desc[] = {
  213. /* mouse */
  214. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  215. 0x09, 0x02, // USAGE (Mouse)
  216. 0xa1, 0x01, // COLLECTION (Application)
  217. //0x85, REPORT_ID_MOUSE, // REPORT_ID (1)
  218. 0x09, 0x01, // USAGE (Pointer)
  219. 0xa1, 0x00, // COLLECTION (Physical)
  220. // ---------------------------- Buttons
  221. 0x05, 0x09, // USAGE_PAGE (Button)
  222. 0x19, 0x01, // USAGE_MINIMUM (Button 1)
  223. 0x29, 0x05, // USAGE_MAXIMUM (Button 5)
  224. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  225. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  226. 0x75, 0x01, // REPORT_SIZE (1)
  227. 0x95, 0x05, // REPORT_COUNT (5)
  228. 0x81, 0x02, // INPUT (Data,Var,Abs)
  229. 0x75, 0x03, // REPORT_SIZE (3)
  230. 0x95, 0x01, // REPORT_COUNT (1)
  231. 0x81, 0x03, // INPUT (Cnst,Var,Abs)
  232. // ---------------------------- X,Y position
  233. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  234. 0x09, 0x30, // USAGE (X)
  235. 0x09, 0x31, // USAGE (Y)
  236. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  237. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  238. 0x75, 0x08, // REPORT_SIZE (8)
  239. 0x95, 0x02, // REPORT_COUNT (2)
  240. 0x81, 0x06, // INPUT (Data,Var,Rel)
  241. // ---------------------------- Vertical wheel
  242. 0x09, 0x38, // USAGE (Wheel)
  243. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  244. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  245. 0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical
  246. 0x45, 0x00, // PHYSICAL_MAXIMUM (0)
  247. 0x75, 0x08, // REPORT_SIZE (8)
  248. 0x95, 0x01, // REPORT_COUNT (1)
  249. 0x81, 0x06, // INPUT (Data,Var,Rel)
  250. // ---------------------------- Horizontal wheel
  251. 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
  252. 0x0a, 0x38, 0x02, // USAGE (AC Pan)
  253. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  254. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  255. 0x75, 0x08, // REPORT_SIZE (8)
  256. 0x95, 0x01, // REPORT_COUNT (1)
  257. 0x81, 0x06, // INPUT (Data,Var,Rel)
  258. 0xc0, // END_COLLECTION
  259. 0xc0, // END_COLLECTION
  260. };
  261. #endif
  262. static const uint8_t PROGMEM debug_hid_report_desc[] = {
  263. 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
  264. 0x09, 0x74, // Usage 0x74
  265. 0xA1, 0x53, // Collection 0x53
  266. 0x75, 0x08, // report size = 8 bits
  267. 0x15, 0x00, // logical minimum = 0
  268. 0x26, 0xFF, 0x00, // logical maximum = 255
  269. 0x95, DEBUG_TX_SIZE, // report count
  270. 0x09, 0x75, // usage
  271. 0x81, 0x02, // Input (array)
  272. 0xC0 // end collection
  273. };
  274. #ifdef EXTRAKEY_ENABLE
  275. // audio controls & system controls
  276. // http://www.microsoft.com/whdc/archive/w2kbd.mspx
  277. static const uint8_t PROGMEM extra_hid_report_desc[] = {
  278. /* system control */
  279. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  280. 0x09, 0x80, // USAGE (System Control)
  281. 0xa1, 0x01, // COLLECTION (Application)
  282. 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2)
  283. 0x15, 0x01, // LOGICAL_MINIMUM (0x1)
  284. 0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7)
  285. 0x19, 0x01, // USAGE_MINIMUM (0x1)
  286. 0x29, 0xb7, // USAGE_MAXIMUM (0xb7)
  287. 0x75, 0x10, // REPORT_SIZE (16)
  288. 0x95, 0x01, // REPORT_COUNT (1)
  289. 0x81, 0x00, // INPUT (Data,Array,Abs)
  290. 0xc0, // END_COLLECTION
  291. /* consumer */
  292. 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
  293. 0x09, 0x01, // USAGE (Consumer Control)
  294. 0xa1, 0x01, // COLLECTION (Application)
  295. 0x85, REPORT_ID_CONSUMER, // REPORT_ID (3)
  296. 0x15, 0x01, // LOGICAL_MINIMUM (0x1)
  297. 0x26, 0x9c, 0x02, // LOGICAL_MAXIMUM (0x29c)
  298. 0x19, 0x01, // USAGE_MINIMUM (0x1)
  299. 0x2a, 0x9c, 0x02, // USAGE_MAXIMUM (0x29c)
  300. 0x75, 0x10, // REPORT_SIZE (16)
  301. 0x95, 0x01, // REPORT_COUNT (1)
  302. 0x81, 0x00, // INPUT (Data,Array,Abs)
  303. 0xc0, // END_COLLECTION
  304. };
  305. #endif
  306. #define KBD_HID_DESC_NUM 0
  307. #define KBD_HID_DESC_OFFSET (9+(9+9+7)*KBD_HID_DESC_NUM+9)
  308. #ifdef MOUSE_ENABLE
  309. # define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 1)
  310. # define MOUSE_HID_DESC_OFFSET (9+(9+9+7)*MOUSE_HID_DESC_NUM+9)
  311. #else
  312. # define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 0)
  313. #endif
  314. #ifdef CONSOLE_ENABLE
  315. #define DEBUG_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 1)
  316. #define DEBUG_HID_DESC_OFFSET (9+(9+9+7)*DEBUG_HID_DESC_NUM+9)
  317. #else
  318. # define DEBUG_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 0)
  319. #endif
  320. #ifdef EXTRAKEY_ENABLE
  321. # define EXTRA_HID_DESC_NUM (DEBUG_HID_DESC_NUM + 1)
  322. # define EXTRA_HID_DESC_OFFSET (9+(9+9+7)*EXTRA_HID_DESC_NUM+9)
  323. #else
  324. # define EXTRA_HID_DESC_NUM (DEBUG_HID_DESC_NUM + 0)
  325. #endif
  326. #ifdef NKRO_ENABLE
  327. # define KBD2_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 1)
  328. # define KBD2_HID_DESC_OFFSET (9+(9+9+7)*EXTRA_HID_DESC_NUM+9)
  329. #else
  330. # define KBD2_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 0)
  331. #endif
  332. #define NUM_INTERFACES (KBD2_HID_DESC_NUM + 1)
  333. #define CONFIG1_DESC_SIZE (9+(9+9+7)*NUM_INTERFACES)
  334. static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
  335. // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
  336. 9, // bLength;
  337. 2, // bDescriptorType;
  338. LSB(CONFIG1_DESC_SIZE), // wTotalLength
  339. MSB(CONFIG1_DESC_SIZE),
  340. NUM_INTERFACES, // bNumInterfaces
  341. 1, // bConfigurationValue
  342. 0, // iConfiguration
  343. 0xA0, // bmAttributes
  344. 50, // bMaxPower
  345. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  346. 9, // bLength
  347. 4, // bDescriptorType
  348. KBD_INTERFACE, // bInterfaceNumber
  349. 0, // bAlternateSetting
  350. 1, // bNumEndpoints
  351. 0x03, // bInterfaceClass (0x03 = HID)
  352. 0x01, // bInterfaceSubClass (0x01 = Boot)
  353. 0x01, // bInterfaceProtocol (0x01 = Keyboard)
  354. 0, // iInterface
  355. // HID descriptor, HID 1.11 spec, section 6.2.1
  356. 9, // bLength
  357. 0x21, // bDescriptorType
  358. 0x11, 0x01, // bcdHID
  359. 0, // bCountryCode
  360. 1, // bNumDescriptors
  361. 0x22, // bDescriptorType
  362. sizeof(keyboard_hid_report_desc), // wDescriptorLength
  363. 0,
  364. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  365. 7, // bLength
  366. 5, // bDescriptorType
  367. KBD_ENDPOINT | 0x80, // bEndpointAddress
  368. 0x03, // bmAttributes (0x03=intr)
  369. KBD_SIZE, 0, // wMaxPacketSize
  370. 10, // bInterval
  371. #ifdef MOUSE_ENABLE
  372. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  373. 9, // bLength
  374. 4, // bDescriptorType
  375. MOUSE_INTERFACE, // bInterfaceNumber
  376. 0, // bAlternateSetting
  377. 1, // bNumEndpoints
  378. 0x03, // bInterfaceClass (0x03 = HID)
  379. // ThinkPad T23 BIOS doesn't work with boot mouse.
  380. 0x00, // bInterfaceSubClass (0x01 = Boot)
  381. 0x00, // bInterfaceProtocol (0x02 = Mouse)
  382. /*
  383. 0x01, // bInterfaceSubClass (0x01 = Boot)
  384. 0x02, // bInterfaceProtocol (0x02 = Mouse)
  385. */
  386. 0, // iInterface
  387. // HID descriptor, HID 1.11 spec, section 6.2.1
  388. 9, // bLength
  389. 0x21, // bDescriptorType
  390. 0x11, 0x01, // bcdHID
  391. 0, // bCountryCode
  392. 1, // bNumDescriptors
  393. 0x22, // bDescriptorType
  394. sizeof(mouse_hid_report_desc), // wDescriptorLength
  395. 0,
  396. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  397. 7, // bLength
  398. 5, // bDescriptorType
  399. MOUSE_ENDPOINT | 0x80, // bEndpointAddress
  400. 0x03, // bmAttributes (0x03=intr)
  401. MOUSE_SIZE, 0, // wMaxPacketSize
  402. 1, // bInterval
  403. #endif
  404. #ifdef CONSOLE_ENABLE
  405. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  406. 9, // bLength
  407. 4, // bDescriptorType
  408. DEBUG_INTERFACE, // bInterfaceNumber
  409. 0, // bAlternateSetting
  410. 1, // bNumEndpoints
  411. 0x03, // bInterfaceClass (0x03 = HID)
  412. 0x00, // bInterfaceSubClass
  413. 0x00, // bInterfaceProtocol
  414. 0, // iInterface
  415. // HID descriptor, HID 1.11 spec, section 6.2.1
  416. 9, // bLength
  417. 0x21, // bDescriptorType
  418. 0x11, 0x01, // bcdHID
  419. 0, // bCountryCode
  420. 1, // bNumDescriptors
  421. 0x22, // bDescriptorType
  422. sizeof(debug_hid_report_desc), // wDescriptorLength
  423. 0,
  424. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  425. 7, // bLength
  426. 5, // bDescriptorType
  427. DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress
  428. 0x03, // bmAttributes (0x03=intr)
  429. DEBUG_TX_SIZE, 0, // wMaxPacketSize
  430. 1, // bInterval
  431. #endif
  432. #ifdef EXTRAKEY_ENABLE
  433. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  434. 9, // bLength
  435. 4, // bDescriptorType
  436. EXTRA_INTERFACE, // bInterfaceNumber
  437. 0, // bAlternateSetting
  438. 1, // bNumEndpoints
  439. 0x03, // bInterfaceClass (0x03 = HID)
  440. 0x00, // bInterfaceSubClass
  441. 0x00, // bInterfaceProtocol
  442. 0, // iInterface
  443. // HID descriptor, HID 1.11 spec, section 6.2.1
  444. 9, // bLength
  445. 0x21, // bDescriptorType
  446. 0x11, 0x01, // bcdHID
  447. 0, // bCountryCode
  448. 1, // bNumDescriptors
  449. 0x22, // bDescriptorType
  450. sizeof(extra_hid_report_desc), // wDescriptorLength
  451. 0,
  452. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  453. 7, // bLength
  454. 5, // bDescriptorType
  455. EXTRA_ENDPOINT | 0x80, // bEndpointAddress
  456. 0x03, // bmAttributes (0x03=intr)
  457. EXTRA_SIZE, 0, // wMaxPacketSize
  458. 10, // bInterval
  459. #endif
  460. #ifdef NKRO_ENABLE
  461. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  462. 9, // bLength
  463. 4, // bDescriptorType
  464. KBD2_INTERFACE, // bInterfaceNumber
  465. 0, // bAlternateSetting
  466. 1, // bNumEndpoints
  467. 0x03, // bInterfaceClass (0x03 = HID)
  468. 0x00, // bInterfaceSubClass (0x01 = Boot)
  469. 0x00, // bInterfaceProtocol (0x01 = Keyboard)
  470. 0, // iInterface
  471. // HID descriptor, HID 1.11 spec, section 6.2.1
  472. 9, // bLength
  473. 0x21, // bDescriptorType
  474. 0x11, 0x01, // bcdHID
  475. 0, // bCountryCode
  476. 1, // bNumDescriptors
  477. 0x22, // bDescriptorType
  478. sizeof(keyboard2_hid_report_desc), // wDescriptorLength
  479. 0,
  480. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  481. 7, // bLength
  482. 5, // bDescriptorType
  483. KBD2_ENDPOINT | 0x80, // bEndpointAddress
  484. 0x03, // bmAttributes (0x03=intr)
  485. KBD2_SIZE, 0, // wMaxPacketSize
  486. 1, // bInterval
  487. #endif
  488. };
  489. // If you're desperate for a little extra code memory, these strings
  490. // can be completely removed if iManufacturer, iProduct, iSerialNumber
  491. // in the device desciptor are changed to zeros.
  492. struct usb_string_descriptor_struct {
  493. uint8_t bLength;
  494. uint8_t bDescriptorType;
  495. int16_t wString[];
  496. };
  497. static const struct usb_string_descriptor_struct PROGMEM string0 = {
  498. 4,
  499. 3,
  500. {0x0409}
  501. };
  502. static const struct usb_string_descriptor_struct PROGMEM string1 = {
  503. sizeof(STR_MANUFACTURER),
  504. 3,
  505. STR_MANUFACTURER
  506. };
  507. static const struct usb_string_descriptor_struct PROGMEM string2 = {
  508. sizeof(STR_PRODUCT),
  509. 3,
  510. STR_PRODUCT
  511. };
  512. // This table defines which descriptor data is sent for each specific
  513. // request from the host (in wValue and wIndex).
  514. static const struct descriptor_list_struct {
  515. uint16_t wValue; // descriptor type
  516. uint16_t wIndex;
  517. const uint8_t *addr;
  518. uint8_t length;
  519. } PROGMEM descriptor_list[] = {
  520. // DEVICE descriptor
  521. {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
  522. // CONFIGURATION descriptor
  523. {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
  524. // HID/REPORT descriptors
  525. {0x2100, KBD_INTERFACE, config1_descriptor+KBD_HID_DESC_OFFSET, 9},
  526. {0x2200, KBD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
  527. #ifdef MOUSE_ENABLE
  528. {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
  529. {0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
  530. #endif
  531. #ifdef CONSOLE_ENABLE
  532. {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
  533. {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
  534. #endif
  535. #ifdef EXTRAKEY_ENABLE
  536. {0x2100, EXTRA_INTERFACE, config1_descriptor+EXTRA_HID_DESC_OFFSET, 9},
  537. {0x2200, EXTRA_INTERFACE, extra_hid_report_desc, sizeof(extra_hid_report_desc)},
  538. #endif
  539. #ifdef NKRO_ENABLE
  540. {0x2100, KBD2_INTERFACE, config1_descriptor+KBD2_HID_DESC_OFFSET, 9},
  541. {0x2200, KBD2_INTERFACE, keyboard2_hid_report_desc, sizeof(keyboard2_hid_report_desc)},
  542. #endif
  543. // STRING descriptors
  544. {0x0300, 0x0000, (const uint8_t *)&string0, 4},
  545. {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
  546. {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
  547. };
  548. #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
  549. /**************************************************************************
  550. *
  551. * Variables - these are the only non-stack RAM usage
  552. *
  553. **************************************************************************/
  554. // zero when we are not configured, non-zero when enumerated
  555. static volatile uint8_t usb_configuration=0;
  556. /**************************************************************************
  557. *
  558. * Public Functions - these are the API intended for the user
  559. *
  560. **************************************************************************/
  561. // initialize USB
  562. void usb_init(void)
  563. {
  564. HW_CONFIG();
  565. USB_FREEZE(); // enable USB
  566. PLL_CONFIG(); // config PLL
  567. while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
  568. USB_CONFIG(); // start USB clock
  569. UDCON = 0; // enable attach resistor
  570. usb_configuration = 0;
  571. suspend = false;
  572. UDIEN = (1<<EORSTE)|(1<<SOFE)|(1<<SUSPE)|(1<<WAKEUPE);
  573. sei();
  574. }
  575. // return 0 if the USB is not configured, or the configuration
  576. // number selected by the HOST
  577. uint8_t usb_configured(void)
  578. {
  579. return usb_configuration && !suspend;
  580. }
  581. void usb_remote_wakeup(void)
  582. {
  583. UDCON |= (1<<RMWKUP);
  584. }
  585. /**************************************************************************
  586. *
  587. * Private Functions - not intended for general user consumption....
  588. *
  589. **************************************************************************/
  590. // USB Device Interrupt - handle all device-level events
  591. // the transmit buffer flushing is triggered by the start of frame
  592. //
  593. ISR(USB_GEN_vect)
  594. {
  595. uint8_t intbits, t;
  596. static uint8_t div4=0;
  597. intbits = UDINT;
  598. UDINT = 0;
  599. if ((intbits & (1<<SUSPI)) && (UDIEN & (1<<SUSPE)) && usb_configuration) {
  600. #ifdef SLEEP_LED_ENABLE
  601. sleep_led_enable();
  602. #endif
  603. UDIEN &= ~(1<<SUSPE);
  604. UDIEN |= (1<<WAKEUPE);
  605. suspend = true;
  606. }
  607. if ((intbits & (1<<WAKEUPI)) && (UDIEN & (1<<WAKEUPE)) && usb_configuration) {
  608. suspend_wakeup_init();
  609. #ifdef SLEEP_LED_ENABLE
  610. sleep_led_disable();
  611. // NOTE: converters may not accept this
  612. led_set(host_keyboard_leds());
  613. #endif
  614. UDIEN |= (1<<SUSPE);
  615. UDIEN &= ~(1<<WAKEUPE);
  616. suspend = false;
  617. }
  618. if (intbits & (1<<EORSTI)) {
  619. UENUM = 0;
  620. UECONX = 1;
  621. UECFG0X = EP_TYPE_CONTROL;
  622. UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
  623. UEIENX = (1<<RXSTPE);
  624. usb_configuration = 0;
  625. }
  626. if ((intbits & (1<<SOFI)) && usb_configuration) {
  627. t = debug_flush_timer;
  628. if (t) {
  629. debug_flush_timer = -- t;
  630. if (!t) {
  631. UENUM = DEBUG_TX_ENDPOINT;
  632. while ((UEINTX & (1<<RWAL))) {
  633. UEDATX = 0;
  634. }
  635. UEINTX = 0x3A;
  636. }
  637. }
  638. /* TODO: should keep IDLE rate on each keyboard interface */
  639. #ifdef NKRO_ENABLE
  640. if (!keyboard_nkro && usb_keyboard_idle_config && (++div4 & 3) == 0) {
  641. #else
  642. if (usb_keyboard_idle_config && (++div4 & 3) == 0) {
  643. #endif
  644. UENUM = KBD_ENDPOINT;
  645. if (UEINTX & (1<<RWAL)) {
  646. usb_keyboard_idle_count++;
  647. if (usb_keyboard_idle_count == usb_keyboard_idle_config) {
  648. usb_keyboard_idle_count = 0;
  649. /* TODO: fix keyboard_report inconsistency */
  650. /* To avoid Mac SET_IDLE behaviour.
  651. UEDATX = keyboard_report_prev->mods;
  652. UEDATX = 0;
  653. uint8_t keys = usb_keyboard_protocol ? KBD_REPORT_KEYS : 6;
  654. for (uint8_t i=0; i<keys; i++) {
  655. UEDATX = keyboard_report_prev->keys[i];
  656. }
  657. UEINTX = 0x3A;
  658. */
  659. }
  660. }
  661. }
  662. }
  663. }
  664. // Misc functions to wait for ready and send/receive packets
  665. static inline void usb_wait_in_ready(void)
  666. {
  667. while (!(UEINTX & (1<<TXINI))) ;
  668. }
  669. static inline void usb_send_in(void)
  670. {
  671. UEINTX = ~(1<<TXINI);
  672. }
  673. static inline void usb_wait_receive_out(void)
  674. {
  675. while (!(UEINTX & (1<<RXOUTI))) ;
  676. }
  677. static inline void usb_ack_out(void)
  678. {
  679. UEINTX = ~(1<<RXOUTI);
  680. }
  681. // USB Endpoint Interrupt - endpoint 0 is handled here. The
  682. // other endpoints are manipulated by the user-callable
  683. // functions, and the start-of-frame interrupt.
  684. //
  685. ISR(USB_COM_vect)
  686. {
  687. uint8_t intbits;
  688. const uint8_t *list;
  689. const uint8_t *cfg;
  690. uint8_t i, n, len, en;
  691. uint8_t bmRequestType;
  692. uint8_t bRequest;
  693. uint16_t wValue;
  694. uint16_t wIndex;
  695. uint16_t wLength;
  696. uint16_t desc_val;
  697. const uint8_t *desc_addr;
  698. uint8_t desc_length;
  699. UENUM = 0;
  700. intbits = UEINTX;
  701. if (intbits & (1<<RXSTPI)) {
  702. bmRequestType = UEDATX;
  703. bRequest = UEDATX;
  704. wValue = UEDATX;
  705. wValue |= (UEDATX << 8);
  706. wIndex = UEDATX;
  707. wIndex |= (UEDATX << 8);
  708. wLength = UEDATX;
  709. wLength |= (UEDATX << 8);
  710. UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
  711. if (bRequest == GET_DESCRIPTOR) {
  712. list = (const uint8_t *)descriptor_list;
  713. for (i=0; ; i++) {
  714. if (i >= NUM_DESC_LIST) {
  715. UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
  716. return;
  717. }
  718. desc_val = pgm_read_word(list);
  719. if (desc_val != wValue) {
  720. list += sizeof(struct descriptor_list_struct);
  721. continue;
  722. }
  723. list += 2;
  724. desc_val = pgm_read_word(list);
  725. if (desc_val != wIndex) {
  726. list += sizeof(struct descriptor_list_struct)-2;
  727. continue;
  728. }
  729. list += 2;
  730. desc_addr = (const uint8_t *)pgm_read_word(list);
  731. list += 2;
  732. desc_length = pgm_read_byte(list);
  733. break;
  734. }
  735. len = (wLength < 256) ? wLength : 255;
  736. if (len > desc_length) len = desc_length;
  737. do {
  738. // wait for host ready for IN packet
  739. do {
  740. i = UEINTX;
  741. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  742. if (i & (1<<RXOUTI)) return; // abort
  743. // send IN packet
  744. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  745. for (i = n; i; i--) {
  746. UEDATX = pgm_read_byte(desc_addr++);
  747. }
  748. len -= n;
  749. usb_send_in();
  750. } while (len || n == ENDPOINT0_SIZE);
  751. return;
  752. }
  753. if (bRequest == SET_ADDRESS) {
  754. usb_send_in();
  755. usb_wait_in_ready();
  756. UDADDR = wValue | (1<<ADDEN);
  757. return;
  758. }
  759. if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
  760. usb_configuration = wValue;
  761. usb_send_in();
  762. cfg = endpoint_config_table;
  763. for (i=1; i<=MAX_ENDPOINT; i++) {
  764. UENUM = i;
  765. en = pgm_read_byte(cfg++);
  766. if (en) {
  767. UECONX = (1<<EPEN);
  768. UECFG0X = pgm_read_byte(cfg++);
  769. UECFG1X = pgm_read_byte(cfg++);
  770. } else {
  771. UECONX = 0;
  772. }
  773. }
  774. UERST = UERST_MASK;
  775. UERST = 0;
  776. return;
  777. }
  778. if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
  779. usb_wait_in_ready();
  780. UEDATX = usb_configuration;
  781. usb_send_in();
  782. return;
  783. }
  784. if (bRequest == GET_STATUS) {
  785. usb_wait_in_ready();
  786. i = 0;
  787. #ifdef SUPPORT_ENDPOINT_HALT
  788. if (bmRequestType == 0x82) {
  789. UENUM = wIndex;
  790. if (UECONX & (1<<STALLRQ)) i = 1;
  791. UENUM = 0;
  792. }
  793. #endif
  794. UEDATX = i;
  795. UEDATX = 0;
  796. usb_send_in();
  797. return;
  798. }
  799. if (bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE) {
  800. #ifdef SUPPORT_ENDPOINT_HALT
  801. if (bmRequestType == 0x02 && wValue == ENDPOINT_HALT) {
  802. i = wIndex & 0x7F;
  803. if (i >= 1 && i <= MAX_ENDPOINT) {
  804. usb_send_in();
  805. UENUM = i;
  806. if (bRequest == SET_FEATURE) {
  807. UECONX = (1<<STALLRQ)|(1<<EPEN);
  808. } else {
  809. UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
  810. UERST = (1 << i);
  811. UERST = 0;
  812. }
  813. return;
  814. }
  815. }
  816. #endif
  817. if (bmRequestType == 0x00 && wValue == DEVICE_REMOTE_WAKEUP) {
  818. if (bRequest == SET_FEATURE) {
  819. remote_wakeup = true;
  820. } else {
  821. remote_wakeup = false;
  822. }
  823. usb_send_in();
  824. return;
  825. }
  826. }
  827. if (wIndex == KBD_INTERFACE) {
  828. if (bmRequestType == 0xA1) {
  829. if (bRequest == HID_GET_REPORT) {
  830. usb_wait_in_ready();
  831. UEDATX = keyboard_report->mods;
  832. UEDATX = 0;
  833. for (i=0; i<6; i++) {
  834. UEDATX = keyboard_report->keys[i];
  835. }
  836. usb_send_in();
  837. return;
  838. }
  839. if (bRequest == HID_GET_IDLE) {
  840. usb_wait_in_ready();
  841. UEDATX = usb_keyboard_idle_config;
  842. usb_send_in();
  843. return;
  844. }
  845. if (bRequest == HID_GET_PROTOCOL) {
  846. usb_wait_in_ready();
  847. UEDATX = usb_keyboard_protocol;
  848. usb_send_in();
  849. return;
  850. }
  851. }
  852. if (bmRequestType == 0x21) {
  853. if (bRequest == HID_SET_REPORT) {
  854. usb_wait_receive_out();
  855. usb_keyboard_leds = UEDATX;
  856. usb_ack_out();
  857. usb_send_in();
  858. return;
  859. }
  860. if (bRequest == HID_SET_IDLE) {
  861. usb_keyboard_idle_config = (wValue >> 8);
  862. usb_keyboard_idle_count = 0;
  863. //usb_wait_in_ready();
  864. usb_send_in();
  865. return;
  866. }
  867. if (bRequest == HID_SET_PROTOCOL) {
  868. usb_keyboard_protocol = wValue;
  869. //usb_wait_in_ready();
  870. usb_send_in();
  871. return;
  872. }
  873. }
  874. }
  875. #ifdef MOUSE_ENABLE
  876. if (wIndex == MOUSE_INTERFACE) {
  877. if (bmRequestType == 0xA1) {
  878. if (bRequest == HID_GET_REPORT) {
  879. if (wValue == HID_REPORT_INPUT) {
  880. usb_wait_in_ready();
  881. UEDATX = 0;
  882. UEDATX = 0;
  883. UEDATX = 0;
  884. UEDATX = 0;
  885. usb_send_in();
  886. return;
  887. }
  888. if (wValue == HID_REPORT_FEATURE) {
  889. usb_wait_in_ready();
  890. UEDATX = 0x05;
  891. usb_send_in();
  892. return;
  893. }
  894. }
  895. if (bRequest == HID_GET_PROTOCOL) {
  896. usb_wait_in_ready();
  897. UEDATX = usb_mouse_protocol;
  898. usb_send_in();
  899. return;
  900. }
  901. }
  902. if (bmRequestType == 0x21) {
  903. if (bRequest == HID_SET_PROTOCOL) {
  904. usb_mouse_protocol = wValue;
  905. usb_send_in();
  906. return;
  907. }
  908. }
  909. }
  910. #endif
  911. if (wIndex == DEBUG_INTERFACE) {
  912. if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
  913. len = wLength;
  914. do {
  915. // wait for host ready for IN packet
  916. do {
  917. i = UEINTX;
  918. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  919. if (i & (1<<RXOUTI)) return; // abort
  920. // send IN packet
  921. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  922. for (i = n; i; i--) {
  923. UEDATX = 0;
  924. }
  925. len -= n;
  926. usb_send_in();
  927. } while (len || n == ENDPOINT0_SIZE);
  928. return;
  929. }
  930. }
  931. }
  932. UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
  933. }