lufa.c (25584B)
1 /* 2 * Copyright 2012 Jun Wako <wakojun@gmail.com> 3 * This file is based on: 4 * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse 5 * LUFA-120219/Demos/Device/Lowlevel/GenericHID 6 */ 7 8 /* 9 LUFA Library 10 Copyright (C) Dean Camera, 2012. 11 12 dean [at] fourwalledcubicle [dot] com 13 www.lufa-lib.org 14 */ 15 16 /* 17 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) 18 Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) 19 20 Permission to use, copy, modify, distribute, and sell this 21 software and its documentation for any purpose is hereby granted 22 without fee, provided that the above copyright notice appear in 23 all copies and that both that the copyright notice and this 24 permission notice and warranty disclaimer appear in supporting 25 documentation, and that the name of the author not be used in 26 advertising or publicity pertaining to distribution of the 27 software without specific, written prior permission. 28 29 The author disclaim all warranties with regard to this 30 software, including all implied warranties of merchantability 31 and fitness. In no event shall the author be liable for any 32 special, indirect or consequential damages or any damages 33 whatsoever resulting from loss of use, data or profits, whether 34 in an action of contract, negligence or other tortious action, 35 arising out of or in connection with the use or performance of 36 this software. 37 */ 38 39 #include "report.h" 40 #include "host.h" 41 #include "host_driver.h" 42 #include "keyboard.h" 43 #include "action.h" 44 #include "led.h" 45 #include "sendchar.h" 46 #include "debug.h" 47 #include "suspend.h" 48 #include "wait.h" 49 50 #include "usb_descriptor.h" 51 #include "lufa.h" 52 #include "usb_device_state.h" 53 #include <util/atomic.h> 54 55 #ifdef VIRTSER_ENABLE 56 # include "virtser.h" 57 #endif 58 59 #ifdef MIDI_ENABLE 60 # include "qmk_midi.h" 61 #endif 62 63 #ifdef RAW_ENABLE 64 # include "raw_hid.h" 65 #endif 66 67 #ifdef WAIT_FOR_USB 68 // TODO: Remove backwards compatibility with old define 69 # define USB_WAIT_FOR_ENUMERATION 70 #endif 71 72 static report_keyboard_t keyboard_report_sent; 73 74 /* Host driver */ 75 static void send_keyboard(report_keyboard_t *report); 76 static void send_nkro(report_nkro_t *report); 77 static void send_mouse(report_mouse_t *report); 78 static void send_extra(report_extra_t *report); 79 #ifdef RAW_ENABLE 80 static void send_raw_hid(uint8_t *data, uint8_t length); 81 #endif 82 83 host_driver_t lufa_driver = { 84 .keyboard_leds = usb_device_state_get_leds, 85 .send_keyboard = send_keyboard, 86 .send_nkro = send_nkro, 87 .send_mouse = send_mouse, 88 .send_extra = send_extra, 89 #ifdef RAW_ENABLE 90 .send_raw_hid = send_raw_hid, 91 #endif 92 }; 93 94 void send_report(uint8_t endpoint, void *report, size_t size) { 95 uint8_t timeout = 255; 96 97 if (USB_DeviceState != DEVICE_STATE_Configured) return; 98 99 Endpoint_SelectEndpoint(endpoint); 100 101 /* Check if write ready for a polling interval around 10ms */ 102 while (timeout-- && !Endpoint_IsReadWriteAllowed()) { 103 _delay_us(40); 104 } 105 if (!Endpoint_IsReadWriteAllowed()) return; 106 107 Endpoint_Write_Stream_LE(report, size, NULL); 108 Endpoint_ClearIN(); 109 } 110 111 #ifdef VIRTSER_ENABLE 112 // clang-format off 113 114 USB_ClassInfo_CDC_Device_t cdc_device = { 115 .Config = { 116 .ControlInterfaceNumber = CCI_INTERFACE, 117 .DataINEndpoint = { 118 .Address = (CDC_IN_EPNUM | ENDPOINT_DIR_IN), 119 .Size = CDC_EPSIZE, 120 .Banks = 1 121 }, 122 .DataOUTEndpoint = { 123 .Address = (CDC_OUT_EPNUM | ENDPOINT_DIR_OUT), 124 .Size = CDC_EPSIZE, 125 .Banks = 1 126 }, 127 .NotificationEndpoint = { 128 .Address = (CDC_NOTIFICATION_EPNUM | ENDPOINT_DIR_IN), 129 .Size = CDC_NOTIFICATION_EPSIZE, 130 .Banks = 1 131 } 132 } 133 }; 134 135 // clang-format on 136 #endif 137 138 #ifdef RAW_ENABLE 139 140 /** \brief Raw HID Send 141 * 142 * FIXME: Needs doc 143 */ 144 static void send_raw_hid(uint8_t *data, uint8_t length) { 145 if (length != RAW_EPSIZE) return; 146 send_report(RAW_IN_EPNUM, data, RAW_EPSIZE); 147 } 148 149 /** \brief Raw HID Task 150 * 151 * FIXME: Needs doc 152 */ 153 void raw_hid_task(void) { 154 // Create a temporary buffer to hold the read in data from the host 155 uint8_t data[RAW_EPSIZE]; 156 bool data_read = false; 157 158 // Device must be connected and configured for the task to run 159 if (USB_DeviceState != DEVICE_STATE_Configured) return; 160 161 Endpoint_SelectEndpoint(RAW_OUT_EPNUM); 162 163 // Check to see if a packet has been sent from the host 164 if (Endpoint_IsOUTReceived()) { 165 // Check to see if the packet contains data 166 if (Endpoint_IsReadWriteAllowed()) { 167 /* Read data */ 168 Endpoint_Read_Stream_LE(data, sizeof(data), NULL); 169 data_read = true; 170 } 171 172 // Finalize the stream transfer to receive the last packet 173 Endpoint_ClearOUT(); 174 175 if (data_read) { 176 raw_hid_receive(data, sizeof(data)); 177 } 178 } 179 } 180 #endif 181 182 /******************************************************************************* 183 * Console 184 ******************************************************************************/ 185 #ifdef CONSOLE_ENABLE 186 /** \brief Console Tasks 187 * 188 * FIXME: Needs doc 189 */ 190 static void console_flush_task(void) { 191 /* Device must be connected and configured for the task to run */ 192 if (USB_DeviceState != DEVICE_STATE_Configured) return; 193 194 uint8_t ep = Endpoint_GetCurrentEndpoint(); 195 196 /* IN packet */ 197 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM); 198 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) { 199 Endpoint_SelectEndpoint(ep); 200 return; 201 } 202 203 // fill empty bank 204 while (Endpoint_IsReadWriteAllowed()) 205 Endpoint_Write_8(0); 206 207 // flush sendchar packet 208 if (Endpoint_IsINReady()) { 209 Endpoint_ClearIN(); 210 } 211 212 Endpoint_SelectEndpoint(ep); 213 } 214 215 void console_task(void) { 216 // do nothing 217 } 218 #endif 219 220 /******************************************************************************* 221 * USB Events 222 ******************************************************************************/ 223 /* 224 * Event Order of Plug in: 225 * 0) EVENT_USB_Device_Connect 226 * 1) EVENT_USB_Device_Suspend 227 * 2) EVENT_USB_Device_Reset 228 * 3) EVENT_USB_Device_Wake 229 */ 230 /** \brief Event USB Device Connect 231 * 232 * FIXME: Needs doc 233 */ 234 void EVENT_USB_Device_Connect(void) { 235 print("[C]"); 236 /* For battery powered device */ 237 if (!USB_IsInitialized) { 238 USB_Disable(); 239 USB_Init(); 240 USB_Device_EnableSOFEvents(); 241 } 242 } 243 244 /** \brief Event USB Device Connect 245 * 246 * FIXME: Needs doc 247 */ 248 void EVENT_USB_Device_Disconnect(void) { 249 print("[D]"); 250 /* For battery powered device */ 251 USB_IsInitialized = false; 252 /* TODO: This doesn't work. After several plug in/outs can not be enumerated. 253 if (USB_IsInitialized) { 254 USB_Disable(); // Disable all interrupts 255 USB_Controller_Enable(); 256 USB_INT_Enable(USB_INT_VBUSTI); 257 } 258 */ 259 } 260 261 /** \brief Event USB Device Connect 262 * 263 * FIXME: Needs doc 264 */ 265 void EVENT_USB_Device_Reset(void) { 266 print("[R]"); 267 usb_device_state_set_reset(); 268 usb_device_state_set_protocol(USB_PROTOCOL_REPORT); 269 } 270 271 /** \brief Event USB Device Connect 272 * 273 * FIXME: Needs doc 274 */ 275 void EVENT_USB_Device_Suspend(void) { 276 print("[S]"); 277 usb_device_state_set_suspend(USB_Device_ConfigurationNumber != 0, USB_Device_ConfigurationNumber); 278 } 279 280 /** \brief Event USB Device Connect 281 * 282 * FIXME: Needs doc 283 */ 284 void EVENT_USB_Device_WakeUp(void) { 285 print("[W]"); 286 #if defined(NO_USB_STARTUP_CHECK) 287 suspend_wakeup_init(); 288 #endif 289 290 usb_device_state_set_resume(USB_DeviceState == DEVICE_STATE_Configured, USB_Device_ConfigurationNumber); 291 } 292 293 #ifdef CONSOLE_ENABLE 294 static bool console_flush = false; 295 # define CONSOLE_FLUSH_SET(b) \ 296 do { \ 297 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { \ 298 console_flush = b; \ 299 } \ 300 } while (0) 301 302 /** \brief Event USB Device Start Of Frame 303 * 304 * FIXME: Needs doc 305 * called every 1ms 306 */ 307 void EVENT_USB_Device_StartOfFrame(void) { 308 static uint8_t count; 309 if (++count % 50) return; 310 count = 0; 311 312 if (!console_flush) return; 313 console_flush_task(); 314 console_flush = false; 315 } 316 317 #endif 318 319 /** \brief Event handler for the USB_ConfigurationChanged event. 320 * 321 * This is fired when the host sets the current configuration of the USB device after enumeration. 322 * 323 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4, 324 * it is safe to use single bank for all endpoints. 325 */ 326 void EVENT_USB_Device_ConfigurationChanged(void) { 327 bool ConfigSuccess = true; 328 329 #ifndef KEYBOARD_SHARED_EP 330 /* Setup keyboard report endpoint */ 331 ConfigSuccess &= Endpoint_ConfigureEndpoint((KEYBOARD_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, KEYBOARD_EPSIZE, 1); 332 #endif 333 334 #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) 335 /* Setup mouse report endpoint */ 336 ConfigSuccess &= Endpoint_ConfigureEndpoint((MOUSE_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, MOUSE_EPSIZE, 1); 337 #endif 338 339 #ifdef SHARED_EP_ENABLE 340 /* Setup shared report endpoint */ 341 ConfigSuccess &= Endpoint_ConfigureEndpoint((SHARED_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, SHARED_EPSIZE, 1); 342 #endif 343 344 #ifdef RAW_ENABLE 345 /* Setup raw HID endpoints */ 346 ConfigSuccess &= Endpoint_ConfigureEndpoint((RAW_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, RAW_EPSIZE, 1); 347 ConfigSuccess &= Endpoint_ConfigureEndpoint((RAW_OUT_EPNUM | ENDPOINT_DIR_OUT), EP_TYPE_INTERRUPT, RAW_EPSIZE, 1); 348 #endif 349 350 #ifdef CONSOLE_ENABLE 351 /* Setup console endpoint */ 352 ConfigSuccess &= Endpoint_ConfigureEndpoint((CONSOLE_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, CONSOLE_EPSIZE, 1); 353 #endif 354 355 #ifdef MIDI_ENABLE 356 /* Setup MIDI stream endpoints */ 357 ConfigSuccess &= Endpoint_ConfigureEndpoint((MIDI_STREAM_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_BULK, MIDI_STREAM_EPSIZE, 1); 358 ConfigSuccess &= Endpoint_ConfigureEndpoint((MIDI_STREAM_OUT_EPNUM | ENDPOINT_DIR_OUT), EP_TYPE_BULK, MIDI_STREAM_EPSIZE, 1); 359 #endif 360 361 #ifdef VIRTSER_ENABLE 362 /* Setup virtual serial endpoints */ 363 ConfigSuccess &= Endpoint_ConfigureEndpoint((CDC_NOTIFICATION_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, 1); 364 ConfigSuccess &= Endpoint_ConfigureEndpoint((CDC_OUT_EPNUM | ENDPOINT_DIR_OUT), EP_TYPE_BULK, CDC_EPSIZE, 1); 365 ConfigSuccess &= Endpoint_ConfigureEndpoint((CDC_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_BULK, CDC_EPSIZE, 1); 366 #endif 367 368 #if defined(JOYSTICK_ENABLE) && !defined(JOYSTICK_SHARED_EP) 369 /* Setup joystick endpoint */ 370 ConfigSuccess &= Endpoint_ConfigureEndpoint((JOYSTICK_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1); 371 #endif 372 373 #if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP) 374 /* Setup digitizer endpoint */ 375 ConfigSuccess &= Endpoint_ConfigureEndpoint((DIGITIZER_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, DIGITIZER_EPSIZE, 1); 376 #endif 377 378 usb_device_state_set_configuration(USB_DeviceState == DEVICE_STATE_Configured, USB_Device_ConfigurationNumber); 379 } 380 381 /* FIXME: Expose this table in the docs somehow 382 Appendix G: HID Request Support Requirements 383 384 The following table enumerates the requests that need to be supported by various types of HID class devices. 385 386 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol 387 ------------------------------------------------------------------------------------------ 388 Boot Mouse Required Optional Optional Optional Required Required 389 Non-Boot Mouse Required Optional Optional Optional Optional Optional 390 Boot Keyboard Required Optional Required Required Required Required 391 Non-Boot Keybrd Required Optional Required Required Optional Optional 392 Other Device Required Optional Optional Optional Optional Optional 393 */ 394 /** \brief Event handler for the USB_ControlRequest event. 395 * 396 * This is fired before passing along unhandled control requests to the library for processing internally. 397 */ 398 void EVENT_USB_Device_ControlRequest(void) { 399 uint8_t *ReportData = NULL; 400 uint8_t ReportSize = 0; 401 402 /* Handle HID Class specific requests */ 403 switch (USB_ControlRequest.bRequest) { 404 case HID_REQ_GetReport: 405 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { 406 Endpoint_ClearSETUP(); 407 408 // Interface 409 switch (USB_ControlRequest.wIndex) { 410 case KEYBOARD_INTERFACE: 411 // TODO: test/check 412 ReportData = (uint8_t *)&keyboard_report_sent; 413 ReportSize = sizeof(keyboard_report_sent); 414 break; 415 } 416 417 /* Write the report data to the control endpoint */ 418 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); 419 Endpoint_ClearOUT(); 420 } 421 422 break; 423 case HID_REQ_SetReport: 424 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { 425 // Interface 426 switch (USB_ControlRequest.wIndex) { 427 case KEYBOARD_INTERFACE: 428 #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP) 429 case SHARED_INTERFACE: 430 #endif 431 Endpoint_ClearSETUP(); 432 433 while (!(Endpoint_IsOUTReceived())) { 434 if (USB_DeviceState == DEVICE_STATE_Unattached) return; 435 } 436 437 if (Endpoint_BytesInEndpoint() == 2) { 438 uint8_t report_id = Endpoint_Read_8(); 439 440 if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) { 441 usb_device_state_set_leds(Endpoint_Read_8()); 442 } 443 } else { 444 usb_device_state_set_leds(Endpoint_Read_8()); 445 } 446 447 Endpoint_ClearOUT(); 448 Endpoint_ClearStatusStage(); 449 break; 450 } 451 } 452 453 break; 454 455 case HID_REQ_GetProtocol: 456 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { 457 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) { 458 Endpoint_ClearSETUP(); 459 while (!(Endpoint_IsINReady())) 460 ; 461 Endpoint_Write_8(usb_device_state_get_protocol()); 462 Endpoint_ClearIN(); 463 Endpoint_ClearStatusStage(); 464 } 465 } 466 467 break; 468 case HID_REQ_SetProtocol: 469 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { 470 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) { 471 Endpoint_ClearSETUP(); 472 Endpoint_ClearStatusStage(); 473 474 usb_device_state_set_protocol(USB_ControlRequest.wValue & 0xFF); 475 clear_keyboard(); 476 } 477 } 478 479 break; 480 case HID_REQ_SetIdle: 481 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { 482 Endpoint_ClearSETUP(); 483 Endpoint_ClearStatusStage(); 484 485 usb_device_state_set_idle_rate(USB_ControlRequest.wValue >> 8); 486 } 487 488 break; 489 case HID_REQ_GetIdle: 490 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { 491 Endpoint_ClearSETUP(); 492 while (!(Endpoint_IsINReady())) 493 ; 494 Endpoint_Write_8(usb_device_state_get_idle_rate()); 495 Endpoint_ClearIN(); 496 Endpoint_ClearStatusStage(); 497 } 498 499 break; 500 } 501 502 #ifdef VIRTSER_ENABLE 503 CDC_Device_ProcessControlRequest(&cdc_device); 504 #endif 505 } 506 507 /******************************************************************************* 508 * Host driver 509 ******************************************************************************/ 510 511 /** \brief Send Keyboard 512 * 513 * FIXME: Needs doc 514 */ 515 static void send_keyboard(report_keyboard_t *report) { 516 /* If we're in Boot Protocol, don't send any report ID or other funky fields */ 517 if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) { 518 send_report(KEYBOARD_IN_EPNUM, &report->mods, 8); 519 } else { 520 send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE); 521 } 522 523 keyboard_report_sent = *report; 524 } 525 526 /** \brief Send NKRO 527 * 528 * FIXME: Needs doc 529 */ 530 static void send_nkro(report_nkro_t *report) { 531 #ifdef NKRO_ENABLE 532 send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t)); 533 #endif 534 } 535 536 /** \brief Send Mouse 537 * 538 * FIXME: Needs doc 539 */ 540 static void send_mouse(report_mouse_t *report) { 541 #ifdef MOUSE_ENABLE 542 send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t)); 543 #endif 544 } 545 546 /** \brief Send Extra 547 * 548 * FIXME: Needs doc 549 */ 550 static void send_extra(report_extra_t *report) { 551 #ifdef EXTRAKEY_ENABLE 552 send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t)); 553 #endif 554 } 555 556 void send_joystick(report_joystick_t *report) { 557 #ifdef JOYSTICK_ENABLE 558 send_report(JOYSTICK_IN_EPNUM, report, sizeof(report_joystick_t)); 559 #endif 560 } 561 562 void send_programmable_button(report_programmable_button_t *report) { 563 #ifdef PROGRAMMABLE_BUTTON_ENABLE 564 send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t)); 565 #endif 566 } 567 568 void send_digitizer(report_digitizer_t *report) { 569 #ifdef DIGITIZER_ENABLE 570 send_report(DIGITIZER_IN_EPNUM, report, sizeof(report_digitizer_t)); 571 #endif 572 } 573 574 /******************************************************************************* 575 * sendchar 576 ******************************************************************************/ 577 #ifdef CONSOLE_ENABLE 578 # define SEND_TIMEOUT 5 579 /** \brief Send Char 580 * 581 * FIXME: Needs doc 582 */ 583 int8_t sendchar(uint8_t c) { 584 // Do not wait if the previous write has timed_out. 585 // Because sendchar() is called so many times, waiting each call causes big lag. 586 // The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state. 587 static bool timed_out = false; 588 589 // prevents console_flush_task() from running during sendchar() runs. 590 // or char will be lost. These two function is mutually exclusive. 591 CONSOLE_FLUSH_SET(false); 592 593 if (USB_DeviceState != DEVICE_STATE_Configured) return -1; 594 595 uint8_t ep = Endpoint_GetCurrentEndpoint(); 596 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM); 597 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) { 598 goto ERROR_EXIT; 599 } 600 601 if (timed_out && !Endpoint_IsReadWriteAllowed()) { 602 goto ERROR_EXIT; 603 } 604 605 timed_out = false; 606 607 uint8_t timeout = SEND_TIMEOUT; 608 while (!Endpoint_IsReadWriteAllowed()) { 609 if (USB_DeviceState != DEVICE_STATE_Configured) { 610 goto ERROR_EXIT; 611 } 612 if (Endpoint_IsStalled()) { 613 goto ERROR_EXIT; 614 } 615 if (!(timeout--)) { 616 timed_out = true; 617 goto ERROR_EXIT; 618 } 619 _delay_ms(1); 620 } 621 622 Endpoint_Write_8(c); 623 624 // send when bank is full 625 if (!Endpoint_IsReadWriteAllowed()) { 626 while (!(Endpoint_IsINReady())) 627 ; 628 Endpoint_ClearIN(); 629 } else { 630 CONSOLE_FLUSH_SET(true); 631 } 632 633 Endpoint_SelectEndpoint(ep); 634 return 0; 635 ERROR_EXIT: 636 Endpoint_SelectEndpoint(ep); 637 return -1; 638 } 639 #endif 640 641 /******************************************************************************* 642 * MIDI 643 ******************************************************************************/ 644 645 #ifdef MIDI_ENABLE 646 // clang-format off 647 648 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface = { 649 .Config = { 650 .StreamingInterfaceNumber = AS_INTERFACE, 651 .DataINEndpoint = { 652 .Address = (MIDI_STREAM_IN_EPNUM | ENDPOINT_DIR_IN), 653 .Size = MIDI_STREAM_EPSIZE, 654 .Banks = 1 655 }, 656 .DataOUTEndpoint = { 657 .Address = (MIDI_STREAM_OUT_EPNUM | ENDPOINT_DIR_OUT), 658 .Size = MIDI_STREAM_EPSIZE, 659 .Banks = 1 660 } 661 } 662 }; 663 664 // clang-format on 665 666 void send_midi_packet(MIDI_EventPacket_t *event) { 667 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event); 668 } 669 670 bool recv_midi_packet(MIDI_EventPacket_t *const event) { 671 return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event); 672 } 673 674 #endif 675 676 /******************************************************************************* 677 * VIRTUAL SERIAL 678 ******************************************************************************/ 679 680 #ifdef VIRTSER_ENABLE 681 /** \brief Virtual Serial Init 682 * 683 * FIXME: Needs doc 684 */ 685 void virtser_init(void) { 686 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR; 687 CDC_Device_SendControlLineStateChange(&cdc_device); 688 } 689 690 /** \brief Virtual Serial Receive 691 * 692 * FIXME: Needs doc 693 */ 694 void virtser_recv(uint8_t c) __attribute__((weak)); 695 void virtser_recv(uint8_t c) { 696 // Ignore by default 697 } 698 699 /** \brief Virtual Serial Task 700 * 701 * FIXME: Needs doc 702 */ 703 void virtser_task(void) { 704 uint16_t count = CDC_Device_BytesReceived(&cdc_device); 705 uint8_t ch; 706 for (; count; --count) { 707 ch = CDC_Device_ReceiveByte(&cdc_device); 708 virtser_recv(ch); 709 } 710 } 711 /** \brief Virtual Serial Send 712 * 713 * FIXME: Needs doc 714 */ 715 void virtser_send(const uint8_t byte) { 716 uint8_t timeout = 255; 717 uint8_t ep = Endpoint_GetCurrentEndpoint(); 718 719 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) { 720 /* IN packet */ 721 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address); 722 723 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) { 724 Endpoint_SelectEndpoint(ep); 725 return; 726 } 727 728 while (timeout-- && !Endpoint_IsReadWriteAllowed()) 729 _delay_us(40); 730 731 Endpoint_Write_8(byte); 732 CDC_Device_Flush(&cdc_device); 733 734 if (Endpoint_IsINReady()) { 735 Endpoint_ClearIN(); 736 } 737 738 Endpoint_SelectEndpoint(ep); 739 } 740 } 741 #endif 742 743 /******************************************************************************* 744 * main 745 ******************************************************************************/ 746 /** \brief Setup MCU 747 * 748 * FIXME: Needs doc 749 */ 750 static void setup_mcu(void) { 751 /* Disable watchdog if enabled by bootloader/fuses */ 752 MCUSR &= ~_BV(WDRF); 753 wdt_disable(); 754 755 // For boards running at 3.3V and crystal at 16 MHz 756 #if (F_CPU == 8000000 && F_USB == 16000000) 757 /* Divide clock by 2 */ 758 clock_prescale_set(clock_div_2); 759 #else /* Disable clock division */ 760 clock_prescale_set(clock_div_1); 761 #endif 762 } 763 764 /** \brief Setup USB 765 * 766 * FIXME: Needs doc 767 */ 768 static void setup_usb(void) { 769 // Leonardo needs. Without this USB device is not recognized. 770 USB_Disable(); 771 772 USB_Init(); 773 774 // for console_flush_task 775 USB_Device_EnableSOFEvents(); 776 } 777 778 void protocol_setup(void) { 779 #ifdef MIDI_ENABLE 780 setup_midi(); 781 #endif 782 783 setup_mcu(); 784 usb_device_state_init(); 785 } 786 787 void protocol_pre_init(void) { 788 setup_usb(); 789 sei(); 790 791 /* wait for USB startup & debug output */ 792 793 #ifdef USB_WAIT_FOR_ENUMERATION 794 while (USB_DeviceState != DEVICE_STATE_Configured) { 795 # if defined(INTERRUPT_CONTROL_ENDPOINT) 796 ; 797 # else 798 USB_USBTask(); 799 # endif 800 } 801 print("USB configured.\n"); 802 #else 803 USB_USBTask(); 804 #endif 805 } 806 807 void protocol_post_init(void) { 808 host_set_driver(&lufa_driver); 809 } 810 811 void protocol_pre_task(void) { 812 #if !defined(NO_USB_STARTUP_CHECK) 813 if (USB_DeviceState == DEVICE_STATE_Suspended) { 814 dprintln("suspending keyboard"); 815 while (USB_DeviceState == DEVICE_STATE_Suspended) { 816 suspend_power_down(); 817 if (suspend_wakeup_condition() && USB_Device_RemoteWakeupEnabled) { 818 USB_Device_SendRemoteWakeup(); 819 clear_keyboard(); 820 821 # if USB_SUSPEND_WAKEUP_DELAY > 0 822 // Some hubs, kvm switches, and monitors do 823 // weird things, with USB device state bouncing 824 // around wildly on wakeup, yielding race 825 // conditions that can corrupt the keyboard state. 826 // 827 // Pause for a while to let things settle... 828 wait_ms(USB_SUSPEND_WAKEUP_DELAY); 829 // ...and then update the wakeup matrix again as the waking key 830 // might have been released during the delay 831 update_matrix_state_after_wakeup(); 832 # endif 833 } 834 } 835 suspend_wakeup_init(); 836 } 837 #endif 838 } 839 840 void protocol_post_task(void) { 841 #ifdef CONSOLE_ENABLE 842 console_task(); 843 #endif 844 845 #ifdef MIDI_ENABLE 846 MIDI_Device_USBTask(&USB_MIDI_Interface); 847 #endif 848 849 #ifdef VIRTSER_ENABLE 850 virtser_task(); 851 CDC_Device_USBTask(&cdc_device); 852 #endif 853 854 #if !defined(INTERRUPT_CONTROL_ENDPOINT) 855 USB_USBTask(); 856 #endif 857 } 858 859 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint16_t wIndex, const void **const DescriptorAddress) { 860 return get_usb_descriptor(wValue, wIndex, USB_ControlRequest.wLength, DescriptorAddress); 861 }