usb_main.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. /*
  2. * (c) 2015 flabberast <s3+flabbergast@sdfeu.org>
  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. /*
  18. * Implementation notes:
  19. *
  20. * USBEndpointConfig - Configured using explicit order instead of struct member name.
  21. * This is due to ChibiOS hal LLD differences, which is dependent on hardware,
  22. * "USBv1" devices have `ep_buffers` and "OTGv1" have `in_multiplier`.
  23. * Given `USBv1/hal_usb_lld.h` marks the field as "not currently used" this code file
  24. * makes the assumption this is safe to avoid littering with preprocessor directives.
  25. */
  26. #include <ch.h>
  27. #include <hal.h>
  28. #include <string.h>
  29. #include "usb_main.h"
  30. #include "host.h"
  31. #include "chibios_config.h"
  32. #include "debug.h"
  33. #include "suspend.h"
  34. #ifdef SLEEP_LED_ENABLE
  35. # include "sleep_led.h"
  36. # include "led.h"
  37. #endif
  38. #include "wait.h"
  39. #include "usb_device_state.h"
  40. #include "usb_descriptor.h"
  41. #include "usb_driver.h"
  42. #include "usb_types.h"
  43. #ifdef NKRO_ENABLE
  44. # include "keycode_config.h"
  45. extern keymap_config_t keymap_config;
  46. #endif
  47. /* ---------------------------------------------------------
  48. * Global interface variables and declarations
  49. * ---------------------------------------------------------
  50. */
  51. #ifndef usb_lld_connect_bus
  52. # define usb_lld_connect_bus(usbp)
  53. #endif
  54. #ifndef usb_lld_disconnect_bus
  55. # define usb_lld_disconnect_bus(usbp)
  56. #endif
  57. uint8_t keyboard_idle __attribute__((aligned(2))) = 0;
  58. uint8_t keyboard_protocol __attribute__((aligned(2))) = 1;
  59. uint8_t keyboard_led_state = 0;
  60. volatile uint16_t keyboard_idle_count = 0;
  61. static virtual_timer_t keyboard_idle_timer;
  62. static void keyboard_idle_timer_cb(struct ch_virtual_timer *, void *arg);
  63. report_keyboard_t keyboard_report_sent = {0};
  64. report_mouse_t mouse_report_sent = {0};
  65. union {
  66. uint8_t report_id;
  67. report_keyboard_t keyboard;
  68. #ifdef EXTRAKEY_ENABLE
  69. report_extra_t extra;
  70. #endif
  71. #ifdef MOUSE_ENABLE
  72. report_mouse_t mouse;
  73. #endif
  74. #ifdef DIGITIZER_ENABLE
  75. report_digitizer_t digitizer;
  76. #endif
  77. #ifdef JOYSTICK_ENABLE
  78. report_joystick_t joystick;
  79. #endif
  80. } universal_report_blank = {0};
  81. /* ---------------------------------------------------------
  82. * Descriptors and USB driver objects
  83. * ---------------------------------------------------------
  84. */
  85. /* USB Low Level driver specific endpoint fields */
  86. #if !defined(usb_lld_endpoint_fields)
  87. # define usb_lld_endpoint_fields \
  88. 2, /* IN multiplier */ \
  89. NULL, /* SETUP buffer (not a SETUP endpoint) */
  90. #endif
  91. static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t wIndex) {
  92. usb_control_request_t *setup = (usb_control_request_t *)usbp->setup;
  93. static USBDescriptor descriptor;
  94. descriptor.ud_string = NULL;
  95. descriptor.ud_size = get_usb_descriptor(setup->wValue.word, setup->wIndex, setup->wLength, (const void **const) & descriptor.ud_string);
  96. if (descriptor.ud_string == NULL) {
  97. return NULL;
  98. }
  99. return &descriptor;
  100. }
  101. /*
  102. * USB notification callback that does nothing. Needed to work around bugs in
  103. * some USB LLDs that fail to resume the waiting thread when the notification
  104. * callback pointer is NULL.
  105. */
  106. static void dummy_usb_cb(USBDriver *usbp, usbep_t ep) {
  107. (void)usbp;
  108. (void)ep;
  109. }
  110. #ifndef KEYBOARD_SHARED_EP
  111. /* keyboard endpoint state structure */
  112. static USBInEndpointState kbd_ep_state;
  113. /* keyboard endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
  114. static const USBEndpointConfig kbd_ep_config = {
  115. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  116. NULL, /* SETUP packet notification callback */
  117. dummy_usb_cb, /* IN notification callback */
  118. NULL, /* OUT notification callback */
  119. KEYBOARD_EPSIZE, /* IN maximum packet size */
  120. 0, /* OUT maximum packet size */
  121. &kbd_ep_state, /* IN Endpoint state */
  122. NULL, /* OUT endpoint state */
  123. usb_lld_endpoint_fields /* USB driver specific endpoint fields */
  124. };
  125. #endif
  126. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  127. /* mouse endpoint state structure */
  128. static USBInEndpointState mouse_ep_state;
  129. /* mouse endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
  130. static const USBEndpointConfig mouse_ep_config = {
  131. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  132. NULL, /* SETUP packet notification callback */
  133. dummy_usb_cb, /* IN notification callback */
  134. NULL, /* OUT notification callback */
  135. MOUSE_EPSIZE, /* IN maximum packet size */
  136. 0, /* OUT maximum packet size */
  137. &mouse_ep_state, /* IN Endpoint state */
  138. NULL, /* OUT endpoint state */
  139. usb_lld_endpoint_fields /* USB driver specific endpoint fields */
  140. };
  141. #endif
  142. #ifdef SHARED_EP_ENABLE
  143. /* shared endpoint state structure */
  144. static USBInEndpointState shared_ep_state;
  145. /* shared endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
  146. static const USBEndpointConfig shared_ep_config = {
  147. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  148. NULL, /* SETUP packet notification callback */
  149. dummy_usb_cb, /* IN notification callback */
  150. NULL, /* OUT notification callback */
  151. SHARED_EPSIZE, /* IN maximum packet size */
  152. 0, /* OUT maximum packet size */
  153. &shared_ep_state, /* IN Endpoint state */
  154. NULL, /* OUT endpoint state */
  155. usb_lld_endpoint_fields /* USB driver specific endpoint fields */
  156. };
  157. #endif
  158. #if defined(JOYSTICK_ENABLE) && !defined(JOYSTICK_SHARED_EP)
  159. /* joystick endpoint state structure */
  160. static USBInEndpointState joystick_ep_state;
  161. /* joystick endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
  162. static const USBEndpointConfig joystick_ep_config = {
  163. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  164. NULL, /* SETUP packet notification callback */
  165. dummy_usb_cb, /* IN notification callback */
  166. NULL, /* OUT notification callback */
  167. JOYSTICK_EPSIZE, /* IN maximum packet size */
  168. 0, /* OUT maximum packet size */
  169. &joystick_ep_state, /* IN Endpoint state */
  170. NULL, /* OUT endpoint state */
  171. usb_lld_endpoint_fields /* USB driver specific endpoint fields */
  172. };
  173. #endif
  174. #if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
  175. /* digitizer endpoint state structure */
  176. static USBInEndpointState digitizer_ep_state;
  177. /* digitizer endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
  178. static const USBEndpointConfig digitizer_ep_config = {
  179. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
  180. NULL, /* SETUP packet notification callback */
  181. dummy_usb_cb, /* IN notification callback */
  182. NULL, /* OUT notification callback */
  183. DIGITIZER_EPSIZE, /* IN maximum packet size */
  184. 0, /* OUT maximum packet size */
  185. &digitizer_ep_state, /* IN Endpoint state */
  186. NULL, /* OUT endpoint state */
  187. usb_lld_endpoint_fields /* USB driver specific endpoint fields */
  188. };
  189. #endif
  190. #ifdef USB_ENDPOINTS_ARE_REORDERABLE
  191. typedef struct {
  192. size_t queue_capacity_in;
  193. size_t queue_capacity_out;
  194. USBInEndpointState in_ep_state;
  195. USBOutEndpointState out_ep_state;
  196. USBInEndpointState int_ep_state;
  197. USBEndpointConfig inout_ep_config;
  198. USBEndpointConfig int_ep_config;
  199. const QMKUSBConfig config;
  200. QMKUSBDriver driver;
  201. } usb_driver_config_t;
  202. #else
  203. typedef struct {
  204. size_t queue_capacity_in;
  205. size_t queue_capacity_out;
  206. USBInEndpointState in_ep_state;
  207. USBOutEndpointState out_ep_state;
  208. USBInEndpointState int_ep_state;
  209. USBEndpointConfig in_ep_config;
  210. USBEndpointConfig out_ep_config;
  211. USBEndpointConfig int_ep_config;
  212. const QMKUSBConfig config;
  213. QMKUSBDriver driver;
  214. } usb_driver_config_t;
  215. #endif
  216. #ifdef USB_ENDPOINTS_ARE_REORDERABLE
  217. /* Reusable initialization structure - see USBEndpointConfig comment at top of file */
  218. # define QMK_USB_DRIVER_CONFIG(stream, notification, fixedsize) \
  219. { \
  220. .queue_capacity_in = stream##_IN_CAPACITY, .queue_capacity_out = stream##_OUT_CAPACITY, \
  221. .inout_ep_config = \
  222. { \
  223. stream##_IN_MODE, /* Interrupt EP */ \
  224. NULL, /* SETUP packet notification callback */ \
  225. qmkusbDataTransmitted, /* IN notification callback */ \
  226. qmkusbDataReceived, /* OUT notification callback */ \
  227. stream##_EPSIZE, /* IN maximum packet size */ \
  228. stream##_EPSIZE, /* OUT maximum packet size */ \
  229. NULL, /* IN Endpoint state */ \
  230. NULL, /* OUT endpoint state */ \
  231. usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
  232. }, \
  233. .int_ep_config = \
  234. { \
  235. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ \
  236. NULL, /* SETUP packet notification callback */ \
  237. qmkusbInterruptTransmitted, /* IN notification callback */ \
  238. NULL, /* OUT notification callback */ \
  239. CDC_NOTIFICATION_EPSIZE, /* IN maximum packet size */ \
  240. 0, /* OUT maximum packet size */ \
  241. NULL, /* IN Endpoint state */ \
  242. NULL, /* OUT endpoint state */ \
  243. usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
  244. }, \
  245. .config = { \
  246. .usbp = &USB_DRIVER, \
  247. .bulk_in = stream##_IN_EPNUM, \
  248. .bulk_out = stream##_OUT_EPNUM, \
  249. .int_in = notification, \
  250. .in_buffers = stream##_IN_CAPACITY, \
  251. .out_buffers = stream##_OUT_CAPACITY, \
  252. .in_size = stream##_EPSIZE, \
  253. .out_size = stream##_EPSIZE, \
  254. .fixed_size = fixedsize, \
  255. .ib = (__attribute__((aligned(4))) uint8_t[BQ_BUFFER_SIZE(stream##_IN_CAPACITY, stream##_EPSIZE)]){}, \
  256. .ob = (__attribute__((aligned(4))) uint8_t[BQ_BUFFER_SIZE(stream##_OUT_CAPACITY, stream##_EPSIZE)]){}, \
  257. } \
  258. }
  259. #else
  260. /* Reusable initialization structure - see USBEndpointConfig comment at top of file */
  261. # define QMK_USB_DRIVER_CONFIG(stream, notification, fixedsize) \
  262. { \
  263. .queue_capacity_in = stream##_IN_CAPACITY, .queue_capacity_out = stream##_OUT_CAPACITY, \
  264. .in_ep_config = \
  265. { \
  266. stream##_IN_MODE, /* Interrupt EP */ \
  267. NULL, /* SETUP packet notification callback */ \
  268. qmkusbDataTransmitted, /* IN notification callback */ \
  269. NULL, /* OUT notification callback */ \
  270. stream##_EPSIZE, /* IN maximum packet size */ \
  271. 0, /* OUT maximum packet size */ \
  272. NULL, /* IN Endpoint state */ \
  273. NULL, /* OUT endpoint state */ \
  274. usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
  275. }, \
  276. .out_ep_config = \
  277. { \
  278. stream##_OUT_MODE, /* Interrupt EP */ \
  279. NULL, /* SETUP packet notification callback */ \
  280. NULL, /* IN notification callback */ \
  281. qmkusbDataReceived, /* OUT notification callback */ \
  282. 0, /* IN maximum packet size */ \
  283. stream##_EPSIZE, /* OUT maximum packet size */ \
  284. NULL, /* IN Endpoint state */ \
  285. NULL, /* OUT endpoint state */ \
  286. usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
  287. }, \
  288. .int_ep_config = \
  289. { \
  290. USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ \
  291. NULL, /* SETUP packet notification callback */ \
  292. qmkusbInterruptTransmitted, /* IN notification callback */ \
  293. NULL, /* OUT notification callback */ \
  294. CDC_NOTIFICATION_EPSIZE, /* IN maximum packet size */ \
  295. 0, /* OUT maximum packet size */ \
  296. NULL, /* IN Endpoint state */ \
  297. NULL, /* OUT endpoint state */ \
  298. usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
  299. }, \
  300. .config = { \
  301. .usbp = &USB_DRIVER, \
  302. .bulk_in = stream##_IN_EPNUM, \
  303. .bulk_out = stream##_OUT_EPNUM, \
  304. .int_in = notification, \
  305. .in_buffers = stream##_IN_CAPACITY, \
  306. .out_buffers = stream##_OUT_CAPACITY, \
  307. .in_size = stream##_EPSIZE, \
  308. .out_size = stream##_EPSIZE, \
  309. .fixed_size = fixedsize, \
  310. .ib = (__attribute__((aligned(4))) uint8_t[BQ_BUFFER_SIZE(stream##_IN_CAPACITY, stream##_EPSIZE)]){}, \
  311. .ob = (__attribute__((aligned(4))) uint8_t[BQ_BUFFER_SIZE(stream##_OUT_CAPACITY, stream##_EPSIZE)]){}, \
  312. } \
  313. }
  314. #endif
  315. typedef struct {
  316. union {
  317. struct {
  318. #ifdef CONSOLE_ENABLE
  319. usb_driver_config_t console_driver;
  320. #endif
  321. #ifdef RAW_ENABLE
  322. usb_driver_config_t raw_driver;
  323. #endif
  324. #ifdef MIDI_ENABLE
  325. usb_driver_config_t midi_driver;
  326. #endif
  327. #ifdef VIRTSER_ENABLE
  328. usb_driver_config_t serial_driver;
  329. #endif
  330. };
  331. usb_driver_config_t array[0];
  332. };
  333. } usb_driver_configs_t;
  334. static usb_driver_configs_t drivers = {
  335. #ifdef CONSOLE_ENABLE
  336. # define CONSOLE_IN_CAPACITY 4
  337. # define CONSOLE_OUT_CAPACITY 4
  338. # define CONSOLE_IN_MODE USB_EP_MODE_TYPE_INTR
  339. # define CONSOLE_OUT_MODE USB_EP_MODE_TYPE_INTR
  340. .console_driver = QMK_USB_DRIVER_CONFIG(CONSOLE, 0, true),
  341. #endif
  342. #ifdef RAW_ENABLE
  343. # ifndef RAW_IN_CAPACITY
  344. # define RAW_IN_CAPACITY 4
  345. # endif
  346. # ifndef RAW_OUT_CAPACITY
  347. # define RAW_OUT_CAPACITY 4
  348. # endif
  349. # define RAW_IN_MODE USB_EP_MODE_TYPE_INTR
  350. # define RAW_OUT_MODE USB_EP_MODE_TYPE_INTR
  351. .raw_driver = QMK_USB_DRIVER_CONFIG(RAW, 0, false),
  352. #endif
  353. #ifdef MIDI_ENABLE
  354. # define MIDI_STREAM_IN_CAPACITY 4
  355. # define MIDI_STREAM_OUT_CAPACITY 4
  356. # define MIDI_STREAM_IN_MODE USB_EP_MODE_TYPE_BULK
  357. # define MIDI_STREAM_OUT_MODE USB_EP_MODE_TYPE_BULK
  358. .midi_driver = QMK_USB_DRIVER_CONFIG(MIDI_STREAM, 0, false),
  359. #endif
  360. #ifdef VIRTSER_ENABLE
  361. # define CDC_IN_CAPACITY 4
  362. # define CDC_OUT_CAPACITY 4
  363. # define CDC_IN_MODE USB_EP_MODE_TYPE_BULK
  364. # define CDC_OUT_MODE USB_EP_MODE_TYPE_BULK
  365. .serial_driver = QMK_USB_DRIVER_CONFIG(CDC, CDC_NOTIFICATION_EPNUM, false),
  366. #endif
  367. };
  368. #define NUM_USB_DRIVERS (sizeof(drivers) / sizeof(usb_driver_config_t))
  369. /* ---------------------------------------------------------
  370. * USB driver functions
  371. * ---------------------------------------------------------
  372. */
  373. #define USB_EVENT_QUEUE_SIZE 16
  374. usbevent_t event_queue[USB_EVENT_QUEUE_SIZE];
  375. uint8_t event_queue_head;
  376. uint8_t event_queue_tail;
  377. void usb_event_queue_init(void) {
  378. // Initialise the event queue
  379. memset(&event_queue, 0, sizeof(event_queue));
  380. event_queue_head = 0;
  381. event_queue_tail = 0;
  382. }
  383. static inline bool usb_event_queue_enqueue(usbevent_t event) {
  384. uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE;
  385. if (next == event_queue_tail) {
  386. return false;
  387. }
  388. event_queue[event_queue_head] = event;
  389. event_queue_head = next;
  390. return true;
  391. }
  392. static inline bool usb_event_queue_dequeue(usbevent_t *event) {
  393. if (event_queue_head == event_queue_tail) {
  394. return false;
  395. }
  396. *event = event_queue[event_queue_tail];
  397. event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE;
  398. return true;
  399. }
  400. static inline void usb_event_suspend_handler(void) {
  401. usb_device_state_set_suspend(USB_DRIVER.configuration != 0, USB_DRIVER.configuration);
  402. #ifdef SLEEP_LED_ENABLE
  403. sleep_led_enable();
  404. #endif /* SLEEP_LED_ENABLE */
  405. }
  406. static inline void usb_event_wakeup_handler(void) {
  407. suspend_wakeup_init();
  408. usb_device_state_set_resume(USB_DRIVER.configuration != 0, USB_DRIVER.configuration);
  409. #ifdef SLEEP_LED_ENABLE
  410. sleep_led_disable();
  411. // NOTE: converters may not accept this
  412. led_set(host_keyboard_leds());
  413. #endif /* SLEEP_LED_ENABLE */
  414. }
  415. bool last_suspend_state = false;
  416. void usb_event_queue_task(void) {
  417. usbevent_t event;
  418. while (usb_event_queue_dequeue(&event)) {
  419. switch (event) {
  420. case USB_EVENT_SUSPEND:
  421. last_suspend_state = true;
  422. usb_event_suspend_handler();
  423. break;
  424. case USB_EVENT_WAKEUP:
  425. last_suspend_state = false;
  426. usb_event_wakeup_handler();
  427. break;
  428. case USB_EVENT_CONFIGURED:
  429. usb_device_state_set_configuration(USB_DRIVER.configuration != 0, USB_DRIVER.configuration);
  430. break;
  431. case USB_EVENT_UNCONFIGURED:
  432. usb_device_state_set_configuration(false, 0);
  433. break;
  434. case USB_EVENT_RESET:
  435. usb_device_state_set_reset();
  436. break;
  437. default:
  438. // Nothing to do, we don't handle it.
  439. break;
  440. }
  441. }
  442. }
  443. /* Handles the USB driver global events. */
  444. static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
  445. switch (event) {
  446. case USB_EVENT_ADDRESS:
  447. return;
  448. case USB_EVENT_CONFIGURED:
  449. osalSysLockFromISR();
  450. /* Enable the endpoints specified into the configuration. */
  451. #ifndef KEYBOARD_SHARED_EP
  452. usbInitEndpointI(usbp, KEYBOARD_IN_EPNUM, &kbd_ep_config);
  453. #endif
  454. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  455. usbInitEndpointI(usbp, MOUSE_IN_EPNUM, &mouse_ep_config);
  456. #endif
  457. #ifdef SHARED_EP_ENABLE
  458. usbInitEndpointI(usbp, SHARED_IN_EPNUM, &shared_ep_config);
  459. #endif
  460. #if defined(JOYSTICK_ENABLE) && !defined(JOYSTICK_SHARED_EP)
  461. usbInitEndpointI(usbp, JOYSTICK_IN_EPNUM, &joystick_ep_config);
  462. #endif
  463. #if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
  464. usbInitEndpointI(usbp, DIGITIZER_IN_EPNUM, &digitizer_ep_config);
  465. #endif
  466. for (int i = 0; i < NUM_USB_DRIVERS; i++) {
  467. #ifdef USB_ENDPOINTS_ARE_REORDERABLE
  468. usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].inout_ep_config);
  469. #else
  470. usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].in_ep_config);
  471. usbInitEndpointI(usbp, drivers.array[i].config.bulk_out, &drivers.array[i].out_ep_config);
  472. #endif
  473. if (drivers.array[i].config.int_in) {
  474. usbInitEndpointI(usbp, drivers.array[i].config.int_in, &drivers.array[i].int_ep_config);
  475. }
  476. qmkusbConfigureHookI(&drivers.array[i].driver);
  477. }
  478. osalSysUnlockFromISR();
  479. if (last_suspend_state) {
  480. usb_event_queue_enqueue(USB_EVENT_WAKEUP);
  481. }
  482. usb_event_queue_enqueue(USB_EVENT_CONFIGURED);
  483. return;
  484. case USB_EVENT_SUSPEND:
  485. /* Falls into.*/
  486. case USB_EVENT_UNCONFIGURED:
  487. /* Falls into.*/
  488. case USB_EVENT_RESET:
  489. usb_event_queue_enqueue(event);
  490. for (int i = 0; i < NUM_USB_DRIVERS; i++) {
  491. chSysLockFromISR();
  492. /* Disconnection event on suspend.*/
  493. qmkusbSuspendHookI(&drivers.array[i].driver);
  494. chSysUnlockFromISR();
  495. }
  496. return;
  497. case USB_EVENT_WAKEUP:
  498. // TODO: from ISR! print("[W]");
  499. for (int i = 0; i < NUM_USB_DRIVERS; i++) {
  500. chSysLockFromISR();
  501. /* Disconnection event on suspend.*/
  502. qmkusbWakeupHookI(&drivers.array[i].driver);
  503. chSysUnlockFromISR();
  504. }
  505. usb_event_queue_enqueue(USB_EVENT_WAKEUP);
  506. return;
  507. case USB_EVENT_STALLED:
  508. return;
  509. }
  510. }
  511. /*
  512. * Appendix G: HID Request Support Requirements
  513. *
  514. * The following table enumerates the requests that need to be supported by various types of HID class devices.
  515. * Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
  516. * ------------------------------------------------------------------------------------------
  517. * Boot Mouse Required Optional Optional Optional Required Required
  518. * Non-Boot Mouse Required Optional Optional Optional Optional Optional
  519. * Boot Keyboard Required Optional Required Required Required Required
  520. * Non-Boot Keybrd Required Optional Required Required Optional Optional
  521. * Other Device Required Optional Optional Optional Optional Optional
  522. */
  523. static uint8_t set_report_buf[2] __attribute__((aligned(4)));
  524. static void set_led_transfer_cb(USBDriver *usbp) {
  525. usb_control_request_t *setup = (usb_control_request_t *)usbp->setup;
  526. if (setup->wLength == 2) {
  527. uint8_t report_id = set_report_buf[0];
  528. if ((report_id == REPORT_ID_KEYBOARD) || (report_id == REPORT_ID_NKRO)) {
  529. keyboard_led_state = set_report_buf[1];
  530. }
  531. } else {
  532. keyboard_led_state = set_report_buf[0];
  533. }
  534. }
  535. static bool usb_requests_hook_cb(USBDriver *usbp) {
  536. usb_control_request_t *setup = (usb_control_request_t *)usbp->setup;
  537. /* Handle HID class specific requests */
  538. if ((setup->bmRequestType & (USB_RTYPE_TYPE_MASK | USB_RTYPE_RECIPIENT_MASK)) == (USB_RTYPE_TYPE_CLASS | USB_RTYPE_RECIPIENT_INTERFACE)) {
  539. switch (setup->bmRequestType & USB_RTYPE_DIR_MASK) {
  540. case USB_RTYPE_DIR_DEV2HOST:
  541. switch (setup->bRequest) {
  542. case HID_REQ_GetReport:
  543. switch (setup->wIndex) {
  544. #ifndef KEYBOARD_SHARED_EP
  545. case KEYBOARD_INTERFACE:
  546. usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, KEYBOARD_REPORT_SIZE, NULL);
  547. return TRUE;
  548. break;
  549. #endif
  550. #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
  551. case MOUSE_INTERFACE:
  552. usbSetupTransfer(usbp, (uint8_t *)&mouse_report_sent, sizeof(mouse_report_sent), NULL);
  553. return TRUE;
  554. break;
  555. #endif
  556. #ifdef SHARED_EP_ENABLE
  557. case SHARED_INTERFACE:
  558. # ifdef KEYBOARD_SHARED_EP
  559. if (setup->wValue.lbyte == REPORT_ID_KEYBOARD) {
  560. usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, KEYBOARD_REPORT_SIZE, NULL);
  561. return true;
  562. }
  563. # endif
  564. # ifdef MOUSE_SHARED_EP
  565. if (setup->wValue.lbyte == REPORT_ID_MOUSE) {
  566. usbSetupTransfer(usbp, (uint8_t *)&mouse_report_sent, sizeof(mouse_report_sent), NULL);
  567. return true;
  568. }
  569. # endif
  570. #endif /* SHARED_EP_ENABLE */
  571. default:
  572. universal_report_blank.report_id = setup->wValue.lbyte;
  573. usbSetupTransfer(usbp, (uint8_t *)&universal_report_blank, setup->wLength, NULL);
  574. return true;
  575. }
  576. break;
  577. case HID_REQ_GetProtocol:
  578. if (setup->wIndex == KEYBOARD_INTERFACE) {
  579. usbSetupTransfer(usbp, &keyboard_protocol, sizeof(uint8_t), NULL);
  580. return true;
  581. }
  582. break;
  583. case HID_REQ_GetIdle:
  584. usbSetupTransfer(usbp, &keyboard_idle, sizeof(uint8_t), NULL);
  585. return true;
  586. }
  587. break;
  588. case USB_RTYPE_DIR_HOST2DEV:
  589. switch (setup->bRequest) {
  590. case HID_REQ_SetReport:
  591. switch (setup->wIndex) {
  592. case KEYBOARD_INTERFACE:
  593. #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
  594. case SHARED_INTERFACE:
  595. #endif
  596. usbSetupTransfer(usbp, set_report_buf, sizeof(set_report_buf), set_led_transfer_cb);
  597. return true;
  598. }
  599. break;
  600. case HID_REQ_SetProtocol:
  601. if (setup->wIndex == KEYBOARD_INTERFACE) {
  602. keyboard_protocol = setup->wValue.word;
  603. #ifdef NKRO_ENABLE
  604. if (!keyboard_protocol && keyboard_idle) {
  605. #else /* NKRO_ENABLE */
  606. if (keyboard_idle) {
  607. #endif /* NKRO_ENABLE */
  608. /* arm the idle timer if boot protocol & idle */
  609. osalSysLockFromISR();
  610. chVTSetI(&keyboard_idle_timer, 4 * TIME_MS2I(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
  611. osalSysUnlockFromISR();
  612. }
  613. }
  614. usbSetupTransfer(usbp, NULL, 0, NULL);
  615. return true;
  616. case HID_REQ_SetIdle:
  617. keyboard_idle = setup->wValue.hbyte;
  618. /* arm the timer */
  619. #ifdef NKRO_ENABLE
  620. if (!keymap_config.nkro && keyboard_idle) {
  621. #else /* NKRO_ENABLE */
  622. if (keyboard_idle) {
  623. #endif /* NKRO_ENABLE */
  624. osalSysLockFromISR();
  625. chVTSetI(&keyboard_idle_timer, 4 * TIME_MS2I(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
  626. osalSysUnlockFromISR();
  627. }
  628. usbSetupTransfer(usbp, NULL, 0, NULL);
  629. return true;
  630. }
  631. break;
  632. }
  633. }
  634. /* Handle the Get_Descriptor Request for HID class, which is not handled by
  635. * the ChibiOS USB driver */
  636. if (((setup->bmRequestType & (USB_RTYPE_DIR_MASK | USB_RTYPE_RECIPIENT_MASK)) == (USB_RTYPE_DIR_DEV2HOST | USB_RTYPE_RECIPIENT_INTERFACE)) && (setup->bRequest == USB_REQ_GET_DESCRIPTOR)) {
  637. const USBDescriptor *descriptor = usbp->config->get_descriptor_cb(usbp, setup->wValue.lbyte, setup->wValue.hbyte, setup->wIndex);
  638. if (descriptor == NULL) {
  639. return false;
  640. }
  641. usbSetupTransfer(usbp, (uint8_t *)descriptor->ud_string, descriptor->ud_size, NULL);
  642. return true;
  643. }
  644. for (int i = 0; i < NUM_USB_DRIVERS; i++) {
  645. if (drivers.array[i].config.int_in) {
  646. // NOTE: Assumes that we only have one serial driver
  647. return qmkusbRequestsHook(usbp);
  648. }
  649. }
  650. return false;
  651. }
  652. static void usb_sof_cb(USBDriver *usbp) {
  653. osalSysLockFromISR();
  654. for (int i = 0; i < NUM_USB_DRIVERS; i++) {
  655. qmkusbSOFHookI(&drivers.array[i].driver);
  656. }
  657. osalSysUnlockFromISR();
  658. }
  659. /* USB driver configuration */
  660. static const USBConfig usbcfg = {
  661. usb_event_cb, /* USB events callback */
  662. usb_get_descriptor_cb, /* Device GET_DESCRIPTOR request callback */
  663. usb_requests_hook_cb, /* Requests hook callback */
  664. usb_sof_cb /* Start Of Frame callback */
  665. };
  666. /*
  667. * Initialize the USB driver
  668. */
  669. void init_usb_driver(USBDriver *usbp) {
  670. for (int i = 0; i < NUM_USB_DRIVERS; i++) {
  671. #ifdef USB_ENDPOINTS_ARE_REORDERABLE
  672. QMKUSBDriver *driver = &drivers.array[i].driver;
  673. drivers.array[i].inout_ep_config.in_state = &drivers.array[i].in_ep_state;
  674. drivers.array[i].inout_ep_config.out_state = &drivers.array[i].out_ep_state;
  675. drivers.array[i].int_ep_config.in_state = &drivers.array[i].int_ep_state;
  676. qmkusbObjectInit(driver, &drivers.array[i].config);
  677. qmkusbStart(driver, &drivers.array[i].config);
  678. #else
  679. QMKUSBDriver *driver = &drivers.array[i].driver;
  680. drivers.array[i].in_ep_config.in_state = &drivers.array[i].in_ep_state;
  681. drivers.array[i].out_ep_config.out_state = &drivers.array[i].out_ep_state;
  682. drivers.array[i].int_ep_config.in_state = &drivers.array[i].int_ep_state;
  683. qmkusbObjectInit(driver, &drivers.array[i].config);
  684. qmkusbStart(driver, &drivers.array[i].config);
  685. #endif
  686. }
  687. /*
  688. * Activates the USB driver and then the USB bus pull-up on D+.
  689. * Note, a delay is inserted in order to not have to disconnect the cable
  690. * after a reset.
  691. */
  692. usbDisconnectBus(usbp);
  693. usbStop(usbp);
  694. wait_ms(50);
  695. usbStart(usbp, &usbcfg);
  696. usbConnectBus(usbp);
  697. chVTObjectInit(&keyboard_idle_timer);
  698. }
  699. __attribute__((weak)) void restart_usb_driver(USBDriver *usbp) {
  700. usbDisconnectBus(usbp);
  701. usbStop(usbp);
  702. #if USB_SUSPEND_WAKEUP_DELAY > 0
  703. // Some hubs, kvm switches, and monitors do
  704. // weird things, with USB device state bouncing
  705. // around wildly on wakeup, yielding race
  706. // conditions that can corrupt the keyboard state.
  707. //
  708. // Pause for a while to let things settle...
  709. wait_ms(USB_SUSPEND_WAKEUP_DELAY);
  710. #endif
  711. usbStart(usbp, &usbcfg);
  712. usbConnectBus(usbp);
  713. }
  714. /* ---------------------------------------------------------
  715. * Keyboard functions
  716. * ---------------------------------------------------------
  717. */
  718. /* Idle requests timer code
  719. * callback (called from ISR, unlocked state) */
  720. static void keyboard_idle_timer_cb(struct ch_virtual_timer *timer, void *arg) {
  721. (void)timer;
  722. USBDriver *usbp = (USBDriver *)arg;
  723. osalSysLockFromISR();
  724. /* check that the states of things are as they're supposed to */
  725. if (usbGetDriverStateI(usbp) != USB_ACTIVE) {
  726. /* do not rearm the timer, should be enabled on IDLE request */
  727. osalSysUnlockFromISR();
  728. return;
  729. }
  730. #ifdef NKRO_ENABLE
  731. if (!keymap_config.nkro && keyboard_idle && keyboard_protocol) {
  732. #else /* NKRO_ENABLE */
  733. if (keyboard_idle && keyboard_protocol) {
  734. #endif /* NKRO_ENABLE */
  735. /* TODO: are we sure we want the KBD_ENDPOINT? */
  736. if (!usbGetTransmitStatusI(usbp, KEYBOARD_IN_EPNUM)) {
  737. usbStartTransmitI(usbp, KEYBOARD_IN_EPNUM, (uint8_t *)&keyboard_report_sent, KEYBOARD_EPSIZE);
  738. }
  739. /* rearm the timer */
  740. chVTSetI(&keyboard_idle_timer, 4 * TIME_MS2I(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
  741. }
  742. /* do not rearm the timer if the condition above fails
  743. * it should be enabled again on either IDLE or SET_PROTOCOL requests */
  744. osalSysUnlockFromISR();
  745. }
  746. /* LED status */
  747. uint8_t keyboard_leds(void) {
  748. return keyboard_led_state;
  749. }
  750. void send_report(uint8_t endpoint, void *report, size_t size) {
  751. osalSysLock();
  752. if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
  753. osalSysUnlock();
  754. return;
  755. }
  756. if (usbGetTransmitStatusI(&USB_DRIVER, endpoint)) {
  757. /* Need to either suspend, or loop and call unlock/lock during
  758. * every iteration - otherwise the system will remain locked,
  759. * no interrupts served, so USB not going through as well.
  760. * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
  761. if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[endpoint]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) {
  762. osalSysUnlock();
  763. return;
  764. }
  765. }
  766. usbStartTransmitI(&USB_DRIVER, endpoint, report, size);
  767. osalSysUnlock();
  768. }
  769. /* prepare and start sending a report IN
  770. * not callable from ISR or locked state */
  771. void send_keyboard(report_keyboard_t *report) {
  772. /* If we're in Boot Protocol, don't send any report ID or other funky fields */
  773. if (!keyboard_protocol) {
  774. send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
  775. } else {
  776. send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);
  777. }
  778. keyboard_report_sent = *report;
  779. }
  780. void send_nkro(report_nkro_t *report) {
  781. #ifdef NKRO_ENABLE
  782. send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t));
  783. #endif
  784. }
  785. /* ---------------------------------------------------------
  786. * Mouse functions
  787. * ---------------------------------------------------------
  788. */
  789. void send_mouse(report_mouse_t *report) {
  790. #ifdef MOUSE_ENABLE
  791. send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t));
  792. mouse_report_sent = *report;
  793. #endif
  794. }
  795. /* ---------------------------------------------------------
  796. * Extrakey functions
  797. * ---------------------------------------------------------
  798. */
  799. void send_extra(report_extra_t *report) {
  800. #ifdef EXTRAKEY_ENABLE
  801. send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t));
  802. #endif
  803. }
  804. void send_programmable_button(report_programmable_button_t *report) {
  805. #ifdef PROGRAMMABLE_BUTTON_ENABLE
  806. send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t));
  807. #endif
  808. }
  809. void send_joystick(report_joystick_t *report) {
  810. #ifdef JOYSTICK_ENABLE
  811. send_report(JOYSTICK_IN_EPNUM, report, sizeof(report_joystick_t));
  812. #endif
  813. }
  814. void send_digitizer(report_digitizer_t *report) {
  815. #ifdef DIGITIZER_ENABLE
  816. send_report(DIGITIZER_IN_EPNUM, report, sizeof(report_digitizer_t));
  817. #endif
  818. }
  819. /* ---------------------------------------------------------
  820. * Console functions
  821. * ---------------------------------------------------------
  822. */
  823. #ifdef CONSOLE_ENABLE
  824. int8_t sendchar(uint8_t c) {
  825. static bool timed_out = false;
  826. /* The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state.
  827. *
  828. * When a 5ms timeout write has timed out, hid_listen is most likely not running, or not
  829. * listening to this keyboard, so we go into the timed_out state. In this state we assume
  830. * that hid_listen is most likely not gonna be connected to us any time soon, so it would
  831. * be wasteful to write follow-up characters with a 5ms timeout, it would all add up and
  832. * unncecessarily slow down the firmware. However instead of just dropping the characters,
  833. * we write them with a TIME_IMMEDIATE timeout, which is a zero timeout,
  834. * and this will succeed only if hid_listen gets connected again. When a write with
  835. * TIME_IMMEDIATE timeout succeeds, we know that hid_listen is listening to us again, and
  836. * we can go back to the timed_out = false state, and following writes will be executed
  837. * with a 5ms timeout. The reason we don't just send all characters with the TIME_IMMEDIATE
  838. * timeout is that this could cause bytes to be lost even if hid_listen is running, if there
  839. * is a lot of data being sent over the console.
  840. *
  841. * This logic will work correctly as long as hid_listen is able to receive at least 200
  842. * bytes per second. On a heavily overloaded machine that's so overloaded that it's
  843. * unusable, and constantly swapping, hid_listen might have trouble receiving 200 bytes per
  844. * second, so some bytes might be lost on the console.
  845. */
  846. const sysinterval_t timeout = timed_out ? TIME_IMMEDIATE : TIME_MS2I(5);
  847. const size_t result = chnWriteTimeout(&drivers.console_driver.driver, &c, 1, timeout);
  848. timed_out = (result == 0);
  849. return result;
  850. }
  851. // Just a dummy function for now, this could be exposed as a weak function
  852. // Or connected to the actual QMK console
  853. static void console_receive(uint8_t *data, uint8_t length) {
  854. (void)data;
  855. (void)length;
  856. }
  857. void console_task(void) {
  858. uint8_t buffer[CONSOLE_EPSIZE];
  859. size_t size = 0;
  860. do {
  861. size = chnReadTimeout(&drivers.console_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
  862. if (size > 0) {
  863. console_receive(buffer, size);
  864. }
  865. } while (size > 0);
  866. }
  867. #endif /* CONSOLE_ENABLE */
  868. #ifdef RAW_ENABLE
  869. void raw_hid_send(uint8_t *data, uint8_t length) {
  870. // TODO: implement variable size packet
  871. if (length != RAW_EPSIZE) {
  872. return;
  873. }
  874. chnWrite(&drivers.raw_driver.driver, data, length);
  875. }
  876. __attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) {
  877. // Users should #include "raw_hid.h" in their own code
  878. // and implement this function there. Leave this as weak linkage
  879. // so users can opt to not handle data coming in.
  880. }
  881. void raw_hid_task(void) {
  882. uint8_t buffer[RAW_EPSIZE];
  883. size_t size = 0;
  884. do {
  885. size = chnReadTimeout(&drivers.raw_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
  886. if (size > 0) {
  887. raw_hid_receive(buffer, size);
  888. }
  889. } while (size > 0);
  890. }
  891. #endif
  892. #ifdef MIDI_ENABLE
  893. void send_midi_packet(MIDI_EventPacket_t *event) {
  894. chnWrite(&drivers.midi_driver.driver, (uint8_t *)event, sizeof(MIDI_EventPacket_t));
  895. }
  896. bool recv_midi_packet(MIDI_EventPacket_t *const event) {
  897. size_t size = chnReadTimeout(&drivers.midi_driver.driver, (uint8_t *)event, sizeof(MIDI_EventPacket_t), TIME_IMMEDIATE);
  898. return size == sizeof(MIDI_EventPacket_t);
  899. }
  900. void midi_ep_task(void) {
  901. uint8_t buffer[MIDI_STREAM_EPSIZE];
  902. size_t size = 0;
  903. do {
  904. size = chnReadTimeout(&drivers.midi_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
  905. if (size > 0) {
  906. MIDI_EventPacket_t event;
  907. recv_midi_packet(&event);
  908. }
  909. } while (size > 0);
  910. }
  911. #endif
  912. #ifdef VIRTSER_ENABLE
  913. void virtser_init(void) {}
  914. void virtser_send(const uint8_t byte) {
  915. chnWrite(&drivers.serial_driver.driver, &byte, 1);
  916. }
  917. __attribute__((weak)) void virtser_recv(uint8_t c) {
  918. // Ignore by default
  919. }
  920. void virtser_task(void) {
  921. uint8_t numBytesReceived = 0;
  922. uint8_t buffer[16];
  923. do {
  924. numBytesReceived = chnReadTimeout(&drivers.serial_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
  925. for (int i = 0; i < numBytesReceived; i++) {
  926. virtser_recv(buffer[i]);
  927. }
  928. } while (numBytesReceived > 0);
  929. }
  930. #endif