Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

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