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_main.c 50KB

Squashed 'tmk_core/' changes from 57d27a8..08ce4c3 08ce4c3 Add update for chibios in README 30cac1d Merge remote-tracking branch 'flabbergast-tmk_keyboard/chibios' f218a38 core: Remove unused warning. Fix tmk_keyboard/#293 3e68807 Chibios: add more guards for transmitting (fix a deadlock bug). cecc807 core: Speed up compilation d01d959 Merge remote-tracking branch 'upstream/master' into chibios 8ff12ae Merge pull request #230 from jerryen/master 3afb83d core: Add note about sudo and git 2525d5d Chibios: Update to new USB API. 2fc5cd6 Merge branch 'master' into chibios 6f5511a core: Fix variable initialize 02a15fa core: Fix variable init and header include 1833ca1 Merge pull request #292 from obones/command_warning bc9dc6f Merge pull request #294 from shayneholmes/fix-debug-message c1b891b Merge pull request #295 from doopai/master 1da837c core: Add macro commands SM(), RM() and CM() d9d5a93 Add support for storing, restoring and clearing modifiers in macros 4f371c0 core: Add dfu-programmer example to doc/build.md ba3792e core: Fix doc/build.md 4b99fed remove SERIAL_SOFT_DEBUG macro 984accb Fix typo in bootmagic debug message 67a7ea1 usb_usb: Fix for keymap editor 2fc9ae4 host_driver is only used if KEYBOARD_LOCK_ENABLE is defined a35cdea Chibios: add 'core/protocol' to the makefiles' search path. 5ed2fd6 Merge remote-tracking branch 'upstream/master' into chibios bbc4851 Do timeout when writing to CONSOLE EP queue. 2450559 Remove an errant comma trailing the KC_ERAS macro alias 8465747 Merge pull request #270 from jeffgran/single-tap-toggle a37339a Merge pull request #271 from jeffgran/default-layer-toggle 8e732f7 core: Update doc/build.md and remove other_projects.md e47dc15 Workaround for compiler warnings when console disabled. 4184c52 Add maple mini code. b555238 core: Fix rules.mk for dfu target 26dacf4 add ACTION_DEFAULT_LAYER_TOGGLE to toggle a default layer on/off 83607d9 enable TAPPING_TOGGLE=1 to work correctly bef3089 Merge branch 'master' into chibios f7a55fd core: Fix debug print of usb_hid 1402f7d core: Add keycode KC_JPY for JIS 8e3a460 Chibios: Remove the wait in the main loop. 7d41746 ChibiOS: prettify/document sleep_led code. 235cdee ChibiOS: Update infinity bootloader code to match updated ChibiOS. 807bf1e Chibios: Add breathing sleep LED on Kinetis MCUs. ba3bf7c ChibiOS: make reset request more CMSISy. bf2ffd4 Add correct chibios/bootloader_jump for infinity KB. f5e03fd Chibios/usb_main: rename a variable for clarity. 63a330c Fix drop key stroke d8f5b06 Fix report size of boot protocol. 38abb50 ChibiOS/STM32: send remote wakeup. 6725650 ChibiOS/kinetis: sending remote wakeup. 69f6e54 Chibios: use WFI in idle. WIP suspend stuff. 02f044b Move chibios/cortex selection to local Makefiles. fa59dfa Rename chibios example keyboard. 5c060de Add eeprom support for chibios/kinetis. efd0044 Move declaration of keymap_config. 7196b24 Make bootmagic.c code portable (_delay_ms -> wait_ms). 37b15b2 Add missing #include to keymap.c. 31316e3 Merge branch 'master' into chibios 166f312 Fix chibios/usb_main GET_REPORT handing. 57ac6c2 Add ARM Teensies bootloader code. 1758086 Move STM32 bootloader address config to separate .h file. 03bb026 Rename some Makefile defines. 76ba6ac NKRO fixes. 06498f8 Update chibios README. db0a4f5 Add basic sleep_led for chibios. c3f930e Move AVR specific sleep_led.c into avr. 4069494 Fix bootloader-jump compiling. 9117f7b Small updates. 269cb85 Implement jump-to-bootloader. 7e81b34 Move chibios to tool. 923a892 Make usb_main more USB_DRIVER #define independent. aa054f0 Add ChibiOS support (USB stack + support files). 1e3e282 Modularity and gcc warnings fixes. 2f60ce0 Add KEYBOARD_LOCK_ENABLE to makefile git-subtree-dir: tmk_core git-subtree-split: 08ce4c3021d2ecd446c5b9a137aded65423d241e
8 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372
  1. /*
  2. * (c) 2015 flabberast <[email protected]>
  3. *
  4. * Based on the following work:
  5. * - Guillaume Duc's raw hid example (MIT License)
  6. * https://github.com/guiduc/usb-hid-chibios-example
  7. * - PJRC Teensy examples (MIT License)
  8. * https://www.pjrc.com/teensy/usb_keyboard.html
  9. * - hasu's TMK keyboard code (GPL v2 and some code Modified BSD)
  10. * https://github.com/tmk/tmk_keyboard/
  11. * - ChibiOS demo code (Apache 2.0 License)
  12. * http://www.chibios.org
  13. *
  14. * Since some GPL'd code is used, this work is licensed under
  15. * GPL v2 or later.
  16. */
  17. #include "ch.h"
  18. #include "hal.h"
  19. #include "usb_main.h"
  20. #include "host.h"
  21. #include "debug.h"
  22. #include "suspend.h"
  23. #ifdef SLEEP_LED_ENABLE
  24. #include "sleep_led.h"
  25. #include "led.h"
  26. #endif
  27. /* ---------------------------------------------------------
  28. * Global interface variables and declarations
  29. * ---------------------------------------------------------
  30. */
  31. uint8_t keyboard_idle = 0;
  32. uint8_t keyboard_protocol = 1;
  33. uint16_t keyboard_led_stats = 0;
  34. volatile uint16_t keyboard_idle_count = 0;
  35. static virtual_timer_t keyboard_idle_timer;
  36. static void keyboard_idle_timer_cb(void *arg);
  37. #ifdef NKRO_ENABLE
  38. extern bool keyboard_nkro;
  39. #endif /* NKRO_ENABLE */
  40. report_keyboard_t keyboard_report_sent = {{0}};
  41. #ifdef MOUSE_ENABLE
  42. report_mouse_t mouse_report_blank = {0};
  43. #endif /* MOUSE_ENABLE */
  44. #ifdef EXTRAKEY_ENABLE
  45. uint8_t extra_report_blank[3] = {0};
  46. #endif /* EXTRAKEY_ENABLE */
  47. #ifdef CONSOLE_ENABLE
  48. /* The emission buffers queue */
  49. output_buffers_queue_t console_buf_queue;
  50. static uint8_t console_queue_buffer[BQ_BUFFER_SIZE(CONSOLE_QUEUE_CAPACITY, CONSOLE_EPSIZE)];
  51. static virtual_timer_t console_flush_timer;
  52. void console_queue_onotify(io_buffers_queue_t *bqp);
  53. static void console_flush_cb(void *arg);
  54. #endif /* CONSOLE_ENABLE */
  55. /* ---------------------------------------------------------
  56. * Descriptors and USB driver objects
  57. * ---------------------------------------------------------
  58. */
  59. /* HID specific constants */
  60. #define USB_DESCRIPTOR_HID 0x21
  61. #define USB_DESCRIPTOR_HID_REPORT 0x22
  62. #define HID_GET_REPORT 0x01
  63. #define HID_GET_IDLE 0x02
  64. #define HID_GET_PROTOCOL 0x03
  65. #define HID_SET_REPORT 0x09
  66. #define HID_SET_IDLE 0x0A
  67. #define HID_SET_PROTOCOL 0x0B
  68. /* USB Device Descriptor */
  69. static const uint8_t usb_device_descriptor_data[] = {
  70. USB_DESC_DEVICE(0x0200, // bcdUSB (1.1)
  71. 0, // bDeviceClass (defined in later in interface)
  72. 0, // bDeviceSubClass
  73. 0, // bDeviceProtocol
  74. 64, // bMaxPacketSize (64 bytes) (the driver didn't work with 32)
  75. VENDOR_ID, // idVendor
  76. PRODUCT_ID, // idProduct
  77. DEVICE_VER, // bcdDevice
  78. 1, // iManufacturer
  79. 2, // iProduct
  80. 3, // iSerialNumber
  81. 1) // bNumConfigurations
  82. };
  83. /* Device Descriptor wrapper */
  84. static const USBDescriptor usb_device_descriptor = {
  85. sizeof usb_device_descriptor_data,
  86. usb_device_descriptor_data
  87. };
  88. /*
  89. * HID Report Descriptor
  90. *
  91. * See "Device Class Definition for Human Interface Devices (HID)"
  92. * (http://www.usb.org/developers/hidpage/HID1_11.pdf) for the
  93. * detailed descrition of all the fields
  94. */
  95. /* Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 */
  96. static const uint8_t keyboard_hid_report_desc_data[] = {
  97. 0x05, 0x01, // Usage Page (Generic Desktop),
  98. 0x09, 0x06, // Usage (Keyboard),
  99. 0xA1, 0x01, // Collection (Application),
  100. 0x75, 0x01, // Report Size (1),
  101. 0x95, 0x08, // Report Count (8),
  102. 0x05, 0x07, // Usage Page (Key Codes),
  103. 0x19, 0xE0, // Usage Minimum (224),
  104. 0x29, 0xE7, // Usage Maximum (231),
  105. 0x15, 0x00, // Logical Minimum (0),
  106. 0x25, 0x01, // Logical Maximum (1),
  107. 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
  108. 0x95, 0x01, // Report Count (1),
  109. 0x75, 0x08, // Report Size (8),
  110. 0x81, 0x03, // Input (Constant), ;Reserved byte
  111. 0x95, 0x05, // Report Count (5),
  112. 0x75, 0x01, // Report Size (1),
  113. 0x05, 0x08, // Usage Page (LEDs),
  114. 0x19, 0x01, // Usage Minimum (1),
  115. 0x29, 0x05, // Usage Maximum (5),
  116. 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
  117. 0x95, 0x01, // Report Count (1),
  118. 0x75, 0x03, // Report Size (3),
  119. 0x91, 0x03, // Output (Constant), ;LED report padding
  120. 0x95, KBD_REPORT_KEYS, // Report Count (),
  121. 0x75, 0x08, // Report Size (8),
  122. 0x15, 0x00, // Logical Minimum (0),
  123. 0x25, 0xFF, // Logical Maximum(255),
  124. 0x05, 0x07, // Usage Page (Key Codes),
  125. 0x19, 0x00, // Usage Minimum (0),
  126. 0x29, 0xFF, // Usage Maximum (255),
  127. 0x81, 0x00, // Input (Data, Array),
  128. 0xc0 // End Collection
  129. };
  130. /* wrapper */
  131. static const USBDescriptor keyboard_hid_report_descriptor = {
  132. sizeof keyboard_hid_report_desc_data,
  133. keyboard_hid_report_desc_data
  134. };
  135. #ifdef NKRO_ENABLE
  136. static const uint8_t nkro_hid_report_desc_data[] = {
  137. 0x05, 0x01, // Usage Page (Generic Desktop),
  138. 0x09, 0x06, // Usage (Keyboard),
  139. 0xA1, 0x01, // Collection (Application),
  140. // bitmap of modifiers
  141. 0x75, 0x01, // Report Size (1),
  142. 0x95, 0x08, // Report Count (8),
  143. 0x05, 0x07, // Usage Page (Key Codes),
  144. 0x19, 0xE0, // Usage Minimum (224),
  145. 0x29, 0xE7, // Usage Maximum (231),
  146. 0x15, 0x00, // Logical Minimum (0),
  147. 0x25, 0x01, // Logical Maximum (1),
  148. 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
  149. // LED output report
  150. 0x95, 0x05, // Report Count (5),
  151. 0x75, 0x01, // Report Size (1),
  152. 0x05, 0x08, // Usage Page (LEDs),
  153. 0x19, 0x01, // Usage Minimum (1),
  154. 0x29, 0x05, // Usage Maximum (5),
  155. 0x91, 0x02, // Output (Data, Variable, Absolute),
  156. 0x95, 0x01, // Report Count (1),
  157. 0x75, 0x03, // Report Size (3),
  158. 0x91, 0x03, // Output (Constant),
  159. // bitmap of keys
  160. 0x95, NKRO_REPORT_KEYS * 8, // Report Count (),
  161. 0x75, 0x01, // Report Size (1),
  162. 0x15, 0x00, // Logical Minimum (0),
  163. 0x25, 0x01, // Logical Maximum(1),
  164. 0x05, 0x07, // Usage Page (Key Codes),
  165. 0x19, 0x00, // Usage Minimum (0),
  166. 0x29, NKRO_REPORT_KEYS * 8 - 1, // Usage Maximum (),
  167. 0x81, 0x02, // Input (Data, Variable, Absolute),
  168. 0xc0 // End Collection
  169. };
  170. /* wrapper */
  171. static const USBDescriptor nkro_hid_report_descriptor = {
  172. sizeof nkro_hid_report_desc_data,
  173. nkro_hid_report_desc_data
  174. };
  175. #endif /* NKRO_ENABLE */
  176. #ifdef MOUSE_ENABLE
  177. /* Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
  178. * http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
  179. * http://www.keil.com/forum/15671/
  180. * http://www.microsoft.com/whdc/device/input/wheel.mspx */
  181. static const uint8_t mouse_hid_report_desc_data[] = {
  182. /* mouse */
  183. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  184. 0x09, 0x02, // USAGE (Mouse)
  185. 0xa1, 0x01, // COLLECTION (Application)
  186. //0x85, REPORT_ID_MOUSE, // REPORT_ID (1)
  187. 0x09, 0x01, // USAGE (Pointer)
  188. 0xa1, 0x00, // COLLECTION (Physical)
  189. // ---------------------------- Buttons
  190. 0x05, 0x09, // USAGE_PAGE (Button)
  191. 0x19, 0x01, // USAGE_MINIMUM (Button 1)
  192. 0x29, 0x05, // USAGE_MAXIMUM (Button 5)
  193. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  194. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  195. 0x75, 0x01, // REPORT_SIZE (1)
  196. 0x95, 0x05, // REPORT_COUNT (5)
  197. 0x81, 0x02, // INPUT (Data,Var,Abs)
  198. 0x75, 0x03, // REPORT_SIZE (3)
  199. 0x95, 0x01, // REPORT_COUNT (1)
  200. 0x81, 0x03, // INPUT (Cnst,Var,Abs)
  201. // ---------------------------- X,Y position
  202. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  203. 0x09, 0x30, // USAGE (X)
  204. 0x09, 0x31, // USAGE (Y)
  205. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  206. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  207. 0x75, 0x08, // REPORT_SIZE (8)
  208. 0x95, 0x02, // REPORT_COUNT (2)
  209. 0x81, 0x06, // INPUT (Data,Var,Rel)
  210. // ---------------------------- Vertical wheel
  211. 0x09, 0x38, // USAGE (Wheel)
  212. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  213. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  214. 0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical
  215. 0x45, 0x00, // PHYSICAL_MAXIMUM (0)
  216. 0x75, 0x08, // REPORT_SIZE (8)
  217. 0x95, 0x01, // REPORT_COUNT (1)
  218. 0x81, 0x06, // INPUT (Data,Var,Rel)
  219. // ---------------------------- Horizontal wheel
  220. 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
  221. 0x0a, 0x38, 0x02, // USAGE (AC Pan)
  222. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  223. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  224. 0x75, 0x08, // REPORT_SIZE (8)
  225. 0x95, 0x01, // REPORT_COUNT (1)
  226. 0x81, 0x06, // INPUT (Data,Var,Rel)
  227. 0xc0, // END_COLLECTION
  228. 0xc0, // END_COLLECTION
  229. };
  230. /* wrapper */
  231. static const USBDescriptor mouse_hid_report_descriptor = {
  232. sizeof mouse_hid_report_desc_data,
  233. mouse_hid_report_desc_data
  234. };
  235. #endif /* MOUSE_ENABLE */
  236. #ifdef CONSOLE_ENABLE
  237. static const uint8_t console_hid_report_desc_data[] = {
  238. 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
  239. 0x09, 0x74, // Usage 0x74
  240. 0xA1, 0x53, // Collection 0x53
  241. 0x75, 0x08, // report size = 8 bits
  242. 0x15, 0x00, // logical minimum = 0
  243. 0x26, 0xFF, 0x00, // logical maximum = 255
  244. 0x95, CONSOLE_EPSIZE, // report count
  245. 0x09, 0x75, // usage
  246. 0x81, 0x02, // Input (array)
  247. 0xC0 // end collection
  248. };
  249. /* wrapper */
  250. static const USBDescriptor console_hid_report_descriptor = {
  251. sizeof console_hid_report_desc_data,
  252. console_hid_report_desc_data
  253. };
  254. #endif /* CONSOLE_ENABLE */
  255. #ifdef EXTRAKEY_ENABLE
  256. /* audio controls & system controls
  257. * http://www.microsoft.com/whdc/archive/w2kbd.mspx */
  258. static const uint8_t extra_hid_report_desc_data[] = {
  259. /* system control */
  260. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  261. 0x09, 0x80, // USAGE (System Control)
  262. 0xa1, 0x01, // COLLECTION (Application)
  263. 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2)
  264. 0x15, 0x01, // LOGICAL_MINIMUM (0x1)
  265. 0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7)
  266. 0x19, 0x01, // USAGE_MINIMUM (0x1)
  267. 0x29, 0xb7, // USAGE_MAXIMUM (0xb7)
  268. 0x75, 0x10, // REPORT_SIZE (16)
  269. 0x95, 0x01, // REPORT_COUNT (1)
  270. 0x81, 0x00, // INPUT (Data,Array,Abs)
  271. 0xc0, // END_COLLECTION
  272. /* consumer */
  273. 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
  274. 0x09, 0x01, // USAGE (Consumer Control)
  275. 0xa1, 0x01, // COLLECTION (Application)
  276. 0x85, REPORT_ID_CONSUMER, // REPORT_ID (3)
  277. 0x15, 0x01, // LOGICAL_MINIMUM (0x1)
  278. 0x26, 0x9c, 0x02, // LOGICAL_MAXIMUM (0x29c)
  279. 0x19, 0x01, // USAGE_MINIMUM (0x1)
  280. 0x2a, 0x9c, 0x02, // USAGE_MAXIMUM (0x29c)
  281. 0x75, 0x10, // REPORT_SIZE (16)
  282. 0x95, 0x01, // REPORT_COUNT (1)
  283. 0x81, 0x00, // INPUT (Data,Array,Abs)
  284. 0xc0, // END_COLLECTION
  285. };
  286. /* wrapper */
  287. static const USBDescriptor extra_hid_report_descriptor = {
  288. sizeof extra_hid_report_desc_data,
  289. extra_hid_report_desc_data
  290. };
  291. #endif /* EXTRAKEY_ENABLE */
  292. /*
  293. * Configuration Descriptor tree for a HID device
  294. *
  295. * The HID Specifications version 1.11 require the following order:
  296. * - Configuration Descriptor
  297. * - Interface Descriptor
  298. * - HID Descriptor
  299. * - Endpoints Descriptors
  300. */
  301. #define KBD_HID_DESC_NUM 0
  302. #define KBD_HID_DESC_OFFSET (9 + (9 + 9 + 7) * KBD_HID_DESC_NUM + 9)
  303. #ifdef MOUSE_ENABLE
  304. # define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 1)
  305. # define MOUSE_HID_DESC_OFFSET (9 + (9 + 9 + 7) * MOUSE_HID_DESC_NUM + 9)
  306. #else /* MOUSE_ENABLE */
  307. # define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 0)
  308. #endif /* MOUSE_ENABLE */
  309. #ifdef CONSOLE_ENABLE
  310. #define CONSOLE_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 1)
  311. #define CONSOLE_HID_DESC_OFFSET (9 + (9 + 9 + 7) * CONSOLE_HID_DESC_NUM + 9)
  312. #else /* CONSOLE_ENABLE */
  313. # define CONSOLE_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 0)
  314. #endif /* CONSOLE_ENABLE */
  315. #ifdef EXTRAKEY_ENABLE
  316. # define EXTRA_HID_DESC_NUM (CONSOLE_HID_DESC_NUM + 1)
  317. # define EXTRA_HID_DESC_OFFSET (9 + (9 + 9 + 7) * EXTRA_HID_DESC_NUM + 9)
  318. #else /* EXTRAKEY_ENABLE */
  319. # define EXTRA_HID_DESC_NUM (CONSOLE_HID_DESC_NUM + 0)
  320. #endif /* EXTRAKEY_ENABLE */
  321. #ifdef NKRO_ENABLE
  322. # define NKRO_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 1)
  323. # define NKRO_HID_DESC_OFFSET (9 + (9 + 9 + 7) * EXTRA_HID_DESC_NUM + 9)
  324. #else /* NKRO_ENABLE */
  325. # define NKRO_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 0)
  326. #endif /* NKRO_ENABLE */
  327. #define NUM_INTERFACES (NKRO_HID_DESC_NUM + 1)
  328. #define CONFIG1_DESC_SIZE (9 + (9 + 9 + 7) * NUM_INTERFACES)
  329. static const uint8_t hid_configuration_descriptor_data[] = {
  330. /* Configuration Descriptor (9 bytes) USB spec 9.6.3, page 264-266, Table 9-10 */
  331. USB_DESC_CONFIGURATION(CONFIG1_DESC_SIZE, // wTotalLength
  332. NUM_INTERFACES, // bNumInterfaces
  333. 1, // bConfigurationValue
  334. 0, // iConfiguration
  335. 0xA0, // bmAttributes (RESERVED|REMOTEWAKEUP)
  336. 50), // bMaxPower (50mA)
  337. /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
  338. USB_DESC_INTERFACE(KBD_INTERFACE, // bInterfaceNumber
  339. 0, // bAlternateSetting
  340. 1, // bNumEndpoints
  341. 0x03, // bInterfaceClass: HID
  342. 0x01, // bInterfaceSubClass: Boot
  343. 0x01, // bInterfaceProtocol: Keyboard
  344. 0), // iInterface
  345. /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
  346. USB_DESC_BYTE(9), // bLength
  347. USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
  348. USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
  349. USB_DESC_BYTE(0), // bCountryCode
  350. USB_DESC_BYTE(1), // bNumDescriptors
  351. USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
  352. USB_DESC_WORD(sizeof(keyboard_hid_report_desc_data)), // wDescriptorLength
  353. /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
  354. USB_DESC_ENDPOINT(KBD_ENDPOINT | 0x80, // bEndpointAddress
  355. 0x03, // bmAttributes (Interrupt)
  356. KBD_EPSIZE,// wMaxPacketSize
  357. 10), // bInterval
  358. #ifdef MOUSE_ENABLE
  359. /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
  360. USB_DESC_INTERFACE(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 (9 bytes) HID 1.11 spec, section 6.2.1 */
  373. USB_DESC_BYTE(9), // bLength
  374. USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
  375. USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
  376. USB_DESC_BYTE(0), // bCountryCode
  377. USB_DESC_BYTE(1), // bNumDescriptors
  378. USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
  379. USB_DESC_WORD(sizeof(mouse_hid_report_desc_data)), // wDescriptorLength
  380. /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
  381. USB_DESC_ENDPOINT(MOUSE_ENDPOINT | 0x80, // bEndpointAddress
  382. 0x03, // bmAttributes (Interrupt)
  383. MOUSE_EPSIZE, // wMaxPacketSize
  384. 1), // bInterval
  385. #endif /* MOUSE_ENABLE */
  386. #ifdef CONSOLE_ENABLE
  387. /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
  388. USB_DESC_INTERFACE(CONSOLE_INTERFACE, // bInterfaceNumber
  389. 0, // bAlternateSetting
  390. 1, // bNumEndpoints
  391. 0x03, // bInterfaceClass: HID
  392. 0x00, // bInterfaceSubClass: None
  393. 0x00, // bInterfaceProtocol: None
  394. 0), // iInterface
  395. /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
  396. USB_DESC_BYTE(9), // bLength
  397. USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
  398. USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
  399. USB_DESC_BYTE(0), // bCountryCode
  400. USB_DESC_BYTE(1), // bNumDescriptors
  401. USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
  402. USB_DESC_WORD(sizeof(console_hid_report_desc_data)), // wDescriptorLength
  403. /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
  404. USB_DESC_ENDPOINT(CONSOLE_ENDPOINT | 0x80, // bEndpointAddress
  405. 0x03, // bmAttributes (Interrupt)
  406. CONSOLE_EPSIZE, // wMaxPacketSize
  407. 1), // bInterval
  408. #endif /* CONSOLE_ENABLE */
  409. #ifdef EXTRAKEY_ENABLE
  410. /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
  411. USB_DESC_INTERFACE(EXTRA_INTERFACE, // bInterfaceNumber
  412. 0, // bAlternateSetting
  413. 1, // bNumEndpoints
  414. 0x03, // bInterfaceClass: HID
  415. 0x00, // bInterfaceSubClass: None
  416. 0x00, // bInterfaceProtocol: None
  417. 0), // iInterface
  418. /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
  419. USB_DESC_BYTE(9), // bLength
  420. USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
  421. USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
  422. USB_DESC_BYTE(0), // bCountryCode
  423. USB_DESC_BYTE(1), // bNumDescriptors
  424. USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
  425. USB_DESC_WORD(sizeof(extra_hid_report_desc_data)), // wDescriptorLength
  426. /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
  427. USB_DESC_ENDPOINT(EXTRA_ENDPOINT | 0x80, // bEndpointAddress
  428. 0x03, // bmAttributes (Interrupt)
  429. EXTRA_EPSIZE, // wMaxPacketSize
  430. 10), // bInterval
  431. #endif /* EXTRAKEY_ENABLE */
  432. #ifdef NKRO_ENABLE
  433. /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
  434. USB_DESC_INTERFACE(NKRO_INTERFACE, // bInterfaceNumber
  435. 0, // bAlternateSetting
  436. 1, // bNumEndpoints
  437. 0x03, // bInterfaceClass: HID
  438. 0x00, // bInterfaceSubClass: None
  439. 0x00, // bInterfaceProtocol: None
  440. 0), // iInterface
  441. /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
  442. USB_DESC_BYTE(9), // bLength
  443. USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
  444. USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
  445. USB_DESC_BYTE(0), // bCountryCode
  446. USB_DESC_BYTE(1), // bNumDescriptors
  447. USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
  448. USB_DESC_WORD(sizeof(nkro_hid_report_desc_data)), // wDescriptorLength
  449. /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
  450. USB_DESC_ENDPOINT(NKRO_ENDPOINT | 0x80, // bEndpointAddress
  451. 0x03, // bmAttributes (Interrupt)
  452. NKRO_EPSIZE, // wMaxPacketSize
  453. 1), // bInterval
  454. #endif /* NKRO_ENABLE */
  455. };
  456. /* Configuration Descriptor wrapper */
  457. static const USBDescriptor hid_configuration_descriptor = {
  458. sizeof hid_configuration_descriptor_data,
  459. hid_configuration_descriptor_data
  460. };
  461. /* wrappers */
  462. #define HID_DESCRIPTOR_SIZE 9
  463. static const USBDescriptor keyboard_hid_descriptor = {
  464. HID_DESCRIPTOR_SIZE,
  465. &hid_configuration_descriptor_data[KBD_HID_DESC_OFFSET]
  466. };
  467. #ifdef MOUSE_ENABLE
  468. static const USBDescriptor mouse_hid_descriptor = {
  469. HID_DESCRIPTOR_SIZE,
  470. &hid_configuration_descriptor_data[MOUSE_HID_DESC_OFFSET]
  471. };
  472. #endif /* MOUSE_ENABLE */
  473. #ifdef CONSOLE_ENABLE
  474. static const USBDescriptor console_hid_descriptor = {
  475. HID_DESCRIPTOR_SIZE,
  476. &hid_configuration_descriptor_data[CONSOLE_HID_DESC_OFFSET]
  477. };
  478. #endif /* CONSOLE_ENABLE */
  479. #ifdef EXTRAKEY_ENABLE
  480. static const USBDescriptor extra_hid_descriptor = {
  481. HID_DESCRIPTOR_SIZE,
  482. &hid_configuration_descriptor_data[EXTRA_HID_DESC_OFFSET]
  483. };
  484. #endif /* EXTRAKEY_ENABLE */
  485. #ifdef NKRO_ENABLE
  486. static const USBDescriptor nkro_hid_descriptor = {
  487. HID_DESCRIPTOR_SIZE,
  488. &hid_configuration_descriptor_data[NKRO_HID_DESC_OFFSET]
  489. };
  490. #endif /* NKRO_ENABLE */
  491. /* U.S. English language identifier */
  492. static const uint8_t usb_string_langid[] = {
  493. USB_DESC_BYTE(4), // bLength
  494. USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType
  495. USB_DESC_WORD(0x0409) // wLANGID (U.S. English)
  496. };
  497. /* ugly ugly hack */
  498. #define PP_NARG(...) \
  499. PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
  500. #define PP_NARG_(...) \
  501. PP_ARG_N(__VA_ARGS__)
  502. #define PP_ARG_N( \
  503. _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
  504. _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
  505. _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
  506. _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
  507. _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
  508. _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
  509. _61,_62,_63,N,...) N
  510. #define PP_RSEQ_N() \
  511. 63,62,61,60, \
  512. 59,58,57,56,55,54,53,52,51,50, \
  513. 49,48,47,46,45,44,43,42,41,40, \
  514. 39,38,37,36,35,34,33,32,31,30, \
  515. 29,28,27,26,25,24,23,22,21,20, \
  516. 19,18,17,16,15,14,13,12,11,10, \
  517. 9,8,7,6,5,4,3,2,1,0
  518. /* Vendor string = manufacturer */
  519. static const uint8_t usb_string_vendor[] = {
  520. USB_DESC_BYTE(PP_NARG(USBSTR_MANUFACTURER)+2), // bLength
  521. USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType
  522. USBSTR_MANUFACTURER
  523. };
  524. /* Device Description string = product */
  525. static const uint8_t usb_string_description[] = {
  526. USB_DESC_BYTE(PP_NARG(USBSTR_PRODUCT)+2), // bLength
  527. USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType
  528. USBSTR_PRODUCT
  529. };
  530. /* Serial Number string (will be filled by the function init_usb_serial_string) */
  531. static uint8_t usb_string_serial[] = {
  532. USB_DESC_BYTE(22), // bLength
  533. USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType
  534. '0', 0, 'x', 0, 'D', 0, 'E', 0, 'A', 0, 'D', 0, 'B', 0, 'E', 0, 'E', 0, 'F', 0
  535. };
  536. /* Strings wrappers array */
  537. static const USBDescriptor usb_strings[] = {
  538. { sizeof usb_string_langid, usb_string_langid }
  539. ,
  540. { sizeof usb_string_vendor, usb_string_vendor }
  541. ,
  542. { sizeof usb_string_description, usb_string_description }
  543. ,
  544. { sizeof usb_string_serial, usb_string_serial }
  545. };
  546. /*
  547. * Handles the GET_DESCRIPTOR callback
  548. *
  549. * Returns the proper descriptor
  550. */
  551. static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t lang) {
  552. (void)usbp;
  553. (void)lang;
  554. switch(dtype) {
  555. /* Generic descriptors */
  556. case USB_DESCRIPTOR_DEVICE: /* Device Descriptor */
  557. return &usb_device_descriptor;
  558. case USB_DESCRIPTOR_CONFIGURATION: /* Configuration Descriptor */
  559. return &hid_configuration_descriptor;
  560. case USB_DESCRIPTOR_STRING: /* Strings */
  561. if(dindex < 4)
  562. return &usb_strings[dindex];
  563. break;
  564. /* HID specific descriptors */
  565. case USB_DESCRIPTOR_HID: /* HID Descriptors */
  566. switch(lang) { /* yea, poor label, it's actually wIndex from the setup packet */
  567. case KBD_INTERFACE:
  568. return &keyboard_hid_descriptor;
  569. #ifdef MOUSE_ENABLE
  570. case MOUSE_INTERFACE:
  571. return &mouse_hid_descriptor;
  572. #endif /* MOUSE_ENABLE */
  573. #ifdef CONSOLE_ENABLE
  574. case CONSOLE_INTERFACE:
  575. return &console_hid_descriptor;
  576. #endif /* CONSOLE_ENABLE */
  577. #ifdef EXTRAKEY_ENABLE
  578. case EXTRA_INTERFACE:
  579. return &extra_hid_descriptor;
  580. #endif /* EXTRAKEY_ENABLE */
  581. #ifdef NKRO_ENABLE
  582. case NKRO_INTERFACE:
  583. return &nkro_hid_descriptor;
  584. #endif /* NKRO_ENABLE */
  585. }
  586. case USB_DESCRIPTOR_HID_REPORT: /* HID Report Descriptor */
  587. switch(lang) {
  588. case KBD_INTERFACE:
  589. return &keyboard_hid_report_descriptor;
  590. #ifdef MOUSE_ENABLE
  591. case MOUSE_INTERFACE:
  592. return &mouse_hid_report_descriptor;
  593. #endif /* MOUSE_ENABLE */
  594. #ifdef CONSOLE_ENABLE
  595. case CONSOLE_INTERFACE:
  596. return &console_hid_report_descriptor;
  597. #endif /* CONSOLE_ENABLE */
  598. #ifdef EXTRAKEY_ENABLE
  599. case EXTRA_INTERFACE:
  600. return &extra_hid_report_descriptor;
  601. #endif /* EXTRAKEY_ENABLE */
  602. #ifdef NKRO_ENABLE
  603. case NKRO_INTERFACE:
  604. return &nkro_hid_report_descriptor;
  605. #endif /* NKRO_ENABLE */
  606. }
  607. }
  608. return NULL;
  609. }
  610. /* keyboard endpoint state structure */
  611. static USBInEndpointState kbd_ep_state;
  612. /* keyboard endpoint initialization structure (IN) */
  613. static const USBEndpointConfig kbd_ep_config = {
  614. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  615. NULL, /* SETUP packet notification callback */
  616. kbd_in_cb, /* IN notification callback */
  617. NULL, /* OUT notification callback */
  618. KBD_EPSIZE, /* IN maximum packet size */
  619. 0, /* OUT maximum packet size */
  620. &kbd_ep_state, /* IN Endpoint state */
  621. NULL, /* OUT endpoint state */
  622. 2, /* IN multiplier */
  623. NULL /* SETUP buffer (not a SETUP endpoint) */
  624. };
  625. #ifdef MOUSE_ENABLE
  626. /* mouse endpoint state structure */
  627. static USBInEndpointState mouse_ep_state;
  628. /* mouse endpoint initialization structure (IN) */
  629. static const USBEndpointConfig mouse_ep_config = {
  630. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  631. NULL, /* SETUP packet notification callback */
  632. mouse_in_cb, /* IN notification callback */
  633. NULL, /* OUT notification callback */
  634. MOUSE_EPSIZE, /* IN maximum packet size */
  635. 0, /* OUT maximum packet size */
  636. &mouse_ep_state, /* IN Endpoint state */
  637. NULL, /* OUT endpoint state */
  638. 2, /* IN multiplier */
  639. NULL /* SETUP buffer (not a SETUP endpoint) */
  640. };
  641. #endif /* MOUSE_ENABLE */
  642. #ifdef CONSOLE_ENABLE
  643. /* console endpoint state structure */
  644. static USBInEndpointState console_ep_state;
  645. /* console endpoint initialization structure (IN) */
  646. static const USBEndpointConfig console_ep_config = {
  647. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  648. NULL, /* SETUP packet notification callback */
  649. console_in_cb, /* IN notification callback */
  650. NULL, /* OUT notification callback */
  651. CONSOLE_EPSIZE, /* IN maximum packet size */
  652. 0, /* OUT maximum packet size */
  653. &console_ep_state, /* IN Endpoint state */
  654. NULL, /* OUT endpoint state */
  655. 2, /* IN multiplier */
  656. NULL /* SETUP buffer (not a SETUP endpoint) */
  657. };
  658. #endif /* CONSOLE_ENABLE */
  659. #ifdef EXTRAKEY_ENABLE
  660. /* extrakey endpoint state structure */
  661. static USBInEndpointState extra_ep_state;
  662. /* extrakey endpoint initialization structure (IN) */
  663. static const USBEndpointConfig extra_ep_config = {
  664. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  665. NULL, /* SETUP packet notification callback */
  666. extra_in_cb, /* IN notification callback */
  667. NULL, /* OUT notification callback */
  668. EXTRA_EPSIZE, /* IN maximum packet size */
  669. 0, /* OUT maximum packet size */
  670. &extra_ep_state, /* IN Endpoint state */
  671. NULL, /* OUT endpoint state */
  672. 2, /* IN multiplier */
  673. NULL /* SETUP buffer (not a SETUP endpoint) */
  674. };
  675. #endif /* EXTRAKEY_ENABLE */
  676. #ifdef NKRO_ENABLE
  677. /* nkro endpoint state structure */
  678. static USBInEndpointState nkro_ep_state;
  679. /* nkro endpoint initialization structure (IN) */
  680. static const USBEndpointConfig nkro_ep_config = {
  681. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  682. NULL, /* SETUP packet notification callback */
  683. nkro_in_cb, /* IN notification callback */
  684. NULL, /* OUT notification callback */
  685. NKRO_EPSIZE, /* IN maximum packet size */
  686. 0, /* OUT maximum packet size */
  687. &nkro_ep_state, /* IN Endpoint state */
  688. NULL, /* OUT endpoint state */
  689. 2, /* IN multiplier */
  690. NULL /* SETUP buffer (not a SETUP endpoint) */
  691. };
  692. #endif /* NKRO_ENABLE */
  693. /* ---------------------------------------------------------
  694. * USB driver functions
  695. * ---------------------------------------------------------
  696. */
  697. /* Handles the USB driver global events
  698. * TODO: maybe disable some things when connection is lost? */
  699. static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
  700. switch(event) {
  701. case USB_EVENT_RESET:
  702. //TODO: from ISR! print("[R]");
  703. return;
  704. case USB_EVENT_ADDRESS:
  705. return;
  706. case USB_EVENT_CONFIGURED:
  707. osalSysLockFromISR();
  708. /* Enable the endpoints specified into the configuration. */
  709. usbInitEndpointI(usbp, KBD_ENDPOINT, &kbd_ep_config);
  710. #ifdef MOUSE_ENABLE
  711. usbInitEndpointI(usbp, MOUSE_ENDPOINT, &mouse_ep_config);
  712. #endif /* MOUSE_ENABLE */
  713. #ifdef CONSOLE_ENABLE
  714. usbInitEndpointI(usbp, CONSOLE_ENDPOINT, &console_ep_config);
  715. /* don't need to start the flush timer, it starts from console_in_cb automatically */
  716. #endif /* CONSOLE_ENABLE */
  717. #ifdef EXTRAKEY_ENABLE
  718. usbInitEndpointI(usbp, EXTRA_ENDPOINT, &extra_ep_config);
  719. #endif /* EXTRAKEY_ENABLE */
  720. #ifdef NKRO_ENABLE
  721. usbInitEndpointI(usbp, NKRO_ENDPOINT, &nkro_ep_config);
  722. #endif /* NKRO_ENABLE */
  723. osalSysUnlockFromISR();
  724. return;
  725. case USB_EVENT_SUSPEND:
  726. //TODO: from ISR! print("[S]");
  727. #ifdef SLEEP_LED_ENABLE
  728. sleep_led_enable();
  729. #endif /* SLEEP_LED_ENABLE */
  730. return;
  731. case USB_EVENT_WAKEUP:
  732. //TODO: from ISR! print("[W]");
  733. suspend_wakeup_init();
  734. #ifdef SLEEP_LED_ENABLE
  735. sleep_led_disable();
  736. // NOTE: converters may not accept this
  737. led_set(host_keyboard_leds());
  738. #endif /* SLEEP_LED_ENABLE */
  739. return;
  740. case USB_EVENT_STALLED:
  741. return;
  742. }
  743. }
  744. /* Function used locally in os/hal/src/usb.c for getting descriptors
  745. * need it here for HID descriptor */
  746. static uint16_t get_hword(uint8_t *p) {
  747. uint16_t hw;
  748. hw = (uint16_t)*p++;
  749. hw |= (uint16_t)*p << 8U;
  750. return hw;
  751. }
  752. /*
  753. * Appendix G: HID Request Support Requirements
  754. *
  755. * The following table enumerates the requests that need to be supported by various types of HID class devices.
  756. * Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
  757. * ------------------------------------------------------------------------------------------
  758. * Boot Mouse Required Optional Optional Optional Required Required
  759. * Non-Boot Mouse Required Optional Optional Optional Optional Optional
  760. * Boot Keyboard Required Optional Required Required Required Required
  761. * Non-Boot Keybrd Required Optional Required Required Optional Optional
  762. * Other Device Required Optional Optional Optional Optional Optional
  763. */
  764. /* Callback for SETUP request on the endpoint 0 (control) */
  765. static bool usb_request_hook_cb(USBDriver *usbp) {
  766. const USBDescriptor *dp;
  767. /* usbp->setup fields:
  768. * 0: bmRequestType (bitmask)
  769. * 1: bRequest
  770. * 2,3: (LSB,MSB) wValue
  771. * 4,5: (LSB,MSB) wIndex
  772. * 6,7: (LSB,MSB) wLength (number of bytes to transfer if there is a data phase) */
  773. /* Handle HID class specific requests */
  774. if(((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) &&
  775. ((usbp->setup[0] & USB_RTYPE_RECIPIENT_MASK) == USB_RTYPE_RECIPIENT_INTERFACE)) {
  776. switch(usbp->setup[0] & USB_RTYPE_DIR_MASK) {
  777. case USB_RTYPE_DIR_DEV2HOST:
  778. switch(usbp->setup[1]) { /* bRequest */
  779. case HID_GET_REPORT:
  780. switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */
  781. case KBD_INTERFACE:
  782. #ifdef NKRO_ENABLE
  783. case NKRO_INTERFACE:
  784. #endif /* NKRO_ENABLE */
  785. usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent), NULL);
  786. return TRUE;
  787. break;
  788. #ifdef MOUSE_ENABLE
  789. case MOUSE_INTERFACE:
  790. usbSetupTransfer(usbp, (uint8_t *)&mouse_report_blank, sizeof(mouse_report_blank), NULL);
  791. return TRUE;
  792. break;
  793. #endif /* MOUSE_ENABLE */
  794. #ifdef CONSOLE_ENABLE
  795. case CONSOLE_INTERFACE:
  796. usbSetupTransfer(usbp, console_queue_buffer, CONSOLE_EPSIZE, NULL);
  797. return TRUE;
  798. break;
  799. #endif /* CONSOLE_ENABLE */
  800. #ifdef EXTRAKEY_ENABLE
  801. case EXTRA_INTERFACE:
  802. if(usbp->setup[3] == 1) { /* MSB(wValue) [Report Type] == 1 [Input Report] */
  803. switch(usbp->setup[2]) { /* LSB(wValue) [Report ID] */
  804. case REPORT_ID_SYSTEM:
  805. extra_report_blank[0] = REPORT_ID_SYSTEM;
  806. usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
  807. return TRUE;
  808. break;
  809. case REPORT_ID_CONSUMER:
  810. extra_report_blank[0] = REPORT_ID_CONSUMER;
  811. usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
  812. return TRUE;
  813. break;
  814. default:
  815. return FALSE;
  816. }
  817. } else {
  818. return FALSE;
  819. }
  820. break;
  821. #endif /* EXTRAKEY_ENABLE */
  822. default:
  823. usbSetupTransfer(usbp, NULL, 0, NULL);
  824. return TRUE;
  825. break;
  826. }
  827. break;
  828. case HID_GET_PROTOCOL:
  829. if((usbp->setup[4] == KBD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */
  830. usbSetupTransfer(usbp, &keyboard_protocol, 1, NULL);
  831. return TRUE;
  832. }
  833. break;
  834. case HID_GET_IDLE:
  835. usbSetupTransfer(usbp, &keyboard_idle, 1, NULL);
  836. return TRUE;
  837. break;
  838. }
  839. break;
  840. case USB_RTYPE_DIR_HOST2DEV:
  841. switch(usbp->setup[1]) { /* bRequest */
  842. case HID_SET_REPORT:
  843. switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0 and wLength==1?) */
  844. case KBD_INTERFACE:
  845. #ifdef NKRO_ENABLE
  846. case NKRO_INTERFACE:
  847. #endif /* NKRO_ENABLE */
  848. /* keyboard_led_stats = <read byte from next OUT report>
  849. * keyboard_led_stats needs be word (or dword), otherwise we get an exception on F0 */
  850. usbSetupTransfer(usbp, (uint8_t *)&keyboard_led_stats, 1, NULL);
  851. return TRUE;
  852. break;
  853. }
  854. break;
  855. case HID_SET_PROTOCOL:
  856. if((usbp->setup[4] == KBD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */
  857. keyboard_protocol = ((usbp->setup[2]) != 0x00); /* LSB(wValue) */
  858. #ifdef NKRO_ENABLE
  859. keyboard_nkro = !!keyboard_protocol;
  860. if(!keyboard_nkro && keyboard_idle) {
  861. #else /* NKRO_ENABLE */
  862. if(keyboard_idle) {
  863. #endif /* NKRO_ENABLE */
  864. /* arm the idle timer if boot protocol & idle */
  865. osalSysLockFromISR();
  866. chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
  867. osalSysUnlockFromISR();
  868. }
  869. }
  870. usbSetupTransfer(usbp, NULL, 0, NULL);
  871. return TRUE;
  872. break;
  873. case HID_SET_IDLE:
  874. keyboard_idle = usbp->setup[3]; /* MSB(wValue) */
  875. /* arm the timer */
  876. #ifdef NKRO_ENABLE
  877. if(!keyboard_nkro && keyboard_idle) {
  878. #else /* NKRO_ENABLE */
  879. if(keyboard_idle) {
  880. #endif /* NKRO_ENABLE */
  881. osalSysLockFromISR();
  882. chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
  883. osalSysUnlockFromISR();
  884. }
  885. usbSetupTransfer(usbp, NULL, 0, NULL);
  886. return TRUE;
  887. break;
  888. }
  889. break;
  890. }
  891. }
  892. /* Handle the Get_Descriptor Request for HID class (not handled by the default hook) */
  893. if((usbp->setup[0] == 0x81) && (usbp->setup[1] == USB_REQ_GET_DESCRIPTOR)) {
  894. dp = usbp->config->get_descriptor_cb(usbp, usbp->setup[3], usbp->setup[2], get_hword(&usbp->setup[4]));
  895. if(dp == NULL)
  896. return FALSE;
  897. usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL);
  898. return TRUE;
  899. }
  900. return FALSE;
  901. }
  902. /* Start-of-frame callback */
  903. static void usb_sof_cb(USBDriver *usbp) {
  904. kbd_sof_cb(usbp);
  905. }
  906. /* USB driver configuration */
  907. static const USBConfig usbcfg = {
  908. usb_event_cb, /* USB events callback */
  909. usb_get_descriptor_cb, /* Device GET_DESCRIPTOR request callback */
  910. usb_request_hook_cb, /* Requests hook callback */
  911. usb_sof_cb /* Start Of Frame callback */
  912. };
  913. /*
  914. * Initialize the USB driver
  915. */
  916. void init_usb_driver(USBDriver *usbp) {
  917. /*
  918. * Activates the USB driver and then the USB bus pull-up on D+.
  919. * Note, a delay is inserted in order to not have to disconnect the cable
  920. * after a reset.
  921. */
  922. usbDisconnectBus(usbp);
  923. chThdSleepMilliseconds(1500);
  924. usbStart(usbp, &usbcfg);
  925. usbConnectBus(usbp);
  926. chVTObjectInit(&keyboard_idle_timer);
  927. #ifdef CONSOLE_ENABLE
  928. obqObjectInit(&console_buf_queue, console_queue_buffer, CONSOLE_EPSIZE, CONSOLE_QUEUE_CAPACITY, console_queue_onotify, (void*)usbp);
  929. chVTObjectInit(&console_flush_timer);
  930. #endif
  931. }
  932. /*
  933. * Send remote wakeup packet
  934. * Note: should not be called from ISR
  935. */
  936. void send_remote_wakeup(USBDriver *usbp) {
  937. (void)usbp;
  938. #if defined(K20x) || defined(KL2x)
  939. #if KINETIS_USB_USE_USB0
  940. USB0->CTL |= USBx_CTL_RESUME;
  941. chThdSleepMilliseconds(15);
  942. USB0->CTL &= ~USBx_CTL_RESUME;
  943. #endif /* KINETIS_USB_USE_USB0 */
  944. #elif defined(STM32F0XX) || defined(STM32F1XX) /* K20x || KL2x */
  945. STM32_USB->CNTR |= CNTR_RESUME;
  946. chThdSleepMilliseconds(15);
  947. STM32_USB->CNTR &= ~CNTR_RESUME;
  948. #else /* STM32F0XX || STM32F1XX */
  949. #warning Sending remote wakeup packet not implemented for your platform.
  950. #endif /* K20x || KL2x */
  951. }
  952. /* ---------------------------------------------------------
  953. * Keyboard functions
  954. * ---------------------------------------------------------
  955. */
  956. /* keyboard IN callback hander (a kbd report has made it IN) */
  957. void kbd_in_cb(USBDriver *usbp, usbep_t ep) {
  958. /* STUB */
  959. (void)usbp;
  960. (void)ep;
  961. }
  962. #ifdef NKRO_ENABLE
  963. /* nkro IN callback hander (a nkro report has made it IN) */
  964. void nkro_in_cb(USBDriver *usbp, usbep_t ep) {
  965. /* STUB */
  966. (void)usbp;
  967. (void)ep;
  968. }
  969. #endif /* NKRO_ENABLE */
  970. /* start-of-frame handler
  971. * TODO: i guess it would be better to re-implement using timers,
  972. * so that this is not going to have to be checked every 1ms */
  973. void kbd_sof_cb(USBDriver *usbp) {
  974. (void)usbp;
  975. }
  976. /* Idle requests timer code
  977. * callback (called from ISR, unlocked state) */
  978. static void keyboard_idle_timer_cb(void *arg) {
  979. USBDriver *usbp = (USBDriver *)arg;
  980. osalSysLockFromISR();
  981. /* check that the states of things are as they're supposed to */
  982. if(usbGetDriverStateI(usbp) != USB_ACTIVE) {
  983. /* do not rearm the timer, should be enabled on IDLE request */
  984. osalSysUnlockFromISR();
  985. return;
  986. }
  987. #ifdef NKRO_ENABLE
  988. if(!keyboard_nkro && keyboard_idle) {
  989. #else /* NKRO_ENABLE */
  990. if(keyboard_idle) {
  991. #endif /* NKRO_ENABLE */
  992. /* TODO: are we sure we want the KBD_ENDPOINT? */
  993. if(!usbGetTransmitStatusI(usbp, KBD_ENDPOINT)) {
  994. usbStartTransmitI(usbp, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, KBD_EPSIZE);
  995. }
  996. /* rearm the timer */
  997. chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
  998. }
  999. /* do not rearm the timer if the condition above fails
  1000. * it should be enabled again on either IDLE or SET_PROTOCOL requests */
  1001. osalSysUnlockFromISR();
  1002. }
  1003. /* LED status */
  1004. uint8_t keyboard_leds(void) {
  1005. return (uint8_t)(keyboard_led_stats & 0xFF);
  1006. }
  1007. /* prepare and start sending a report IN
  1008. * not callable from ISR or locked state */
  1009. void send_keyboard(report_keyboard_t *report) {
  1010. osalSysLock();
  1011. if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
  1012. osalSysUnlock();
  1013. return;
  1014. }
  1015. osalSysUnlock();
  1016. #ifdef NKRO_ENABLE
  1017. if(keyboard_nkro) { /* NKRO protocol */
  1018. /* need to wait until the previous packet has made it through */
  1019. /* can rewrite this using the synchronous API, then would wait
  1020. * until *after* the packet has been transmitted. I think
  1021. * this is more efficient */
  1022. /* busy wait, should be short and not very common */
  1023. osalSysLock();
  1024. if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_ENDPOINT)) {
  1025. /* Need to either suspend, or loop and call unlock/lock during
  1026. * every iteration - otherwise the system will remain locked,
  1027. * no interrupts served, so USB not going through as well.
  1028. * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
  1029. osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_ENDPOINT]->in_state->thread);
  1030. }
  1031. usbStartTransmitI(&USB_DRIVER, NKRO_ENDPOINT, (uint8_t *)report, sizeof(report_keyboard_t));
  1032. osalSysUnlock();
  1033. } else
  1034. #endif /* NKRO_ENABLE */
  1035. { /* boot protocol */
  1036. /* need to wait until the previous packet has made it through */
  1037. /* busy wait, should be short and not very common */
  1038. osalSysLock();
  1039. if(usbGetTransmitStatusI(&USB_DRIVER, KBD_ENDPOINT)) {
  1040. /* Need to either suspend, or loop and call unlock/lock during
  1041. * every iteration - otherwise the system will remain locked,
  1042. * no interrupts served, so USB not going through as well.
  1043. * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
  1044. osalThreadSuspendS(&(&USB_DRIVER)->epc[KBD_ENDPOINT]->in_state->thread);
  1045. }
  1046. usbStartTransmitI(&USB_DRIVER, KBD_ENDPOINT, (uint8_t *)report, KBD_EPSIZE);
  1047. osalSysUnlock();
  1048. }
  1049. keyboard_report_sent = *report;
  1050. }
  1051. /* ---------------------------------------------------------
  1052. * Mouse functions
  1053. * ---------------------------------------------------------
  1054. */
  1055. #ifdef MOUSE_ENABLE
  1056. /* mouse IN callback hander (a mouse report has made it IN) */
  1057. void mouse_in_cb(USBDriver *usbp, usbep_t ep) {
  1058. (void)usbp;
  1059. (void)ep;
  1060. }
  1061. void send_mouse(report_mouse_t *report) {
  1062. osalSysLock();
  1063. if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
  1064. osalSysUnlock();
  1065. return;
  1066. }
  1067. osalSysUnlock();
  1068. /* TODO: LUFA manually waits for the endpoint to become ready
  1069. * for about 10ms for mouse, kbd, system; 1ms for nkro
  1070. * is this really needed?
  1071. */
  1072. osalSysLock();
  1073. usbStartTransmitI(&USB_DRIVER, MOUSE_ENDPOINT, (uint8_t *)report, sizeof(report_mouse_t));
  1074. osalSysUnlock();
  1075. }
  1076. #else /* MOUSE_ENABLE */
  1077. void send_mouse(report_mouse_t *report) {
  1078. (void)report;
  1079. }
  1080. #endif /* MOUSE_ENABLE */
  1081. /* ---------------------------------------------------------
  1082. * Extrakey functions
  1083. * ---------------------------------------------------------
  1084. */
  1085. #ifdef EXTRAKEY_ENABLE
  1086. /* extrakey IN callback hander */
  1087. void extra_in_cb(USBDriver *usbp, usbep_t ep) {
  1088. /* STUB */
  1089. (void)usbp;
  1090. (void)ep;
  1091. }
  1092. static void send_extra_report(uint8_t report_id, uint16_t data) {
  1093. osalSysLock();
  1094. if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
  1095. osalSysUnlock();
  1096. return;
  1097. }
  1098. report_extra_t report = {
  1099. .report_id = report_id,
  1100. .usage = data
  1101. };
  1102. usbStartTransmitI(&USB_DRIVER, EXTRA_ENDPOINT, (uint8_t *)&report, sizeof(report_extra_t));
  1103. osalSysUnlock();
  1104. }
  1105. void send_system(uint16_t data) {
  1106. send_extra_report(REPORT_ID_SYSTEM, data);
  1107. }
  1108. void send_consumer(uint16_t data) {
  1109. send_extra_report(REPORT_ID_CONSUMER, data);
  1110. }
  1111. #else /* EXTRAKEY_ENABLE */
  1112. void send_system(uint16_t data) {
  1113. (void)data;
  1114. }
  1115. void send_consumer(uint16_t data) {
  1116. (void)data;
  1117. }
  1118. #endif /* EXTRAKEY_ENABLE */
  1119. /* ---------------------------------------------------------
  1120. * Console functions
  1121. * ---------------------------------------------------------
  1122. */
  1123. #ifdef CONSOLE_ENABLE
  1124. /* console IN callback hander */
  1125. void console_in_cb(USBDriver *usbp, usbep_t ep) {
  1126. (void)ep; /* should have ep == CONSOLE_ENDPOINT, so use that to save time/space */
  1127. uint8_t *buf;
  1128. size_t n;
  1129. osalSysLockFromISR();
  1130. /* rearm the timer */
  1131. chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
  1132. /* Freeing the buffer just transmitted, if it was not a zero size packet.*/
  1133. if (usbp->epc[CONSOLE_ENDPOINT]->in_state->txsize > 0U) {
  1134. obqReleaseEmptyBufferI(&console_buf_queue);
  1135. }
  1136. /* Checking if there is a buffer ready for transmission.*/
  1137. buf = obqGetFullBufferI(&console_buf_queue, &n);
  1138. if (buf != NULL) {
  1139. /* The endpoint cannot be busy, we are in the context of the callback,
  1140. so it is safe to transmit without a check.*/
  1141. /* Should have n == CONSOLE_EPSIZE; check it? */
  1142. usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE);
  1143. } else {
  1144. /* Nothing to transmit.*/
  1145. }
  1146. osalSysUnlockFromISR();
  1147. }
  1148. /* Callback when data is inserted into the output queue
  1149. * Called from a locked state */
  1150. void console_queue_onotify(io_buffers_queue_t *bqp) {
  1151. size_t n;
  1152. USBDriver *usbp = bqGetLinkX(bqp);
  1153. if(usbGetDriverStateI(usbp) != USB_ACTIVE)
  1154. return;
  1155. /* Checking if there is already a transaction ongoing on the endpoint.*/
  1156. if (!usbGetTransmitStatusI(usbp, CONSOLE_ENDPOINT)) {
  1157. /* Trying to get a full buffer.*/
  1158. uint8_t *buf = obqGetFullBufferI(&console_buf_queue, &n);
  1159. if (buf != NULL) {
  1160. /* Buffer found, starting a new transaction.*/
  1161. /* Should have n == CONSOLE_EPSIZE; check this? */
  1162. usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE);
  1163. }
  1164. }
  1165. }
  1166. /* Flush timer code
  1167. * callback (called from ISR, unlocked state) */
  1168. static void console_flush_cb(void *arg) {
  1169. USBDriver *usbp = (USBDriver *)arg;
  1170. osalSysLockFromISR();
  1171. /* check that the states of things are as they're supposed to */
  1172. if(usbGetDriverStateI(usbp) != USB_ACTIVE) {
  1173. /* rearm the timer */
  1174. chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
  1175. osalSysUnlockFromISR();
  1176. return;
  1177. }
  1178. /* If there is already a transaction ongoing then another one cannot be
  1179. started.*/
  1180. if (usbGetTransmitStatusI(usbp, CONSOLE_ENDPOINT)) {
  1181. /* rearm the timer */
  1182. chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
  1183. osalSysUnlockFromISR();
  1184. return;
  1185. }
  1186. /* Checking if there only a buffer partially filled, if so then it is
  1187. enforced in the queue and transmitted.*/
  1188. if(obqTryFlushI(&console_buf_queue)) {
  1189. size_t n,i;
  1190. uint8_t *buf = obqGetFullBufferI(&console_buf_queue, &n);
  1191. osalDbgAssert(buf != NULL, "queue is empty");
  1192. /* zero the rest of the buffer (buf should point to allocated space) */
  1193. for(i=n; i<CONSOLE_EPSIZE; i++)
  1194. buf[i]=0;
  1195. usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE);
  1196. }
  1197. /* rearm the timer */
  1198. chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
  1199. osalSysUnlockFromISR();
  1200. }
  1201. int8_t sendchar(uint8_t c) {
  1202. osalSysLock();
  1203. if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
  1204. osalSysUnlock();
  1205. return 0;
  1206. }
  1207. osalSysUnlock();
  1208. /* Timeout after 5us if the queue is full.
  1209. * Increase this timeout if too much stuff is getting
  1210. * dropped (i.e. the buffer is getting full too fast
  1211. * for USB/HIDRAW to dequeue). Another possibility
  1212. * for fixing this kind of thing is to increase
  1213. * CONSOLE_QUEUE_CAPACITY. */
  1214. return(obqPutTimeout(&console_buf_queue, c, US2ST(100)));
  1215. }
  1216. #else /* CONSOLE_ENABLE */
  1217. int8_t sendchar(uint8_t c) {
  1218. (void)c;
  1219. return 0;
  1220. }
  1221. #endif /* CONSOLE_ENABLE */
  1222. void sendchar_pf(void *p, char c) {
  1223. (void)p;
  1224. sendchar((uint8_t)c);
  1225. }