Keyboard firmwares for Atmel AVR and Cortex-M
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.

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