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 32KB

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