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 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
413 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
416 /* Setup Mouse HID Report Endpoint */
417 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
418 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
421 #ifdef EXTRAKEY_ENABLE
422 /* Setup Extra HID Report Endpoint */
423 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
424 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
428 /* Setup Raw HID Report Endpoints */
429 ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
430 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
431 ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
432 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
435 #ifdef CONSOLE_ENABLE
436 /* Setup Console HID Report Endpoints */
437 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
438 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
440 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
441 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
446 /* Setup NKRO HID Report Endpoints */
447 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
448 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
452 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
453 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
456 #ifdef VIRTSER_ENABLE
457 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
458 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
459 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
463 /* FIXME: Expose this table in the docs somehow
464 Appendix G: HID Request Support Requirements
466 The following table enumerates the requests that need to be supported by various types of HID class devices.
468 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
469 ------------------------------------------------------------------------------------------
470 Boot Mouse Required Optional Optional Optional Required Required
471 Non-Boot Mouse Required Optional Optional Optional Optional Optional
472 Boot Keyboard Required Optional Required Required Required Required
473 Non-Boot Keybrd Required Optional Required Required Optional Optional
474 Other Device Required Optional Optional Optional Optional Optional
476 /** \brief Event handler for the USB_ControlRequest event.
478 * This is fired before passing along unhandled control requests to the library for processing internally.
480 void EVENT_USB_Device_ControlRequest(void)
482 uint8_t* ReportData = NULL;
483 uint8_t ReportSize = 0;
485 /* Handle HID Class specific requests */
486 switch (USB_ControlRequest.bRequest)
488 case HID_REQ_GetReport:
489 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
491 Endpoint_ClearSETUP();
494 switch (USB_ControlRequest.wIndex) {
495 case KEYBOARD_INTERFACE:
497 ReportData = (uint8_t*)&keyboard_report_sent;
498 ReportSize = sizeof(keyboard_report_sent);
502 /* Write the report data to the control endpoint */
503 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
508 case HID_REQ_SetReport:
509 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
513 switch (USB_ControlRequest.wIndex) {
514 case KEYBOARD_INTERFACE:
518 Endpoint_ClearSETUP();
520 while (!(Endpoint_IsOUTReceived())) {
521 if (USB_DeviceState == DEVICE_STATE_Unattached)
524 keyboard_led_stats = Endpoint_Read_8();
527 Endpoint_ClearStatusStage();
535 case HID_REQ_GetProtocol:
536 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
538 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
539 Endpoint_ClearSETUP();
540 while (!(Endpoint_IsINReady()));
541 Endpoint_Write_8(keyboard_protocol);
543 Endpoint_ClearStatusStage();
548 case HID_REQ_SetProtocol:
549 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
551 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
552 Endpoint_ClearSETUP();
553 Endpoint_ClearStatusStage();
555 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
561 case HID_REQ_SetIdle:
562 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
564 Endpoint_ClearSETUP();
565 Endpoint_ClearStatusStage();
567 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
571 case HID_REQ_GetIdle:
572 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
574 Endpoint_ClearSETUP();
575 while (!(Endpoint_IsINReady()));
576 Endpoint_Write_8(keyboard_idle);
578 Endpoint_ClearStatusStage();
584 #ifdef VIRTSER_ENABLE
585 CDC_Device_ProcessControlRequest(&cdc_device);
589 /*******************************************************************************
591 ******************************************************************************/
592 /** \brief Keyboard LEDs
596 static uint8_t keyboard_leds(void)
598 return keyboard_led_stats;
601 /** \brief Send Keyboard
605 static void send_keyboard(report_keyboard_t *report)
607 uint8_t timeout = 255;
608 uint8_t where = where_to_send();
610 #ifdef BLUETOOTH_ENABLE
611 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
612 #ifdef MODULE_ADAFRUIT_BLE
613 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
615 bluefruit_serial_send(0xFD);
616 bluefruit_serial_send(0x09);
617 bluefruit_serial_send(0x01);
618 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
619 bluefruit_serial_send(report->raw[i]);
622 bluefruit_serial_send(0xFD);
623 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
624 bluefruit_serial_send(report->raw[i]);
630 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
634 /* Select the Keyboard Report Endpoint */
636 if (keyboard_protocol && keymap_config.nkro) {
637 /* Report protocol - NKRO */
638 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
640 /* Check if write ready for a polling interval around 1ms */
641 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
642 if (!Endpoint_IsReadWriteAllowed()) return;
644 /* Write Keyboard Report Data */
645 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
651 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
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 /* Write Keyboard Report Data */
658 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
661 /* Finalize the stream transfer to send the last packet */
664 keyboard_report_sent = *report;
667 /** \brief Send Mouse
671 static void send_mouse(report_mouse_t *report)
674 uint8_t timeout = 255;
675 uint8_t where = where_to_send();
677 #ifdef BLUETOOTH_ENABLE
678 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
679 #ifdef MODULE_ADAFRUIT_BLE
680 // FIXME: mouse buttons
681 adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
683 bluefruit_serial_send(0xFD);
684 bluefruit_serial_send(0x00);
685 bluefruit_serial_send(0x03);
686 bluefruit_serial_send(report->buttons);
687 bluefruit_serial_send(report->x);
688 bluefruit_serial_send(report->y);
689 bluefruit_serial_send(report->v); // should try sending the wheel v here
690 bluefruit_serial_send(report->h); // should try sending the wheel h here
691 bluefruit_serial_send(0x00);
696 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
700 /* Select the Mouse Report Endpoint */
701 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
703 /* Check if write ready for a polling interval around 10ms */
704 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
705 if (!Endpoint_IsReadWriteAllowed()) return;
707 /* Write Mouse Report Data */
708 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
710 /* Finalize the stream transfer to send the last packet */
715 /** \brief Send System
719 static void send_system(uint16_t data)
721 uint8_t timeout = 255;
723 if (USB_DeviceState != DEVICE_STATE_Configured)
727 .report_id = REPORT_ID_SYSTEM,
728 .usage = data - SYSTEM_POWER_DOWN + 1
730 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
732 /* Check if write ready for a polling interval around 10ms */
733 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
734 if (!Endpoint_IsReadWriteAllowed()) return;
736 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
740 /** \brief Send Consumer
744 static void send_consumer(uint16_t data)
746 uint8_t timeout = 255;
747 uint8_t where = where_to_send();
749 #ifdef BLUETOOTH_ENABLE
750 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
751 #ifdef MODULE_ADAFRUIT_BLE
752 adafruit_ble_send_consumer_key(data, 0);
754 static uint16_t last_data = 0;
755 if (data == last_data) return;
757 uint16_t bitmap = CONSUMER2RN42(data);
758 bluefruit_serial_send(0xFD);
759 bluefruit_serial_send(0x03);
760 bluefruit_serial_send(0x03);
761 bluefruit_serial_send(bitmap&0xFF);
762 bluefruit_serial_send((bitmap>>8)&0xFF);
764 static uint16_t last_data = 0;
765 if (data == last_data) return;
767 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
768 bluefruit_serial_send(0xFD);
769 bluefruit_serial_send(0x00);
770 bluefruit_serial_send(0x02);
771 bluefruit_serial_send((bitmap>>8)&0xFF);
772 bluefruit_serial_send(bitmap&0xFF);
773 bluefruit_serial_send(0x00);
774 bluefruit_serial_send(0x00);
775 bluefruit_serial_send(0x00);
776 bluefruit_serial_send(0x00);
781 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
786 .report_id = REPORT_ID_CONSUMER,
789 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
791 /* Check if write ready for a polling interval around 10ms */
792 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
793 if (!Endpoint_IsReadWriteAllowed()) return;
795 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
800 /*******************************************************************************
802 ******************************************************************************/
803 #ifdef CONSOLE_ENABLE
804 #define SEND_TIMEOUT 5
809 int8_t sendchar(uint8_t c)
811 // Not wait once timeouted.
812 // Because sendchar() is called so many times, waiting each call causes big lag.
813 static bool timeouted = false;
815 // prevents Console_Task() from running during sendchar() runs.
816 // or char will be lost. These two function is mutually exclusive.
817 CONSOLE_FLUSH_SET(false);
819 if (USB_DeviceState != DEVICE_STATE_Configured)
822 uint8_t ep = Endpoint_GetCurrentEndpoint();
823 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
824 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
828 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
834 uint8_t timeout = SEND_TIMEOUT;
835 while (!Endpoint_IsReadWriteAllowed()) {
836 if (USB_DeviceState != DEVICE_STATE_Configured) {
839 if (Endpoint_IsStalled()) {
851 // send when bank is full
852 if (!Endpoint_IsReadWriteAllowed()) {
853 while (!(Endpoint_IsINReady()));
856 CONSOLE_FLUSH_SET(true);
859 Endpoint_SelectEndpoint(ep);
862 Endpoint_SelectEndpoint(ep);
866 int8_t sendchar(uint8_t c)
872 /*******************************************************************************
874 ******************************************************************************/
877 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
881 .StreamingInterfaceNumber = AS_INTERFACE,
884 .Address = MIDI_STREAM_IN_EPADDR,
885 .Size = MIDI_STREAM_EPSIZE,
890 .Address = MIDI_STREAM_OUT_EPADDR,
891 .Size = MIDI_STREAM_EPSIZE,
897 void send_midi_packet(MIDI_EventPacket_t* event) {
898 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event);
901 bool recv_midi_packet(MIDI_EventPacket_t* const event) {
902 return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event);
907 /*******************************************************************************
909 ******************************************************************************/
911 #ifdef VIRTSER_ENABLE
912 /** \brief Virtual Serial Init
916 void virtser_init(void)
918 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
919 CDC_Device_SendControlLineStateChange(&cdc_device);
922 /** \brief Virtual Serial Receive
926 void virtser_recv(uint8_t c) __attribute__ ((weak));
927 void virtser_recv(uint8_t c)
932 /** \brief Virtual Serial Task
936 void virtser_task(void)
938 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
942 ch = CDC_Device_ReceiveByte(&cdc_device);
946 /** \brief Virtual Serial Send
950 void virtser_send(const uint8_t byte)
952 uint8_t timeout = 255;
953 uint8_t ep = Endpoint_GetCurrentEndpoint();
955 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
958 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
960 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
961 Endpoint_SelectEndpoint(ep);
965 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
967 Endpoint_Write_8(byte);
968 CDC_Device_Flush(&cdc_device);
970 if (Endpoint_IsINReady()) {
974 Endpoint_SelectEndpoint(ep);
979 /*******************************************************************************
981 ******************************************************************************/
986 static void setup_mcu(void)
988 /* Disable watchdog if enabled by bootloader/fuses */
989 MCUSR &= ~(1 << WDRF);
992 /* Disable clock division */
993 // clock_prescale_set(clock_div_1);
995 CLKPR = (1 << CLKPCE);
996 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
1003 static void setup_usb(void)
1005 // Leonardo needs. Without this USB device is not recognized.
1011 USB_Device_EnableSOFEvents();
1012 print_set_sendchar(sendchar);
1019 int main(void) __attribute__ ((weak));
1031 #if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
1035 /* wait for USB startup & debug output */
1038 while (USB_DeviceState != DEVICE_STATE_Configured) {
1039 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1045 print("USB configured.\n");
1051 host_set_driver(&lufa_driver);
1052 #ifdef SLEEP_LED_ENABLE
1056 #ifdef VIRTSER_ENABLE
1060 print("Keyboard start.\n");
1062 #if !defined(NO_USB_STARTUP_CHECK)
1063 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1065 suspend_power_down();
1066 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1067 USB_Device_SendRemoteWakeup();
1075 MIDI_Device_USBTask(&USB_MIDI_Interface);
1078 #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
1082 #ifdef MODULE_ADAFRUIT_BLE
1083 adafruit_ble_task();
1086 #ifdef VIRTSER_ENABLE
1088 CDC_Device_USBTask(&cdc_device);
1095 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1102 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
1103 const uint16_t wIndex,
1104 const void** const DescriptorAddress)
1106 return get_usb_descriptor(wValue, wIndex, DescriptorAddress);