usb_main.c (20035B)
1 // Copyright 2023 Stefan Kerkmann 2 // Copyright 2020-2021 Ryan (@fauxpark) 3 // Copyright 2020 Nick Brassel (@tzarc) 4 // Copyright 2020 a-chol 5 // Copyright 2020 xyzz 6 // Copyright 2020 Joel Challis (@zvecr) 7 // Copyright 2020 George (@goshdarnharris) 8 // Copyright 2018 James Laird-Wah 9 // Copyright 2018 Drashna Jaelre (@drashna) 10 // Copyright 2016 Fredizzimo 11 // Copyright 2016 Giovanni Di Sirio 12 // SPDX-License-Identifier: GPL-3.0-or-later OR Apache-2.0 13 14 #include <ch.h> 15 #include <hal.h> 16 #include <string.h> 17 18 #include "usb_main.h" 19 #include "usb_report_handling.h" 20 21 #include "host.h" 22 #include "suspend.h" 23 #include "timer.h" 24 #include "wait.h" 25 #include "usb_endpoints.h" 26 #include "usb_device_state.h" 27 #include "usb_descriptor.h" 28 #include "usb_driver.h" 29 #include "usb_types.h" 30 31 #ifdef RAW_ENABLE 32 # include "raw_hid.h" 33 #endif 34 35 #ifdef NKRO_ENABLE 36 # include "keycode_config.h" 37 38 extern keymap_config_t keymap_config; 39 #endif 40 41 /* --------------------------------------------------------- 42 * Global interface variables and declarations 43 * --------------------------------------------------------- 44 */ 45 46 #ifndef usb_lld_connect_bus 47 # define usb_lld_connect_bus(usbp) 48 #endif 49 50 #ifndef usb_lld_disconnect_bus 51 # define usb_lld_disconnect_bus(usbp) 52 #endif 53 54 extern usb_endpoint_in_t usb_endpoints_in[USB_ENDPOINT_IN_COUNT]; 55 extern usb_endpoint_out_t usb_endpoints_out[USB_ENDPOINT_OUT_COUNT]; 56 57 static bool __attribute__((__unused__)) send_report_buffered(usb_endpoint_in_lut_t endpoint, void *report, size_t size); 58 static void __attribute__((__unused__)) flush_report_buffered(usb_endpoint_in_lut_t endpoint, bool padded); 59 static bool __attribute__((__unused__)) receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t size); 60 61 /* --------------------------------------------------------- 62 * Descriptors and USB driver objects 63 * --------------------------------------------------------- 64 */ 65 66 /* USB Low Level driver specific endpoint fields */ 67 #if !defined(usb_lld_endpoint_fields) 68 # define usb_lld_endpoint_fields \ 69 2, /* IN multiplier */ \ 70 NULL, /* SETUP buffer (not a SETUP endpoint) */ 71 #endif 72 73 /* 74 * Handles the GET_DESCRIPTOR callback 75 * 76 * Returns the proper descriptor 77 */ 78 static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t wIndex) { 79 usb_control_request_t *setup = (usb_control_request_t *)usbp->setup; 80 81 static USBDescriptor descriptor; 82 descriptor.ud_string = NULL; 83 descriptor.ud_size = get_usb_descriptor(setup->wValue.word, setup->wIndex, setup->wLength, (const void **const)&descriptor.ud_string); 84 85 if (descriptor.ud_string == NULL) { 86 return NULL; 87 } 88 89 return &descriptor; 90 } 91 92 /* --------------------------------------------------------- 93 * USB driver functions 94 * --------------------------------------------------------- 95 */ 96 97 #define USB_EVENT_QUEUE_SIZE 16 98 usbevent_t event_queue[USB_EVENT_QUEUE_SIZE]; 99 uint8_t event_queue_head; 100 uint8_t event_queue_tail; 101 102 void usb_event_queue_init(void) { 103 // Initialise the event queue 104 memset(&event_queue, 0, sizeof(event_queue)); 105 event_queue_head = 0; 106 event_queue_tail = 0; 107 } 108 109 static inline bool usb_event_queue_enqueue(usbevent_t event) { 110 uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE; 111 if (next == event_queue_tail) { 112 return false; 113 } 114 event_queue[event_queue_head] = event; 115 event_queue_head = next; 116 return true; 117 } 118 119 static inline bool usb_event_queue_dequeue(usbevent_t *event) { 120 if (event_queue_head == event_queue_tail) { 121 return false; 122 } 123 *event = event_queue[event_queue_tail]; 124 event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE; 125 return true; 126 } 127 128 static inline void usb_event_suspend_handler(void) { 129 usb_device_state_set_suspend(USB_DRIVER.configuration != 0, USB_DRIVER.configuration); 130 } 131 132 static inline void usb_event_wakeup_handler(void) { 133 suspend_wakeup_init(); 134 usb_device_state_set_resume(USB_DRIVER.configuration != 0, USB_DRIVER.configuration); 135 } 136 137 bool last_suspend_state = false; 138 139 void usb_event_queue_task(void) { 140 usbevent_t event; 141 while (usb_event_queue_dequeue(&event)) { 142 switch (event) { 143 case USB_EVENT_SUSPEND: 144 last_suspend_state = true; 145 usb_event_suspend_handler(); 146 break; 147 case USB_EVENT_WAKEUP: 148 last_suspend_state = false; 149 usb_event_wakeup_handler(); 150 break; 151 case USB_EVENT_CONFIGURED: 152 usb_device_state_set_configuration(USB_DRIVER.configuration != 0, USB_DRIVER.configuration); 153 break; 154 case USB_EVENT_UNCONFIGURED: 155 usb_device_state_set_configuration(false, 0); 156 break; 157 case USB_EVENT_RESET: 158 usb_device_state_set_reset(); 159 usb_device_state_set_protocol(USB_PROTOCOL_REPORT); 160 break; 161 default: 162 // Nothing to do, we don't handle it. 163 break; 164 } 165 } 166 } 167 168 /* Handles the USB driver global events. */ 169 static void usb_event_cb(USBDriver *usbp, usbevent_t event) { 170 switch (event) { 171 case USB_EVENT_ADDRESS: 172 return; 173 174 case USB_EVENT_CONFIGURED: 175 osalSysLockFromISR(); 176 for (int i = 0; i < USB_ENDPOINT_IN_COUNT; i++) { 177 usb_endpoint_in_configure_cb(&usb_endpoints_in[i]); 178 } 179 for (int i = 0; i < USB_ENDPOINT_OUT_COUNT; i++) { 180 usb_endpoint_out_configure_cb(&usb_endpoints_out[i]); 181 } 182 osalSysUnlockFromISR(); 183 if (last_suspend_state) { 184 usb_event_queue_enqueue(USB_EVENT_WAKEUP); 185 } 186 usb_event_queue_enqueue(USB_EVENT_CONFIGURED); 187 return; 188 case USB_EVENT_SUSPEND: 189 /* Falls into.*/ 190 case USB_EVENT_UNCONFIGURED: 191 /* Falls into.*/ 192 case USB_EVENT_RESET: 193 usb_event_queue_enqueue(event); 194 chSysLockFromISR(); 195 for (int i = 0; i < USB_ENDPOINT_IN_COUNT; i++) { 196 usb_endpoint_in_suspend_cb(&usb_endpoints_in[i]); 197 } 198 for (int i = 0; i < USB_ENDPOINT_OUT_COUNT; i++) { 199 usb_endpoint_out_suspend_cb(&usb_endpoints_out[i]); 200 } 201 chSysUnlockFromISR(); 202 return; 203 204 case USB_EVENT_WAKEUP: 205 chSysLockFromISR(); 206 for (int i = 0; i < USB_ENDPOINT_IN_COUNT; i++) { 207 usb_endpoint_in_wakeup_cb(&usb_endpoints_in[i]); 208 } 209 for (int i = 0; i < USB_ENDPOINT_OUT_COUNT; i++) { 210 usb_endpoint_out_wakeup_cb(&usb_endpoints_out[i]); 211 } 212 chSysUnlockFromISR(); 213 usb_event_queue_enqueue(USB_EVENT_WAKEUP); 214 return; 215 216 case USB_EVENT_STALLED: 217 return; 218 } 219 } 220 221 /* 222 * Appendix G: HID Request Support Requirements 223 * 224 * The following table enumerates the requests that need to be supported by various types of HID class devices. 225 * Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol 226 * ------------------------------------------------------------------------------------------ 227 * Boot Mouse Required Optional Optional Optional Required Required 228 * Non-Boot Mouse Required Optional Optional Optional Optional Optional 229 * Boot Keyboard Required Optional Required Required Required Required 230 * Non-Boot Keybrd Required Optional Required Required Optional Optional 231 * Other Device Required Optional Optional Optional Optional Optional 232 */ 233 234 static uint8_t _Alignas(4) set_report_buf[2]; 235 236 static void set_led_transfer_cb(USBDriver *usbp) { 237 usb_control_request_t *setup = (usb_control_request_t *)usbp->setup; 238 239 if (setup->wLength == 2) { 240 uint8_t report_id = set_report_buf[0]; 241 if ((report_id == REPORT_ID_KEYBOARD) || (report_id == REPORT_ID_NKRO)) { 242 usb_device_state_set_leds(set_report_buf[1]); 243 } 244 } else { 245 usb_device_state_set_leds(set_report_buf[0]); 246 } 247 } 248 249 static bool usb_requests_hook_cb(USBDriver *usbp) { 250 usb_control_request_t *setup = (usb_control_request_t *)usbp->setup; 251 252 /* Handle HID class specific requests */ 253 if ((setup->bmRequestType & (USB_RTYPE_TYPE_MASK | USB_RTYPE_RECIPIENT_MASK)) == (USB_RTYPE_TYPE_CLASS | USB_RTYPE_RECIPIENT_INTERFACE)) { 254 switch (setup->bmRequestType & USB_RTYPE_DIR_MASK) { 255 case USB_RTYPE_DIR_DEV2HOST: 256 switch (setup->bRequest) { 257 case HID_REQ_GetReport: 258 return usb_get_report_cb(usbp); 259 case HID_REQ_GetProtocol: 260 if (setup->wIndex == KEYBOARD_INTERFACE) { 261 static uint8_t keyboard_protocol; 262 keyboard_protocol = usb_device_state_get_protocol(); 263 usbSetupTransfer(usbp, &keyboard_protocol, sizeof(keyboard_protocol), NULL); 264 return true; 265 } 266 break; 267 268 case HID_REQ_GetIdle: 269 return usb_get_idle_cb(usbp); 270 } 271 272 case USB_RTYPE_DIR_HOST2DEV: 273 switch (setup->bRequest) { 274 case HID_REQ_SetReport: 275 switch (setup->wIndex) { 276 case KEYBOARD_INTERFACE: 277 #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP) 278 case SHARED_INTERFACE: 279 #endif 280 usbSetupTransfer(usbp, set_report_buf, sizeof(set_report_buf), set_led_transfer_cb); 281 return true; 282 } 283 break; 284 case HID_REQ_SetProtocol: 285 if (setup->wIndex == KEYBOARD_INTERFACE) { 286 usb_device_state_set_protocol(setup->wValue.lbyte); 287 } 288 usbSetupTransfer(usbp, NULL, 0, NULL); 289 return true; 290 case HID_REQ_SetIdle: 291 usb_device_state_set_idle_rate(setup->wValue.hbyte); 292 return usb_set_idle_cb(usbp); 293 } 294 break; 295 } 296 } 297 298 /* Handle the Get_Descriptor Request for HID class, which is not handled by 299 * the ChibiOS USB driver */ 300 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)) { 301 const USBDescriptor *descriptor = usbp->config->get_descriptor_cb(usbp, setup->wValue.lbyte, setup->wValue.hbyte, setup->wIndex); 302 if (descriptor == NULL) { 303 return false; 304 } 305 usbSetupTransfer(usbp, (uint8_t *)descriptor->ud_string, descriptor->ud_size, NULL); 306 return true; 307 } 308 309 for (int i = 0; i < USB_ENDPOINT_IN_COUNT; i++) { 310 if (usb_endpoints_in[i].usb_requests_cb != NULL) { 311 if (usb_endpoints_in[i].usb_requests_cb(usbp)) { 312 return true; 313 } 314 } 315 } 316 317 return false; 318 } 319 320 static const USBConfig usbcfg = { 321 usb_event_cb, /* USB events callback */ 322 usb_get_descriptor_cb, /* Device GET_DESCRIPTOR request callback */ 323 usb_requests_hook_cb, /* Requests hook callback */ 324 }; 325 326 void init_usb_driver(USBDriver *usbp) { 327 for (int i = 0; i < USB_ENDPOINT_IN_COUNT; i++) { 328 usb_endpoint_in_init(&usb_endpoints_in[i]); 329 usb_endpoint_in_start(&usb_endpoints_in[i]); 330 } 331 332 for (int i = 0; i < USB_ENDPOINT_OUT_COUNT; i++) { 333 usb_endpoint_out_init(&usb_endpoints_out[i]); 334 usb_endpoint_out_start(&usb_endpoints_out[i]); 335 } 336 337 /* 338 * Activates the USB driver and then the USB bus pull-up on D+. 339 * Note, a delay is inserted in order to not have to disconnect the cable 340 * after a reset. 341 */ 342 usbDisconnectBus(usbp); 343 usbStop(usbp); 344 wait_ms(50); 345 usbStart(usbp, &usbcfg); 346 usbConnectBus(usbp); 347 } 348 349 __attribute__((weak)) void restart_usb_driver(USBDriver *usbp) { 350 usbDisconnectBus(usbp); 351 usbStop(usbp); 352 353 for (int i = 0; i < USB_ENDPOINT_IN_COUNT; i++) { 354 usb_endpoint_in_stop(&usb_endpoints_in[i]); 355 } 356 357 for (int i = 0; i < USB_ENDPOINT_OUT_COUNT; i++) { 358 usb_endpoint_out_stop(&usb_endpoints_out[i]); 359 } 360 361 wait_ms(50); 362 363 for (int i = 0; i < USB_ENDPOINT_IN_COUNT; i++) { 364 usb_endpoint_in_init(&usb_endpoints_in[i]); 365 usb_endpoint_in_start(&usb_endpoints_in[i]); 366 } 367 368 for (int i = 0; i < USB_ENDPOINT_OUT_COUNT; i++) { 369 usb_endpoint_out_init(&usb_endpoints_out[i]); 370 usb_endpoint_out_start(&usb_endpoints_out[i]); 371 } 372 373 usbStart(usbp, &usbcfg); 374 usbConnectBus(usbp); 375 } 376 377 /* --------------------------------------------------------- 378 * Keyboard functions 379 * --------------------------------------------------------- 380 */ 381 382 /** 383 * @brief Send a report to the host, the report is enqueued into an output 384 * queue and send once the USB endpoint becomes empty. 385 * 386 * @param endpoint USB IN endpoint to send the report from 387 * @param report pointer to the report 388 * @param size size of the report 389 * @return true Success 390 * @return false Failure 391 */ 392 bool send_report(usb_endpoint_in_lut_t endpoint, void *report, size_t size) { 393 return usb_endpoint_in_send(&usb_endpoints_in[endpoint], (uint8_t *)report, size, TIME_MS2I(100), false); 394 } 395 396 /** 397 * @brief Send a report to the host, but delay the sending until the size of 398 * endpoint report is reached or the incompletely filled buffer is flushed with 399 * a call to `flush_report_buffered`. This is useful if the report is being 400 * updated frequently. The complete report is then enqueued into an output 401 * queue and send once the USB endpoint becomes empty. 402 * 403 * @param endpoint USB IN endpoint to send the report from 404 * @param report pointer to the report 405 * @param size size of the report 406 * @return true Success 407 * @return false Failure 408 */ 409 static bool send_report_buffered(usb_endpoint_in_lut_t endpoint, void *report, size_t size) { 410 return usb_endpoint_in_send(&usb_endpoints_in[endpoint], (uint8_t *)report, size, TIME_MS2I(100), true); 411 } 412 413 /** @brief Flush all buffered reports which were enqueued with a call to 414 * `send_report_buffered` that haven't been send. If necessary the buffered 415 * report can be padded with zeros up to the endpoints maximum size. 416 * 417 * @param endpoint USB IN endpoint to flush the reports from 418 * @param padded Pad the buffered report with zeros up to the endpoints maximum size 419 */ 420 static void flush_report_buffered(usb_endpoint_in_lut_t endpoint, bool padded) { 421 usb_endpoint_in_flush(&usb_endpoints_in[endpoint], padded); 422 } 423 424 /** 425 * @brief Receive a report from the host. 426 * 427 * @param endpoint USB OUT endpoint to receive the report from 428 * @param report pointer to the report 429 * @param size size of the report 430 * @return true Success 431 * @return false Failure 432 */ 433 static bool receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t size) { 434 return usb_endpoint_out_receive(&usb_endpoints_out[endpoint], (uint8_t *)report, size, TIME_IMMEDIATE); 435 } 436 437 void send_keyboard(report_keyboard_t *report) { 438 /* If we're in Boot Protocol, don't send any report ID or other funky fields */ 439 if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) { 440 send_report(USB_ENDPOINT_IN_KEYBOARD, &report->mods, 8); 441 } else { 442 send_report(USB_ENDPOINT_IN_KEYBOARD, report, KEYBOARD_REPORT_SIZE); 443 } 444 } 445 446 void send_nkro(report_nkro_t *report) { 447 #ifdef NKRO_ENABLE 448 send_report(USB_ENDPOINT_IN_SHARED, report, sizeof(report_nkro_t)); 449 #endif 450 } 451 452 /* --------------------------------------------------------- 453 * Mouse functions 454 * --------------------------------------------------------- 455 */ 456 457 void send_mouse(report_mouse_t *report) { 458 #ifdef MOUSE_ENABLE 459 send_report(USB_ENDPOINT_IN_MOUSE, report, sizeof(report_mouse_t)); 460 #endif 461 } 462 463 /* --------------------------------------------------------- 464 * Extrakey functions 465 * --------------------------------------------------------- 466 */ 467 468 void send_extra(report_extra_t *report) { 469 #ifdef EXTRAKEY_ENABLE 470 send_report(USB_ENDPOINT_IN_SHARED, report, sizeof(report_extra_t)); 471 #endif 472 } 473 474 void send_programmable_button(report_programmable_button_t *report) { 475 #ifdef PROGRAMMABLE_BUTTON_ENABLE 476 send_report(USB_ENDPOINT_IN_SHARED, report, sizeof(report_programmable_button_t)); 477 #endif 478 } 479 480 void send_joystick(report_joystick_t *report) { 481 #ifdef JOYSTICK_ENABLE 482 send_report(USB_ENDPOINT_IN_JOYSTICK, report, sizeof(report_joystick_t)); 483 #endif 484 } 485 486 void send_digitizer(report_digitizer_t *report) { 487 #ifdef DIGITIZER_ENABLE 488 send_report(USB_ENDPOINT_IN_DIGITIZER, report, sizeof(report_digitizer_t)); 489 #endif 490 } 491 492 /* --------------------------------------------------------- 493 * Console functions 494 * --------------------------------------------------------- 495 */ 496 497 #ifdef CONSOLE_ENABLE 498 499 int8_t sendchar(uint8_t c) { 500 return (int8_t)send_report_buffered(USB_ENDPOINT_IN_CONSOLE, &c, sizeof(uint8_t)); 501 } 502 503 void console_task(void) { 504 flush_report_buffered(USB_ENDPOINT_IN_CONSOLE, true); 505 } 506 507 #endif /* CONSOLE_ENABLE */ 508 509 #ifdef RAW_ENABLE 510 void send_raw_hid(uint8_t *data, uint8_t length) { 511 if (length != RAW_EPSIZE) { 512 return; 513 } 514 send_report(USB_ENDPOINT_IN_RAW, data, length); 515 } 516 517 void raw_hid_task(void) { 518 uint8_t buffer[RAW_EPSIZE]; 519 while (receive_report(USB_ENDPOINT_OUT_RAW, buffer, sizeof(buffer))) { 520 raw_hid_receive(buffer, sizeof(buffer)); 521 } 522 } 523 524 #endif 525 526 #ifdef MIDI_ENABLE 527 528 void send_midi_packet(MIDI_EventPacket_t *event) { 529 send_report(USB_ENDPOINT_IN_MIDI, (uint8_t *)event, sizeof(MIDI_EventPacket_t)); 530 } 531 532 bool recv_midi_packet(MIDI_EventPacket_t *const event) { 533 return receive_report(USB_ENDPOINT_OUT_MIDI, (uint8_t *)event, sizeof(MIDI_EventPacket_t)); 534 } 535 536 #endif 537 538 #ifdef VIRTSER_ENABLE 539 540 # include "hal_usb_cdc.h" 541 /** 542 * @brief CDC serial driver configuration structure. Set to 9600 baud, 1 stop bit, no parity, 8 data bits. 543 */ 544 static cdc_linecoding_t linecoding = {{0x00, 0x96, 0x00, 0x00}, LC_STOP_1, LC_PARITY_NONE, 8}; 545 546 bool virtser_usb_request_cb(USBDriver *usbp) { 547 if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) { /* bmRequestType */ 548 if (usbp->setup[4] == CCI_INTERFACE) { /* wIndex (LSB) */ 549 switch (usbp->setup[1]) { /* bRequest */ 550 case CDC_GET_LINE_CODING: 551 usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL); 552 return true; 553 case CDC_SET_LINE_CODING: 554 usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL); 555 return true; 556 case CDC_SET_CONTROL_LINE_STATE: 557 /* Nothing to do, there are no control lines.*/ 558 usbSetupTransfer(usbp, NULL, 0, NULL); 559 return true; 560 default: 561 return false; 562 } 563 } 564 } 565 566 return false; 567 } 568 569 void virtser_init(void) {} 570 571 void virtser_send(const uint8_t byte) { 572 send_report_buffered(USB_ENDPOINT_IN_CDC_DATA, (void *)&byte, sizeof(byte)); 573 } 574 575 __attribute__((weak)) void virtser_recv(uint8_t c) { 576 // Ignore by default 577 } 578 579 void virtser_task(void) { 580 uint8_t buffer[CDC_EPSIZE]; 581 while (receive_report(USB_ENDPOINT_OUT_CDC_DATA, buffer, sizeof(buffer))) { 582 for (int i = 0; i < sizeof(buffer); i++) { 583 virtser_recv(buffer[i]); 584 } 585 } 586 587 flush_report_buffered(USB_ENDPOINT_IN_CDC_DATA, false); 588 } 589 590 #endif