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