Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

usb.c 33KB

13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  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 USB_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 USB_EXTRA_ENABLE
  86. 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4
  87. #else
  88. 0, // 4
  89. #endif
  90. #ifdef USB_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 USB_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 USB_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. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  201. 0x09, 0x02, // USAGE (Mouse)
  202. 0xa1, 0x01, // COLLECTION (Application)
  203. 0x09, 0x02, // USAGE (Mouse)
  204. 0xa1, 0x02, // COLLECTION (Logical)
  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. // ------------------------------ Padding
  217. 0x75, 0x03, // REPORT_SIZE (3)
  218. 0x95, 0x01, // REPORT_COUNT (1)
  219. 0x81, 0x03, // INPUT (Cnst,Var,Abs)
  220. // ------------------------------ X,Y position
  221. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  222. 0x09, 0x30, // USAGE (X)
  223. 0x09, 0x31, // USAGE (Y)
  224. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  225. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  226. 0x75, 0x08, // REPORT_SIZE (8)
  227. 0x95, 0x02, // REPORT_COUNT (2)
  228. 0x81, 0x06, // INPUT (Data,Var,Rel)
  229. 0xa1, 0x02, // COLLECTION (Logical)
  230. // ------------------------------ Vertical wheel res multiplier
  231. 0x09, 0x48, // USAGE (Resolution Multiplier)
  232. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  233. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  234. 0x35, 0x01, // PHYSICAL_MINIMUM (1)
  235. 0x45, 0x04, // PHYSICAL_MAXIMUM (4)
  236. 0x75, 0x02, // REPORT_SIZE (2)
  237. 0x95, 0x01, // REPORT_COUNT (1)
  238. 0xa4, // PUSH
  239. 0xb1, 0x02, // FEATURE (Data,Var,Abs)
  240. // ------------------------------ Vertical wheel
  241. 0x09, 0x38, // USAGE (Wheel)
  242. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  243. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  244. 0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical
  245. 0x45, 0x00, // PHYSICAL_MAXIMUM (0)
  246. 0x75, 0x08, // REPORT_SIZE (8)
  247. 0x81, 0x06, // INPUT (Data,Var,Rel)
  248. 0xc0, // END_COLLECTION
  249. 0xa1, 0x02, // COLLECTION (Logical)
  250. // ------------------------------ Horizontal wheel res multiplier
  251. 0x09, 0x48, // USAGE (Resolution Multiplier)
  252. 0xb4, // POP
  253. 0xb1, 0x02, // FEATURE (Data,Var,Abs)
  254. // ------------------------------ Padding for Feature report
  255. 0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical
  256. 0x45, 0x00, // PHYSICAL_MAXIMUM (0)
  257. 0x75, 0x04, // REPORT_SIZE (4)
  258. 0xb1, 0x03, // FEATURE (Cnst,Var,Abs)
  259. // ------------------------------ Horizontal wheel
  260. 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
  261. 0x0a, 0x38, 0x02, // USAGE (AC Pan)
  262. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  263. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  264. 0x75, 0x08, // REPORT_SIZE (8)
  265. 0x81, 0x06, // INPUT (Data,Var,Rel)
  266. 0xc0, // END_COLLECTION
  267. 0xc0, // END_COLLECTION
  268. 0xc0, // END_COLLECTION
  269. 0xc0 // END_COLLECTION
  270. };
  271. #endif
  272. static uint8_t PROGMEM debug_hid_report_desc[] = {
  273. 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
  274. 0x09, 0x74, // Usage 0x74
  275. 0xA1, 0x53, // Collection 0x53
  276. 0x75, 0x08, // report size = 8 bits
  277. 0x15, 0x00, // logical minimum = 0
  278. 0x26, 0xFF, 0x00, // logical maximum = 255
  279. 0x95, DEBUG_TX_SIZE, // report count
  280. 0x09, 0x75, // usage
  281. 0x81, 0x02, // Input (array)
  282. 0xC0 // end collection
  283. };
  284. #ifdef USB_EXTRA_ENABLE
  285. // audio controls & system controls
  286. // http://www.microsoft.com/whdc/archive/w2kbd.mspx
  287. static uint8_t PROGMEM extra_hid_report_desc[] = {
  288. 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
  289. 0x09, 0x01, // USAGE (Consumer Control)
  290. 0xa1, 0x01, // COLLECTION (Application)
  291. 0x85, 0x01, // REPORT_ID (1)
  292. 0x09, 0xe9, // USAGE (Volume Up)
  293. 0x09, 0xea, // USAGE (Volume Down)
  294. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  295. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  296. 0x75, 0x01, // REPORT_SIZE (1)
  297. 0x95, 0x02, // REPORT_COUNT (2)
  298. 0x81, 0x02, // INPUT (Data,Var,Abs)
  299. 0x09, 0xe2, // USAGE (Mute)
  300. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  301. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  302. 0x75, 0x01, // REPORT_SIZE (1)
  303. 0x95, 0x01, // REPORT_COUNT (1)
  304. 0x81, 0x06, // INPUT (Data,Var,Rel)
  305. 0x95, 0x05, // REPORT_COUNT (5)
  306. 0x81, 0x07, // INPUT (Cnst,Var,Abs)
  307. 0xc0, // END_COLLECTION
  308. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  309. 0x09, 0x80, // USAGE (System Control)
  310. 0xa1, 0x01, // COLLECTION (Application)
  311. 0x85, 0x02, // REPORT_ID (2)
  312. 0x19, 0x81, // USAGE_MINIMUM (System Power Down)
  313. 0x29, 0x83, // USAGE_MAXIMUM (System Wake Up)
  314. 0x95, 0x03, // REPORT_COUNT (3)
  315. 0x81, 0x06, // INPUT (Data,Var,Rel)
  316. 0x95, 0x05, // REPORT_COUNT (5)
  317. 0x81, 0x07, // INPUT (Cnst,Var,Rel)
  318. 0xc0 // END_COLLECTION
  319. };
  320. #endif
  321. #define KBD_HID_DESC_NUM 0
  322. #define KBD_HID_DESC_OFFSET (9+(9+9+7)*KBD_HID_DESC_NUM+9)
  323. #ifdef USB_MOUSE_ENABLE
  324. # define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 1)
  325. # define MOUSE_HID_DESC_OFFSET (9+(9+9+7)*MOUSE_HID_DESC_NUM+9)
  326. #else
  327. # define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 0)
  328. #endif
  329. #define DEBUG_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 1)
  330. #define DEBUG_HID_DESC_OFFSET (9+(9+9+7)*DEBUG_HID_DESC_NUM+9)
  331. #ifdef USB_EXTRA_ENABLE
  332. # define EXTRA_HID_DESC_NUM (DEBUG_HID_DESC_NUM + 1)
  333. # define EXTRA_HID_DESC_OFFSET (9+(9+9+7)*EXTRA_HID_DESC_NUM+9)
  334. #else
  335. # define EXTRA_HID_DESC_NUM (DEBUG_HID_DESC_NUM + 0)
  336. #endif
  337. #ifdef USB_NKRO_ENABLE
  338. # define KBD2_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 1)
  339. # define KBD2_HID_DESC_OFFSET (9+(9+9+7)*EXTRA_HID_DESC_NUM+9)
  340. #else
  341. # define KBD2_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 0)
  342. #endif
  343. #define NUM_INTERFACES (KBD2_HID_DESC_NUM + 1)
  344. #define CONFIG1_DESC_SIZE (9+(9+9+7)*NUM_INTERFACES)
  345. static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
  346. // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
  347. 9, // bLength;
  348. 2, // bDescriptorType;
  349. LSB(CONFIG1_DESC_SIZE), // wTotalLength
  350. MSB(CONFIG1_DESC_SIZE),
  351. NUM_INTERFACES, // bNumInterfaces
  352. 1, // bConfigurationValue
  353. 0, // iConfiguration
  354. 0xA0, // bmAttributes
  355. 50, // bMaxPower
  356. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  357. 9, // bLength
  358. 4, // bDescriptorType
  359. KBD_INTERFACE, // bInterfaceNumber
  360. 0, // bAlternateSetting
  361. 1, // bNumEndpoints
  362. 0x03, // bInterfaceClass (0x03 = HID)
  363. 0x01, // bInterfaceSubClass (0x01 = Boot)
  364. 0x01, // bInterfaceProtocol (0x01 = Keyboard)
  365. 0, // iInterface
  366. // HID descriptor, HID 1.11 spec, section 6.2.1
  367. 9, // bLength
  368. 0x21, // bDescriptorType
  369. 0x11, 0x01, // bcdHID
  370. 0, // bCountryCode
  371. 1, // bNumDescriptors
  372. 0x22, // bDescriptorType
  373. sizeof(keyboard_hid_report_desc), // wDescriptorLength
  374. 0,
  375. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  376. 7, // bLength
  377. 5, // bDescriptorType
  378. KBD_ENDPOINT | 0x80, // bEndpointAddress
  379. 0x03, // bmAttributes (0x03=intr)
  380. KBD_SIZE, 0, // wMaxPacketSize
  381. 10, // bInterval
  382. #ifdef USB_MOUSE_ENABLE
  383. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  384. 9, // bLength
  385. 4, // bDescriptorType
  386. MOUSE_INTERFACE, // bInterfaceNumber
  387. 0, // bAlternateSetting
  388. 1, // bNumEndpoints
  389. 0x03, // bInterfaceClass (0x03 = HID)
  390. // ThinkPad T23 BIOS doesn't work with boot mouse.
  391. 0x00, // bInterfaceSubClass (0x01 = Boot)
  392. 0x00, // bInterfaceProtocol (0x02 = Mouse)
  393. /*
  394. 0x01, // bInterfaceSubClass (0x01 = Boot)
  395. 0x02, // bInterfaceProtocol (0x02 = Mouse)
  396. */
  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(mouse_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. MOUSE_ENDPOINT | 0x80, // bEndpointAddress
  411. 0x03, // bmAttributes (0x03=intr)
  412. MOUSE_SIZE, 0, // wMaxPacketSize
  413. 1, // bInterval
  414. #endif
  415. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  416. 9, // bLength
  417. 4, // bDescriptorType
  418. DEBUG_INTERFACE, // bInterfaceNumber
  419. 0, // bAlternateSetting
  420. 1, // bNumEndpoints
  421. 0x03, // bInterfaceClass (0x03 = HID)
  422. 0x00, // bInterfaceSubClass
  423. 0x00, // bInterfaceProtocol
  424. 0, // iInterface
  425. // HID descriptor, HID 1.11 spec, section 6.2.1
  426. 9, // bLength
  427. 0x21, // bDescriptorType
  428. 0x11, 0x01, // bcdHID
  429. 0, // bCountryCode
  430. 1, // bNumDescriptors
  431. 0x22, // bDescriptorType
  432. sizeof(debug_hid_report_desc), // wDescriptorLength
  433. 0,
  434. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  435. 7, // bLength
  436. 5, // bDescriptorType
  437. DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress
  438. 0x03, // bmAttributes (0x03=intr)
  439. DEBUG_TX_SIZE, 0, // wMaxPacketSize
  440. 1, // bInterval
  441. #ifdef USB_EXTRA_ENABLE
  442. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  443. 9, // bLength
  444. 4, // bDescriptorType
  445. EXTRA_INTERFACE, // bInterfaceNumber
  446. 0, // bAlternateSetting
  447. 1, // bNumEndpoints
  448. 0x03, // bInterfaceClass (0x03 = HID)
  449. 0x00, // bInterfaceSubClass
  450. 0x00, // bInterfaceProtocol
  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(extra_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. EXTRA_ENDPOINT | 0x80, // bEndpointAddress
  465. 0x03, // bmAttributes (0x03=intr)
  466. EXTRA_SIZE, 0, // wMaxPacketSize
  467. 10, // bInterval
  468. #endif
  469. #ifdef USB_NKRO_ENABLE
  470. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  471. 9, // bLength
  472. 4, // bDescriptorType
  473. KBD2_INTERFACE, // bInterfaceNumber
  474. 0, // bAlternateSetting
  475. 1, // bNumEndpoints
  476. 0x03, // bInterfaceClass (0x03 = HID)
  477. 0x00, // bInterfaceSubClass (0x01 = Boot)
  478. 0x00, // bInterfaceProtocol (0x01 = Keyboard)
  479. 0, // iInterface
  480. // HID descriptor, HID 1.11 spec, section 6.2.1
  481. 9, // bLength
  482. 0x21, // bDescriptorType
  483. 0x11, 0x01, // bcdHID
  484. 0, // bCountryCode
  485. 1, // bNumDescriptors
  486. 0x22, // bDescriptorType
  487. sizeof(keyboard2_hid_report_desc), // wDescriptorLength
  488. 0,
  489. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  490. 7, // bLength
  491. 5, // bDescriptorType
  492. KBD2_ENDPOINT | 0x80, // bEndpointAddress
  493. 0x03, // bmAttributes (0x03=intr)
  494. KBD2_SIZE, 0, // wMaxPacketSize
  495. 1, // bInterval
  496. #endif
  497. };
  498. // If you're desperate for a little extra code memory, these strings
  499. // can be completely removed if iManufacturer, iProduct, iSerialNumber
  500. // in the device desciptor are changed to zeros.
  501. struct usb_string_descriptor_struct {
  502. uint8_t bLength;
  503. uint8_t bDescriptorType;
  504. int16_t wString[];
  505. };
  506. static struct usb_string_descriptor_struct PROGMEM string0 = {
  507. 4,
  508. 3,
  509. {0x0409}
  510. };
  511. static struct usb_string_descriptor_struct PROGMEM string1 = {
  512. sizeof(STR_MANUFACTURER),
  513. 3,
  514. STR_MANUFACTURER
  515. };
  516. static struct usb_string_descriptor_struct PROGMEM string2 = {
  517. sizeof(STR_PRODUCT),
  518. 3,
  519. STR_PRODUCT
  520. };
  521. // This table defines which descriptor data is sent for each specific
  522. // request from the host (in wValue and wIndex).
  523. static struct descriptor_list_struct {
  524. uint16_t wValue; // descriptor type
  525. uint16_t wIndex;
  526. const uint8_t *addr;
  527. uint8_t length;
  528. } PROGMEM descriptor_list[] = {
  529. // DEVICE descriptor
  530. {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
  531. // CONFIGURATION descriptor
  532. {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
  533. // HID/REPORT descriptors
  534. {0x2100, KBD_INTERFACE, config1_descriptor+KBD_HID_DESC_OFFSET, 9},
  535. {0x2200, KBD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
  536. #ifdef USB_MOUSE_ENABLE
  537. {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
  538. {0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
  539. #endif
  540. {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
  541. {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
  542. #ifdef USB_EXTRA_ENABLE
  543. {0x2100, EXTRA_INTERFACE, config1_descriptor+EXTRA_HID_DESC_OFFSET, 9},
  544. {0x2200, EXTRA_INTERFACE, extra_hid_report_desc, sizeof(extra_hid_report_desc)},
  545. #endif
  546. #ifdef USB_NKRO_ENABLE
  547. {0x2100, KBD2_INTERFACE, config1_descriptor+KBD2_HID_DESC_OFFSET, 9},
  548. {0x2200, KBD2_INTERFACE, keyboard2_hid_report_desc, sizeof(keyboard2_hid_report_desc)},
  549. #endif
  550. // STRING descriptors
  551. {0x0300, 0x0000, (const uint8_t *)&string0, 4},
  552. {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
  553. {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
  554. };
  555. #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
  556. /**************************************************************************
  557. *
  558. * Variables - these are the only non-stack RAM usage
  559. *
  560. **************************************************************************/
  561. // zero when we are not configured, non-zero when enumerated
  562. static volatile uint8_t usb_configuration=0;
  563. /**************************************************************************
  564. *
  565. * Public Functions - these are the API intended for the user
  566. *
  567. **************************************************************************/
  568. // initialize USB
  569. void usb_init(void)
  570. {
  571. HW_CONFIG();
  572. USB_FREEZE(); // enable USB
  573. PLL_CONFIG(); // config PLL
  574. while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
  575. USB_CONFIG(); // start USB clock
  576. UDCON = 0; // enable attach resistor
  577. usb_configuration = 0;
  578. UDIEN = (1<<EORSTE)|(1<<SOFE)|(1<<SUSPE);
  579. sei();
  580. }
  581. // return 0 if the USB is not configured, or the configuration
  582. // number selected by the HOST
  583. uint8_t usb_configured(void)
  584. {
  585. return usb_configuration && !suspend;
  586. }
  587. void usb_remote_wakeup(void)
  588. {
  589. UDCON |= (1<<RMWKUP);
  590. }
  591. /**************************************************************************
  592. *
  593. * Private Functions - not intended for general user consumption....
  594. *
  595. **************************************************************************/
  596. // USB Device Interrupt - handle all device-level events
  597. // the transmit buffer flushing is triggered by the start of frame
  598. //
  599. ISR(USB_GEN_vect)
  600. {
  601. uint8_t intbits, t, i;
  602. static uint8_t div4=0;
  603. intbits = UDINT;
  604. UDINT = 0;
  605. if (intbits & (1<<SUSPI)) {
  606. suspend = true;
  607. } else {
  608. suspend = false;
  609. }
  610. if (intbits & (1<<EORSTI)) {
  611. UENUM = 0;
  612. UECONX = 1;
  613. UECFG0X = EP_TYPE_CONTROL;
  614. UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
  615. UEIENX = (1<<RXSTPE);
  616. usb_configuration = 0;
  617. }
  618. if ((intbits & (1<<SOFI)) && usb_configuration) {
  619. t = debug_flush_timer;
  620. if (t) {
  621. debug_flush_timer = -- t;
  622. if (!t) {
  623. UENUM = DEBUG_TX_ENDPOINT;
  624. while ((UEINTX & (1<<RWAL))) {
  625. UEDATX = 0;
  626. }
  627. UEINTX = 0x3A;
  628. }
  629. }
  630. if (usb_keyboard_idle_config && (++div4 & 3) == 0) {
  631. UENUM = KBD_ENDPOINT;
  632. if (UEINTX & (1<<RWAL)) {
  633. usb_keyboard_idle_count++;
  634. if (usb_keyboard_idle_count == usb_keyboard_idle_config) {
  635. usb_keyboard_idle_count = 0;
  636. UEDATX = usb_keyboard_mods;
  637. UEDATX = 0;
  638. for (i=0; i<6; i++) {
  639. UEDATX = usb_keyboard_keys[i];
  640. }
  641. UEINTX = 0x3A;
  642. }
  643. }
  644. }
  645. }
  646. }
  647. // Misc functions to wait for ready and send/receive packets
  648. static inline void usb_wait_in_ready(void)
  649. {
  650. while (!(UEINTX & (1<<TXINI))) ;
  651. }
  652. static inline void usb_send_in(void)
  653. {
  654. UEINTX = ~(1<<TXINI);
  655. }
  656. static inline void usb_wait_receive_out(void)
  657. {
  658. while (!(UEINTX & (1<<RXOUTI))) ;
  659. }
  660. static inline void usb_ack_out(void)
  661. {
  662. UEINTX = ~(1<<RXOUTI);
  663. }
  664. // USB Endpoint Interrupt - endpoint 0 is handled here. The
  665. // other endpoints are manipulated by the user-callable
  666. // functions, and the start-of-frame interrupt.
  667. //
  668. ISR(USB_COM_vect)
  669. {
  670. uint8_t intbits;
  671. const uint8_t *list;
  672. const uint8_t *cfg;
  673. uint8_t i, n, len, en;
  674. uint8_t bmRequestType;
  675. uint8_t bRequest;
  676. uint16_t wValue;
  677. uint16_t wIndex;
  678. uint16_t wLength;
  679. uint16_t desc_val;
  680. const uint8_t *desc_addr;
  681. uint8_t desc_length;
  682. UENUM = 0;
  683. intbits = UEINTX;
  684. if (intbits & (1<<RXSTPI)) {
  685. bmRequestType = UEDATX;
  686. bRequest = UEDATX;
  687. wValue = UEDATX;
  688. wValue |= (UEDATX << 8);
  689. wIndex = UEDATX;
  690. wIndex |= (UEDATX << 8);
  691. wLength = UEDATX;
  692. wLength |= (UEDATX << 8);
  693. UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
  694. if (bRequest == GET_DESCRIPTOR) {
  695. list = (const uint8_t *)descriptor_list;
  696. for (i=0; ; i++) {
  697. if (i >= NUM_DESC_LIST) {
  698. UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
  699. return;
  700. }
  701. desc_val = pgm_read_word(list);
  702. if (desc_val != wValue) {
  703. list += sizeof(struct descriptor_list_struct);
  704. continue;
  705. }
  706. list += 2;
  707. desc_val = pgm_read_word(list);
  708. if (desc_val != wIndex) {
  709. list += sizeof(struct descriptor_list_struct)-2;
  710. continue;
  711. }
  712. list += 2;
  713. desc_addr = (const uint8_t *)pgm_read_word(list);
  714. list += 2;
  715. desc_length = pgm_read_byte(list);
  716. break;
  717. }
  718. len = (wLength < 256) ? wLength : 255;
  719. if (len > desc_length) len = desc_length;
  720. do {
  721. // wait for host ready for IN packet
  722. do {
  723. i = UEINTX;
  724. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  725. if (i & (1<<RXOUTI)) return; // abort
  726. // send IN packet
  727. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  728. for (i = n; i; i--) {
  729. UEDATX = pgm_read_byte(desc_addr++);
  730. }
  731. len -= n;
  732. usb_send_in();
  733. } while (len || n == ENDPOINT0_SIZE);
  734. return;
  735. }
  736. if (bRequest == SET_ADDRESS) {
  737. usb_send_in();
  738. usb_wait_in_ready();
  739. UDADDR = wValue | (1<<ADDEN);
  740. return;
  741. }
  742. if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
  743. usb_configuration = wValue;
  744. usb_send_in();
  745. cfg = endpoint_config_table;
  746. for (i=1; i<=6; i++) {
  747. UENUM = i;
  748. en = pgm_read_byte(cfg++);
  749. if (en) {
  750. UECONX = (1<<EPEN);
  751. UECFG0X = pgm_read_byte(cfg++);
  752. UECFG1X = pgm_read_byte(cfg++);
  753. } else {
  754. UECONX = 0;
  755. }
  756. }
  757. UERST = 0x7E;
  758. UERST = 0;
  759. return;
  760. }
  761. if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
  762. usb_wait_in_ready();
  763. UEDATX = usb_configuration;
  764. usb_send_in();
  765. return;
  766. }
  767. if (bRequest == GET_STATUS) {
  768. usb_wait_in_ready();
  769. i = 0;
  770. #ifdef SUPPORT_ENDPOINT_HALT
  771. if (bmRequestType == 0x82) {
  772. UENUM = wIndex;
  773. if (UECONX & (1<<STALLRQ)) i = 1;
  774. UENUM = 0;
  775. }
  776. #endif
  777. UEDATX = i;
  778. UEDATX = 0;
  779. usb_send_in();
  780. return;
  781. }
  782. if (bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE) {
  783. #ifdef SUPPORT_ENDPOINT_HALT
  784. if (bmRequestType == 0x02 && wValue == ENDPOINT_HALT) {
  785. i = wIndex & 0x7F;
  786. if (i >= 1 && i <= MAX_ENDPOINT) {
  787. usb_send_in();
  788. UENUM = i;
  789. if (bRequest == SET_FEATURE) {
  790. UECONX = (1<<STALLRQ)|(1<<EPEN);
  791. } else {
  792. UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
  793. UERST = (1 << i);
  794. UERST = 0;
  795. }
  796. return;
  797. }
  798. }
  799. #endif
  800. if (bmRequestType == 0x00 && wValue == DEVICE_REMOTE_WAKEUP) {
  801. if (bRequest == SET_FEATURE) {
  802. remote_wakeup = true;
  803. } else {
  804. remote_wakeup = false;
  805. }
  806. usb_send_in();
  807. return;
  808. }
  809. }
  810. if (wIndex == KBD_INTERFACE) {
  811. if (bmRequestType == 0xA1) {
  812. if (bRequest == HID_GET_REPORT) {
  813. usb_wait_in_ready();
  814. UEDATX = usb_keyboard_mods;
  815. UEDATX = 0;
  816. for (i=0; i<6; i++) {
  817. UEDATX = usb_keyboard_keys[i];
  818. }
  819. usb_send_in();
  820. return;
  821. }
  822. if (bRequest == HID_GET_IDLE) {
  823. usb_wait_in_ready();
  824. UEDATX = usb_keyboard_idle_config;
  825. usb_send_in();
  826. return;
  827. }
  828. if (bRequest == HID_GET_PROTOCOL) {
  829. usb_wait_in_ready();
  830. UEDATX = usb_keyboard_protocol;
  831. usb_send_in();
  832. return;
  833. }
  834. }
  835. if (bmRequestType == 0x21) {
  836. if (bRequest == HID_SET_REPORT) {
  837. usb_wait_receive_out();
  838. usb_keyboard_leds = UEDATX;
  839. usb_ack_out();
  840. usb_send_in();
  841. return;
  842. }
  843. if (bRequest == HID_SET_IDLE) {
  844. usb_keyboard_idle_config = (wValue >> 8);
  845. usb_keyboard_idle_count = 0;
  846. //usb_wait_in_ready();
  847. usb_send_in();
  848. return;
  849. }
  850. if (bRequest == HID_SET_PROTOCOL) {
  851. usb_keyboard_protocol = wValue;
  852. //usb_wait_in_ready();
  853. usb_send_in();
  854. return;
  855. }
  856. }
  857. }
  858. #ifdef USB_MOUSE_ENABLE
  859. if (wIndex == MOUSE_INTERFACE) {
  860. if (bmRequestType == 0xA1) {
  861. if (bRequest == HID_GET_REPORT) {
  862. if (wValue == HID_REPORT_INPUT) {
  863. usb_wait_in_ready();
  864. UEDATX = 0;
  865. UEDATX = 0;
  866. UEDATX = 0;
  867. UEDATX = 0;
  868. usb_send_in();
  869. return;
  870. }
  871. if (wValue == HID_REPORT_FEATURE) {
  872. usb_wait_in_ready();
  873. UEDATX = 0x05;
  874. usb_send_in();
  875. return;
  876. }
  877. }
  878. if (bRequest == HID_GET_PROTOCOL) {
  879. usb_wait_in_ready();
  880. UEDATX = usb_mouse_protocol;
  881. usb_send_in();
  882. return;
  883. }
  884. }
  885. if (bmRequestType == 0x21) {
  886. if (bRequest == HID_SET_PROTOCOL) {
  887. usb_mouse_protocol = wValue;
  888. usb_send_in();
  889. return;
  890. }
  891. }
  892. }
  893. #endif
  894. if (wIndex == DEBUG_INTERFACE) {
  895. if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
  896. len = wLength;
  897. do {
  898. // wait for host ready for IN packet
  899. do {
  900. i = UEINTX;
  901. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  902. if (i & (1<<RXOUTI)) return; // abort
  903. // send IN packet
  904. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  905. for (i = n; i; i--) {
  906. UEDATX = 0;
  907. }
  908. len -= n;
  909. usb_send_in();
  910. } while (len || n == ENDPOINT0_SIZE);
  911. return;
  912. }
  913. }
  914. }
  915. UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
  916. }