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)
521 if (Endpoint_BytesInEndpoint() == 2) {
522 uint8_t report_id = Endpoint_Read_8();
524 if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
525 keyboard_led_stats = Endpoint_Read_8();
528 keyboard_led_stats = Endpoint_Read_8();
532 Endpoint_ClearStatusStage();
540 case HID_REQ_GetProtocol:
541 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
543 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
544 Endpoint_ClearSETUP();
545 while (!(Endpoint_IsINReady()));
546 Endpoint_Write_8(keyboard_protocol);
548 Endpoint_ClearStatusStage();
553 case HID_REQ_SetProtocol:
554 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
556 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
557 Endpoint_ClearSETUP();
558 Endpoint_ClearStatusStage();
560 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
566 case HID_REQ_SetIdle:
567 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
569 Endpoint_ClearSETUP();
570 Endpoint_ClearStatusStage();
572 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
576 case HID_REQ_GetIdle:
577 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
579 Endpoint_ClearSETUP();
580 while (!(Endpoint_IsINReady()));
581 Endpoint_Write_8(keyboard_idle);
583 Endpoint_ClearStatusStage();
589 #ifdef VIRTSER_ENABLE
590 CDC_Device_ProcessControlRequest(&cdc_device);
594 /*******************************************************************************
596 ******************************************************************************/
597 /** \brief Keyboard LEDs
601 static uint8_t keyboard_leds(void)
603 return keyboard_led_stats;
606 /** \brief Send Keyboard
610 static void send_keyboard(report_keyboard_t *report)
612 uint8_t timeout = 255;
613 uint8_t where = where_to_send();
615 #ifdef BLUETOOTH_ENABLE
616 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
617 #ifdef MODULE_ADAFRUIT_BLE
618 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
620 bluefruit_serial_send(0xFD);
621 bluefruit_serial_send(0x09);
622 bluefruit_serial_send(0x01);
623 bluefruit_serial_send(report->mods);
624 bluefruit_serial_send(report->reserved);
625 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
626 bluefruit_serial_send(report->keys[i]);
629 bluefruit_serial_send(0xFD);
630 bluefruit_serial_send(report->mods);
631 bluefruit_serial_send(report->reserved);
632 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
633 bluefruit_serial_send(report->keys[i]);
639 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
643 /* Select the Keyboard Report Endpoint */
644 uint8_t ep = KEYBOARD_IN_EPNUM;
645 uint8_t size = KEYBOARD_REPORT_SIZE;
647 if (keyboard_protocol && keymap_config.nkro) {
648 ep = SHARED_IN_EPNUM;
649 size = sizeof(struct nkro_report);
652 Endpoint_SelectEndpoint(ep);
653 /* Check if write ready for a polling interval around 10ms */
654 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
655 if (!Endpoint_IsReadWriteAllowed()) return;
657 /* If we're in Boot Protocol, don't send any report ID or other funky fields */
658 if (!keyboard_protocol) {
659 Endpoint_Write_Stream_LE(&report->mods, 8, NULL);
661 Endpoint_Write_Stream_LE(report, size, NULL);
664 /* Finalize the stream transfer to send the last packet */
667 keyboard_report_sent = *report;
670 /** \brief Send Mouse
674 static void send_mouse(report_mouse_t *report)
677 uint8_t timeout = 255;
678 uint8_t where = where_to_send();
680 #ifdef BLUETOOTH_ENABLE
681 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
682 #ifdef MODULE_ADAFRUIT_BLE
683 // FIXME: mouse buttons
684 adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
686 bluefruit_serial_send(0xFD);
687 bluefruit_serial_send(0x00);
688 bluefruit_serial_send(0x03);
689 bluefruit_serial_send(report->buttons);
690 bluefruit_serial_send(report->x);
691 bluefruit_serial_send(report->y);
692 bluefruit_serial_send(report->v); // should try sending the wheel v here
693 bluefruit_serial_send(report->h); // should try sending the wheel h here
694 bluefruit_serial_send(0x00);
699 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
703 /* Select the Mouse Report Endpoint */
704 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
706 /* Check if write ready for a polling interval around 10ms */
707 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
708 if (!Endpoint_IsReadWriteAllowed()) return;
710 /* Write Mouse Report Data */
711 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
713 /* Finalize the stream transfer to send the last packet */
718 /** \brief Send System
722 static void send_system(uint16_t data)
724 #ifdef EXTRAKEY_ENABLE
725 uint8_t timeout = 255;
727 if (USB_DeviceState != DEVICE_STATE_Configured)
731 .report_id = REPORT_ID_SYSTEM,
732 .usage = data - SYSTEM_POWER_DOWN + 1
734 Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
736 /* Check if write ready for a polling interval around 10ms */
737 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
738 if (!Endpoint_IsReadWriteAllowed()) return;
740 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
745 /** \brief Send Consumer
749 static void send_consumer(uint16_t data)
751 #ifdef EXTRAKEY_ENABLE
752 uint8_t timeout = 255;
753 uint8_t where = where_to_send();
755 #ifdef BLUETOOTH_ENABLE
756 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
757 #ifdef MODULE_ADAFRUIT_BLE
758 adafruit_ble_send_consumer_key(data, 0);
760 static uint16_t last_data = 0;
761 if (data == last_data) return;
763 uint16_t bitmap = CONSUMER2RN42(data);
764 bluefruit_serial_send(0xFD);
765 bluefruit_serial_send(0x03);
766 bluefruit_serial_send(0x03);
767 bluefruit_serial_send(bitmap&0xFF);
768 bluefruit_serial_send((bitmap>>8)&0xFF);
770 static uint16_t last_data = 0;
771 if (data == last_data) return;
773 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
774 bluefruit_serial_send(0xFD);
775 bluefruit_serial_send(0x00);
776 bluefruit_serial_send(0x02);
777 bluefruit_serial_send((bitmap>>8)&0xFF);
778 bluefruit_serial_send(bitmap&0xFF);
779 bluefruit_serial_send(0x00);
780 bluefruit_serial_send(0x00);
781 bluefruit_serial_send(0x00);
782 bluefruit_serial_send(0x00);
787 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
792 .report_id = REPORT_ID_CONSUMER,
795 Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
797 /* Check if write ready for a polling interval around 10ms */
798 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
799 if (!Endpoint_IsReadWriteAllowed()) return;
801 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
807 /*******************************************************************************
809 ******************************************************************************/
810 #ifdef CONSOLE_ENABLE
811 #define SEND_TIMEOUT 5
816 int8_t sendchar(uint8_t c)
818 // Not wait once timeouted.
819 // Because sendchar() is called so many times, waiting each call causes big lag.
820 static bool timeouted = false;
822 // prevents Console_Task() from running during sendchar() runs.
823 // or char will be lost. These two function is mutually exclusive.
824 CONSOLE_FLUSH_SET(false);
826 if (USB_DeviceState != DEVICE_STATE_Configured)
829 uint8_t ep = Endpoint_GetCurrentEndpoint();
830 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
831 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
835 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
841 uint8_t timeout = SEND_TIMEOUT;
842 while (!Endpoint_IsReadWriteAllowed()) {
843 if (USB_DeviceState != DEVICE_STATE_Configured) {
846 if (Endpoint_IsStalled()) {
858 // send when bank is full
859 if (!Endpoint_IsReadWriteAllowed()) {
860 while (!(Endpoint_IsINReady()));
863 CONSOLE_FLUSH_SET(true);
866 Endpoint_SelectEndpoint(ep);
869 Endpoint_SelectEndpoint(ep);
873 int8_t sendchar(uint8_t c)
879 /*******************************************************************************
881 ******************************************************************************/
884 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
888 .StreamingInterfaceNumber = AS_INTERFACE,
891 .Address = MIDI_STREAM_IN_EPADDR,
892 .Size = MIDI_STREAM_EPSIZE,
897 .Address = MIDI_STREAM_OUT_EPADDR,
898 .Size = MIDI_STREAM_EPSIZE,
904 void send_midi_packet(MIDI_EventPacket_t* event) {
905 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event);
908 bool recv_midi_packet(MIDI_EventPacket_t* const event) {
909 return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event);
914 /*******************************************************************************
916 ******************************************************************************/
918 #ifdef VIRTSER_ENABLE
919 /** \brief Virtual Serial Init
923 void virtser_init(void)
925 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
926 CDC_Device_SendControlLineStateChange(&cdc_device);
929 /** \brief Virtual Serial Receive
933 void virtser_recv(uint8_t c) __attribute__ ((weak));
934 void virtser_recv(uint8_t c)
939 /** \brief Virtual Serial Task
943 void virtser_task(void)
945 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
949 ch = CDC_Device_ReceiveByte(&cdc_device);
953 /** \brief Virtual Serial Send
957 void virtser_send(const uint8_t byte)
959 uint8_t timeout = 255;
960 uint8_t ep = Endpoint_GetCurrentEndpoint();
962 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
965 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
967 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
968 Endpoint_SelectEndpoint(ep);
972 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
974 Endpoint_Write_8(byte);
975 CDC_Device_Flush(&cdc_device);
977 if (Endpoint_IsINReady()) {
981 Endpoint_SelectEndpoint(ep);
986 /*******************************************************************************
988 ******************************************************************************/
993 static void setup_mcu(void)
995 /* Disable watchdog if enabled by bootloader/fuses */
996 MCUSR &= ~(1 << WDRF);
999 /* Disable clock division */
1000 // clock_prescale_set(clock_div_1);
1002 CLKPR = (1 << CLKPCE);
1003 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
1006 /** \brief Setup USB
1010 static void setup_usb(void)
1012 // Leonardo needs. Without this USB device is not recognized.
1018 USB_Device_EnableSOFEvents();
1019 print_set_sendchar(sendchar);
1026 int main(void) __attribute__ ((weak));
1038 #if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
1042 /* wait for USB startup & debug output */
1045 while (USB_DeviceState != DEVICE_STATE_Configured) {
1046 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1052 print("USB configured.\n");
1058 host_set_driver(&lufa_driver);
1059 #ifdef SLEEP_LED_ENABLE
1063 #ifdef VIRTSER_ENABLE
1067 print("Keyboard start.\n");
1069 #if !defined(NO_USB_STARTUP_CHECK)
1070 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1072 suspend_power_down();
1073 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1074 USB_Device_SendRemoteWakeup();
1082 MIDI_Device_USBTask(&USB_MIDI_Interface);
1085 #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
1089 #ifdef MODULE_ADAFRUIT_BLE
1090 adafruit_ble_task();
1093 #ifdef VIRTSER_ENABLE
1095 CDC_Device_USBTask(&cdc_device);
1102 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1109 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
1110 const uint16_t wIndex,
1111 const void** const DescriptorAddress)
1113 return get_usb_descriptor(wValue, wIndex, DescriptorAddress);