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