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.

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