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
10 Copyright (C) Dean Camera, 2012.
12 dean [at] fourwalledcubicle [dot] com
17 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
18 Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
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.
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
41 #include "host_driver.h"
47 #ifdef SLEEP_LED_ENABLE
48 #include "sleep_led.h"
52 #include "usb_descriptor.h"
55 #include <util/atomic.h>
56 #include "outputselect.h"
57 #include "rgblight_reconfig.h"
60 #include "keycode_config.h"
62 extern keymap_config_t keymap_config;
70 #ifdef BLUETOOTH_ENABLE
71 #ifdef MODULE_ADAFRUIT_BLE
72 #include "adafruit_ble.h"
74 #include "bluetooth.h"
82 #if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE)
94 uint8_t keyboard_idle = 0;
95 /* 0: Boot Protocol, 1: Report Protocol(default) */
96 uint8_t keyboard_protocol = 1;
97 static uint8_t keyboard_led_stats = 0;
99 static report_keyboard_t keyboard_report_sent;
102 static uint8_t keyboard_leds(void);
103 static void send_keyboard(report_keyboard_t *report);
104 static void send_mouse(report_mouse_t *report);
105 static void send_system(uint16_t data);
106 static void send_consumer(uint16_t data);
107 host_driver_t lufa_driver = {
115 #ifdef VIRTSER_ENABLE
116 USB_ClassInfo_CDC_Device_t cdc_device =
120 .ControlInterfaceNumber = CCI_INTERFACE,
123 .Address = CDC_IN_EPADDR,
129 .Address = CDC_OUT_EPADDR,
133 .NotificationEndpoint =
135 .Address = CDC_NOTIFICATION_EPADDR,
136 .Size = CDC_NOTIFICATION_EPSIZE,
145 /** \brief Raw HID Send
149 void raw_hid_send( uint8_t *data, uint8_t length )
151 // TODO: implement variable size packet
152 if ( length != RAW_EPSIZE )
157 if (USB_DeviceState != DEVICE_STATE_Configured)
162 // TODO: decide if we allow calls to raw_hid_send() in the middle
163 // of other endpoint usage.
164 uint8_t ep = Endpoint_GetCurrentEndpoint();
166 Endpoint_SelectEndpoint(RAW_IN_EPNUM);
168 // Check to see if the host is ready to accept another packet
169 if (Endpoint_IsINReady())
172 Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL);
173 // Finalize the stream transfer to send the last packet
177 Endpoint_SelectEndpoint(ep);
180 /** \brief Raw HID Receive
184 __attribute__ ((weak))
185 void raw_hid_receive( uint8_t *data, uint8_t length )
187 // Users should #include "raw_hid.h" in their own code
188 // and implement this function there. Leave this as weak linkage
189 // so users can opt to not handle data coming in.
192 /** \brief Raw HID Task
196 static void raw_hid_task(void)
198 // Create a temporary buffer to hold the read in data from the host
199 uint8_t data[RAW_EPSIZE];
200 bool data_read = false;
202 // Device must be connected and configured for the task to run
203 if (USB_DeviceState != DEVICE_STATE_Configured)
206 Endpoint_SelectEndpoint(RAW_OUT_EPNUM);
208 // Check to see if a packet has been sent from the host
209 if (Endpoint_IsOUTReceived())
211 // Check to see if the packet contains data
212 if (Endpoint_IsReadWriteAllowed())
215 Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
219 // Finalize the stream transfer to receive the last packet
224 raw_hid_receive( data, sizeof(data) );
230 /*******************************************************************************
232 ******************************************************************************/
233 #ifdef CONSOLE_ENABLE
234 /** \brief Console Task
238 static void Console_Task(void)
240 /* Device must be connected and configured for the task to run */
241 if (USB_DeviceState != DEVICE_STATE_Configured)
244 uint8_t ep = Endpoint_GetCurrentEndpoint();
247 // TODO: impl receivechar()/recvchar()
248 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
250 /* Check to see if a packet has been sent from the host */
251 if (Endpoint_IsOUTReceived())
253 /* Check to see if the packet contains data */
254 if (Endpoint_IsReadWriteAllowed())
256 /* Create a temporary buffer to hold the read in report from the host */
257 uint8_t ConsoleData[CONSOLE_EPSIZE];
259 /* Read Console Report Data */
260 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
262 /* Process Console Report Data */
263 //ProcessConsoleHIDReport(ConsoleData);
266 /* Finalize the stream transfer to send the last packet */
272 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
273 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
274 Endpoint_SelectEndpoint(ep);
279 while (Endpoint_IsReadWriteAllowed())
282 // flash senchar packet
283 if (Endpoint_IsINReady()) {
287 Endpoint_SelectEndpoint(ep);
292 /*******************************************************************************
294 ******************************************************************************/
296 * Event Order of Plug in:
297 * 0) EVENT_USB_Device_Connect
298 * 1) EVENT_USB_Device_Suspend
299 * 2) EVENT_USB_Device_Reset
300 * 3) EVENT_USB_Device_Wake
302 /** \brief Event USB Device Connect
306 void EVENT_USB_Device_Connect(void)
309 /* For battery powered device */
310 if (!USB_IsInitialized) {
313 USB_Device_EnableSOFEvents();
317 /** \brief Event USB Device Connect
321 void EVENT_USB_Device_Disconnect(void)
324 /* For battery powered device */
325 USB_IsInitialized = false;
326 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
327 if (USB_IsInitialized) {
328 USB_Disable(); // Disable all interrupts
329 USB_Controller_Enable();
330 USB_INT_Enable(USB_INT_VBUSTI);
335 /** \brief Event USB Device Connect
339 void EVENT_USB_Device_Reset(void)
344 /** \brief Event USB Device Connect
348 void EVENT_USB_Device_Suspend()
351 #ifdef SLEEP_LED_ENABLE
356 /** \brief Event USB Device Connect
360 void EVENT_USB_Device_WakeUp()
363 suspend_wakeup_init();
365 #ifdef SLEEP_LED_ENABLE
367 // NOTE: converters may not accept this
368 led_set(host_keyboard_leds());
374 #ifdef CONSOLE_ENABLE
375 static bool console_flush = false;
376 #define CONSOLE_FLUSH_SET(b) do { \
377 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\
382 /** \brief Event USB Device Start Of Frame
387 void EVENT_USB_Device_StartOfFrame(void)
389 static uint8_t count;
390 if (++count % 50) return;
393 if (!console_flush) return;
395 console_flush = false;
400 /** \brief Event handler for the USB_ConfigurationChanged event.
402 * This is fired when the host sets the current configuration of the USB device after enumeration.
404 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
405 * it is safe to use single bank for all endpoints.
407 void EVENT_USB_Device_ConfigurationChanged(void)
409 bool ConfigSuccess = true;
411 /* Setup Keyboard HID Report Endpoints */
412 #ifndef KEYBOARD_SHARED_EP
413 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
414 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
417 #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
418 /* Setup Mouse HID Report Endpoint */
419 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
420 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
423 #ifdef SHARED_EP_ENABLE
424 /* Setup Shared HID Report Endpoint */
425 ConfigSuccess &= ENDPOINT_CONFIG(SHARED_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
426 SHARED_EPSIZE, ENDPOINT_BANK_SINGLE);
430 /* Setup Raw HID Report Endpoints */
431 ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
432 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
433 ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
434 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
437 #ifdef CONSOLE_ENABLE
438 /* Setup Console HID Report Endpoints */
439 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
440 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
442 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
443 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
448 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
449 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
452 #ifdef VIRTSER_ENABLE
453 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
454 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
455 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
459 /* FIXME: Expose this table in the docs somehow
460 Appendix G: HID Request Support Requirements
462 The following table enumerates the requests that need to be supported by various types of HID class devices.
464 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
465 ------------------------------------------------------------------------------------------
466 Boot Mouse Required Optional Optional Optional Required Required
467 Non-Boot Mouse Required Optional Optional Optional Optional Optional
468 Boot Keyboard Required Optional Required Required Required Required
469 Non-Boot Keybrd Required Optional Required Required Optional Optional
470 Other Device Required Optional Optional Optional Optional Optional
472 /** \brief Event handler for the USB_ControlRequest event.
474 * This is fired before passing along unhandled control requests to the library for processing internally.
476 void EVENT_USB_Device_ControlRequest(void)
478 uint8_t* ReportData = NULL;
479 uint8_t ReportSize = 0;
481 /* Handle HID Class specific requests */
482 switch (USB_ControlRequest.bRequest)
484 case HID_REQ_GetReport:
485 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
487 Endpoint_ClearSETUP();
490 switch (USB_ControlRequest.wIndex) {
491 case KEYBOARD_INTERFACE:
493 ReportData = (uint8_t*)&keyboard_report_sent;
494 ReportSize = sizeof(keyboard_report_sent);
498 /* Write the report data to the control endpoint */
499 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
504 case HID_REQ_SetReport:
505 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
509 switch (USB_ControlRequest.wIndex) {
510 case KEYBOARD_INTERFACE:
511 #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
512 case SHARED_INTERFACE:
514 Endpoint_ClearSETUP();
516 while (!(Endpoint_IsOUTReceived())) {
517 if (USB_DeviceState == DEVICE_STATE_Unattached)
520 #if defined(SHARED_EP_ENABLE)
521 uint8_t report_id = REPORT_ID_KEYBOARD;
522 if (keyboard_protocol) {
523 report_id = Endpoint_Read_8();
525 if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
526 keyboard_led_stats = Endpoint_Read_8();
529 keyboard_led_stats = Endpoint_Read_8();
533 Endpoint_ClearStatusStage();
541 case HID_REQ_GetProtocol:
542 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
544 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
545 Endpoint_ClearSETUP();
546 while (!(Endpoint_IsINReady()));
547 Endpoint_Write_8(keyboard_protocol);
549 Endpoint_ClearStatusStage();
554 case HID_REQ_SetProtocol:
555 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
557 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
558 Endpoint_ClearSETUP();
559 Endpoint_ClearStatusStage();
561 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
567 case HID_REQ_SetIdle:
568 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
570 Endpoint_ClearSETUP();
571 Endpoint_ClearStatusStage();
573 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
577 case HID_REQ_GetIdle:
578 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
580 Endpoint_ClearSETUP();
581 while (!(Endpoint_IsINReady()));
582 Endpoint_Write_8(keyboard_idle);
584 Endpoint_ClearStatusStage();
590 #ifdef VIRTSER_ENABLE
591 CDC_Device_ProcessControlRequest(&cdc_device);
595 /*******************************************************************************
597 ******************************************************************************/
598 /** \brief Keyboard LEDs
602 static uint8_t keyboard_leds(void)
604 return keyboard_led_stats;
607 /** \brief Send Keyboard
611 static void send_keyboard(report_keyboard_t *report)
613 uint8_t timeout = 255;
614 uint8_t where = where_to_send();
616 #ifdef BLUETOOTH_ENABLE
617 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
618 #ifdef MODULE_ADAFRUIT_BLE
619 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
621 bluefruit_serial_send(0xFD);
622 bluefruit_serial_send(0x09);
623 bluefruit_serial_send(0x01);
624 bluefruit_serial_send(report->mods);
625 bluefruit_serial_send(report->reserved);
626 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
627 bluefruit_serial_send(report->keys[i]);
630 bluefruit_serial_send(0xFD);
631 bluefruit_serial_send(report->mods);
632 bluefruit_serial_send(report->reserved);
633 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
634 bluefruit_serial_send(report->keys[i]);
640 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
644 /* Select the Keyboard Report Endpoint */
645 uint8_t ep = KEYBOARD_IN_EPNUM;
646 uint8_t size = KEYBOARD_REPORT_SIZE;
648 if (keyboard_protocol && keymap_config.nkro) {
649 ep = SHARED_IN_EPNUM;
650 size = sizeof(struct nkro_report);
653 Endpoint_SelectEndpoint(ep);
654 /* Check if write ready for a polling interval around 10ms */
655 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
656 if (!Endpoint_IsReadWriteAllowed()) return;
658 /* If we're in Boot Protocol, don't send any report ID or other funky fields */
659 if (!keyboard_protocol) {
660 Endpoint_Write_Stream_LE(&report->mods, 8, NULL);
662 Endpoint_Write_Stream_LE(report, size, NULL);
665 /* Finalize the stream transfer to send the last packet */
668 keyboard_report_sent = *report;
671 /** \brief Send Mouse
675 static void send_mouse(report_mouse_t *report)
678 uint8_t timeout = 255;
679 uint8_t where = where_to_send();
681 #ifdef BLUETOOTH_ENABLE
682 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
683 #ifdef MODULE_ADAFRUIT_BLE
684 // FIXME: mouse buttons
685 adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
687 bluefruit_serial_send(0xFD);
688 bluefruit_serial_send(0x00);
689 bluefruit_serial_send(0x03);
690 bluefruit_serial_send(report->buttons);
691 bluefruit_serial_send(report->x);
692 bluefruit_serial_send(report->y);
693 bluefruit_serial_send(report->v); // should try sending the wheel v here
694 bluefruit_serial_send(report->h); // should try sending the wheel h here
695 bluefruit_serial_send(0x00);
700 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
704 /* Select the Mouse Report Endpoint */
705 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
707 /* Check if write ready for a polling interval around 10ms */
708 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
709 if (!Endpoint_IsReadWriteAllowed()) return;
711 /* Write Mouse Report Data */
712 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
714 /* Finalize the stream transfer to send the last packet */
719 /** \brief Send System
723 static void send_system(uint16_t data)
725 #ifdef EXTRAKEY_ENABLE
726 uint8_t timeout = 255;
728 if (USB_DeviceState != DEVICE_STATE_Configured)
732 .report_id = REPORT_ID_SYSTEM,
733 .usage = data - SYSTEM_POWER_DOWN + 1
735 Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
737 /* Check if write ready for a polling interval around 10ms */
738 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
739 if (!Endpoint_IsReadWriteAllowed()) return;
741 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
746 /** \brief Send Consumer
750 static void send_consumer(uint16_t data)
752 #ifdef EXTRAKEY_ENABLE
753 uint8_t timeout = 255;
754 uint8_t where = where_to_send();
756 #ifdef BLUETOOTH_ENABLE
757 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
758 #ifdef MODULE_ADAFRUIT_BLE
759 adafruit_ble_send_consumer_key(data, 0);
761 static uint16_t last_data = 0;
762 if (data == last_data) return;
764 uint16_t bitmap = CONSUMER2RN42(data);
765 bluefruit_serial_send(0xFD);
766 bluefruit_serial_send(0x03);
767 bluefruit_serial_send(0x03);
768 bluefruit_serial_send(bitmap&0xFF);
769 bluefruit_serial_send((bitmap>>8)&0xFF);
771 static uint16_t last_data = 0;
772 if (data == last_data) return;
774 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
775 bluefruit_serial_send(0xFD);
776 bluefruit_serial_send(0x00);
777 bluefruit_serial_send(0x02);
778 bluefruit_serial_send((bitmap>>8)&0xFF);
779 bluefruit_serial_send(bitmap&0xFF);
780 bluefruit_serial_send(0x00);
781 bluefruit_serial_send(0x00);
782 bluefruit_serial_send(0x00);
783 bluefruit_serial_send(0x00);
788 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
793 .report_id = REPORT_ID_CONSUMER,
796 Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
798 /* Check if write ready for a polling interval around 10ms */
799 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
800 if (!Endpoint_IsReadWriteAllowed()) return;
802 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
808 /*******************************************************************************
810 ******************************************************************************/
811 #ifdef CONSOLE_ENABLE
812 #define SEND_TIMEOUT 5
817 int8_t sendchar(uint8_t c)
819 // Not wait once timeouted.
820 // Because sendchar() is called so many times, waiting each call causes big lag.
821 static bool timeouted = false;
823 // prevents Console_Task() from running during sendchar() runs.
824 // or char will be lost. These two function is mutually exclusive.
825 CONSOLE_FLUSH_SET(false);
827 if (USB_DeviceState != DEVICE_STATE_Configured)
830 uint8_t ep = Endpoint_GetCurrentEndpoint();
831 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
832 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
836 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
842 uint8_t timeout = SEND_TIMEOUT;
843 while (!Endpoint_IsReadWriteAllowed()) {
844 if (USB_DeviceState != DEVICE_STATE_Configured) {
847 if (Endpoint_IsStalled()) {
859 // send when bank is full
860 if (!Endpoint_IsReadWriteAllowed()) {
861 while (!(Endpoint_IsINReady()));
864 CONSOLE_FLUSH_SET(true);
867 Endpoint_SelectEndpoint(ep);
870 Endpoint_SelectEndpoint(ep);
874 int8_t sendchar(uint8_t c)
880 /*******************************************************************************
882 ******************************************************************************/
885 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
889 .StreamingInterfaceNumber = AS_INTERFACE,
892 .Address = MIDI_STREAM_IN_EPADDR,
893 .Size = MIDI_STREAM_EPSIZE,
898 .Address = MIDI_STREAM_OUT_EPADDR,
899 .Size = MIDI_STREAM_EPSIZE,
905 void send_midi_packet(MIDI_EventPacket_t* event) {
906 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event);
909 bool recv_midi_packet(MIDI_EventPacket_t* const event) {
910 return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event);
915 /*******************************************************************************
917 ******************************************************************************/
919 #ifdef VIRTSER_ENABLE
920 /** \brief Virtual Serial Init
924 void virtser_init(void)
926 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
927 CDC_Device_SendControlLineStateChange(&cdc_device);
930 /** \brief Virtual Serial Receive
934 void virtser_recv(uint8_t c) __attribute__ ((weak));
935 void virtser_recv(uint8_t c)
940 /** \brief Virtual Serial Task
944 void virtser_task(void)
946 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
950 ch = CDC_Device_ReceiveByte(&cdc_device);
954 /** \brief Virtual Serial Send
958 void virtser_send(const uint8_t byte)
960 uint8_t timeout = 255;
961 uint8_t ep = Endpoint_GetCurrentEndpoint();
963 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
966 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
968 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
969 Endpoint_SelectEndpoint(ep);
973 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
975 Endpoint_Write_8(byte);
976 CDC_Device_Flush(&cdc_device);
978 if (Endpoint_IsINReady()) {
982 Endpoint_SelectEndpoint(ep);
987 /*******************************************************************************
989 ******************************************************************************/
994 static void setup_mcu(void)
996 /* Disable watchdog if enabled by bootloader/fuses */
997 MCUSR &= ~(1 << WDRF);
1000 /* Disable clock division */
1001 // clock_prescale_set(clock_div_1);
1003 CLKPR = (1 << CLKPCE);
1004 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
1007 /** \brief Setup USB
1011 static void setup_usb(void)
1013 // Leonardo needs. Without this USB device is not recognized.
1019 USB_Device_EnableSOFEvents();
1020 print_set_sendchar(sendchar);
1027 int main(void) __attribute__ ((weak));
1039 #if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
1043 /* wait for USB startup & debug output */
1046 while (USB_DeviceState != DEVICE_STATE_Configured) {
1047 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1053 print("USB configured.\n");
1059 host_set_driver(&lufa_driver);
1060 #ifdef SLEEP_LED_ENABLE
1064 #ifdef VIRTSER_ENABLE
1068 print("Keyboard start.\n");
1070 #if !defined(NO_USB_STARTUP_CHECK)
1071 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1073 suspend_power_down();
1074 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1075 USB_Device_SendRemoteWakeup();
1083 MIDI_Device_USBTask(&USB_MIDI_Interface);
1086 #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
1090 #ifdef MODULE_ADAFRUIT_BLE
1091 adafruit_ble_task();
1094 #ifdef VIRTSER_ENABLE
1096 CDC_Device_USBTask(&cdc_device);
1103 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1110 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
1111 const uint16_t wIndex,
1112 const void** const DescriptorAddress)
1114 return get_usb_descriptor(wValue, wIndex, DescriptorAddress);