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"
59 #include "keycode_config.h"
61 extern keymap_config_t keymap_config;
69 #ifdef BLUETOOTH_ENABLE
70 #ifdef MODULE_ADAFRUIT_BLE
71 #include "adafruit_ble.h"
73 #include "bluetooth.h"
81 #if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE)
93 uint8_t keyboard_idle = 0;
94 /* 0: Boot Protocol, 1: Report Protocol(default) */
95 uint8_t keyboard_protocol = 1;
96 static uint8_t keyboard_led_stats = 0;
98 static report_keyboard_t keyboard_report_sent;
101 static uint8_t keyboard_leds(void);
102 static void send_keyboard(report_keyboard_t *report);
103 static void send_mouse(report_mouse_t *report);
104 static void send_system(uint16_t data);
105 static void send_consumer(uint16_t data);
106 host_driver_t lufa_driver = {
114 #ifdef VIRTSER_ENABLE
115 USB_ClassInfo_CDC_Device_t cdc_device =
119 .ControlInterfaceNumber = CCI_INTERFACE,
122 .Address = CDC_IN_EPADDR,
128 .Address = CDC_OUT_EPADDR,
132 .NotificationEndpoint =
134 .Address = CDC_NOTIFICATION_EPADDR,
135 .Size = CDC_NOTIFICATION_EPSIZE,
144 /** \brief Raw HID Send
148 void raw_hid_send( uint8_t *data, uint8_t length )
150 // TODO: implement variable size packet
151 if ( length != RAW_EPSIZE )
156 if (USB_DeviceState != DEVICE_STATE_Configured)
161 // TODO: decide if we allow calls to raw_hid_send() in the middle
162 // of other endpoint usage.
163 uint8_t ep = Endpoint_GetCurrentEndpoint();
165 Endpoint_SelectEndpoint(RAW_IN_EPNUM);
167 // Check to see if the host is ready to accept another packet
168 if (Endpoint_IsINReady())
171 Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL);
172 // Finalize the stream transfer to send the last packet
176 Endpoint_SelectEndpoint(ep);
179 /** \brief Raw HID Receive
183 __attribute__ ((weak))
184 void raw_hid_receive( uint8_t *data, uint8_t length )
186 // Users should #include "raw_hid.h" in their own code
187 // and implement this function there. Leave this as weak linkage
188 // so users can opt to not handle data coming in.
191 /** \brief Raw HID Task
195 static void raw_hid_task(void)
197 // Create a temporary buffer to hold the read in data from the host
198 uint8_t data[RAW_EPSIZE];
199 bool data_read = false;
201 // Device must be connected and configured for the task to run
202 if (USB_DeviceState != DEVICE_STATE_Configured)
205 Endpoint_SelectEndpoint(RAW_OUT_EPNUM);
207 // Check to see if a packet has been sent from the host
208 if (Endpoint_IsOUTReceived())
210 // Check to see if the packet contains data
211 if (Endpoint_IsReadWriteAllowed())
214 Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
218 // Finalize the stream transfer to receive the last packet
223 raw_hid_receive( data, sizeof(data) );
229 /*******************************************************************************
231 ******************************************************************************/
232 #ifdef CONSOLE_ENABLE
233 /** \brief Console Task
237 static void Console_Task(void)
239 /* Device must be connected and configured for the task to run */
240 if (USB_DeviceState != DEVICE_STATE_Configured)
243 uint8_t ep = Endpoint_GetCurrentEndpoint();
246 // TODO: impl receivechar()/recvchar()
247 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
249 /* Check to see if a packet has been sent from the host */
250 if (Endpoint_IsOUTReceived())
252 /* Check to see if the packet contains data */
253 if (Endpoint_IsReadWriteAllowed())
255 /* Create a temporary buffer to hold the read in report from the host */
256 uint8_t ConsoleData[CONSOLE_EPSIZE];
258 /* Read Console Report Data */
259 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
261 /* Process Console Report Data */
262 //ProcessConsoleHIDReport(ConsoleData);
265 /* Finalize the stream transfer to send the last packet */
271 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
272 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
273 Endpoint_SelectEndpoint(ep);
278 while (Endpoint_IsReadWriteAllowed())
281 // flash senchar packet
282 if (Endpoint_IsINReady()) {
286 Endpoint_SelectEndpoint(ep);
291 /*******************************************************************************
293 ******************************************************************************/
295 * Event Order of Plug in:
296 * 0) EVENT_USB_Device_Connect
297 * 1) EVENT_USB_Device_Suspend
298 * 2) EVENT_USB_Device_Reset
299 * 3) EVENT_USB_Device_Wake
301 /** \brief Event USB Device Connect
305 void EVENT_USB_Device_Connect(void)
308 /* For battery powered device */
309 if (!USB_IsInitialized) {
312 USB_Device_EnableSOFEvents();
316 /** \brief Event USB Device Connect
320 void EVENT_USB_Device_Disconnect(void)
323 /* For battery powered device */
324 USB_IsInitialized = false;
325 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
326 if (USB_IsInitialized) {
327 USB_Disable(); // Disable all interrupts
328 USB_Controller_Enable();
329 USB_INT_Enable(USB_INT_VBUSTI);
334 /** \brief Event USB Device Connect
338 void EVENT_USB_Device_Reset(void)
343 /** \brief Event USB Device Connect
347 void EVENT_USB_Device_Suspend()
350 #ifdef SLEEP_LED_ENABLE
355 /** \brief Event USB Device Connect
359 void EVENT_USB_Device_WakeUp()
362 suspend_wakeup_init();
364 #ifdef SLEEP_LED_ENABLE
366 // NOTE: converters may not accept this
367 led_set(host_keyboard_leds());
373 #ifdef CONSOLE_ENABLE
374 static bool console_flush = false;
375 #define CONSOLE_FLUSH_SET(b) do { \
376 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\
381 /** \brief Event USB Device Start Of Frame
386 void EVENT_USB_Device_StartOfFrame(void)
388 static uint8_t count;
389 if (++count % 50) return;
392 if (!console_flush) return;
394 console_flush = false;
399 /** \brief Event handler for the USB_ConfigurationChanged event.
401 * This is fired when the host sets the current configuration of the USB device after enumeration.
403 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
404 * it is safe to use single bank for all endpoints.
406 void EVENT_USB_Device_ConfigurationChanged(void)
408 bool ConfigSuccess = true;
410 /* Setup Keyboard HID Report Endpoints */
411 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
412 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
415 /* Setup Mouse HID Report Endpoint */
416 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
417 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
420 #ifdef EXTRAKEY_ENABLE
421 /* Setup Extra HID Report Endpoint */
422 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
423 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
427 /* Setup Raw HID Report Endpoints */
428 ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
429 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
430 ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
431 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
434 #ifdef CONSOLE_ENABLE
435 /* Setup Console HID Report Endpoints */
436 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
437 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
439 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
440 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
445 /* Setup NKRO HID Report Endpoints */
446 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
447 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
451 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
452 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
455 #ifdef VIRTSER_ENABLE
456 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
457 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
458 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
462 /* FIXME: Expose this table in the docs somehow
463 Appendix G: HID Request Support Requirements
465 The following table enumerates the requests that need to be supported by various types of HID class devices.
467 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
468 ------------------------------------------------------------------------------------------
469 Boot Mouse Required Optional Optional Optional Required Required
470 Non-Boot Mouse Required Optional Optional Optional Optional Optional
471 Boot Keyboard Required Optional Required Required Required Required
472 Non-Boot Keybrd Required Optional Required Required Optional Optional
473 Other Device Required Optional Optional Optional Optional Optional
475 /** \brief Event handler for the USB_ControlRequest event.
477 * This is fired before passing along unhandled control requests to the library for processing internally.
479 void EVENT_USB_Device_ControlRequest(void)
481 uint8_t* ReportData = NULL;
482 uint8_t ReportSize = 0;
484 /* Handle HID Class specific requests */
485 switch (USB_ControlRequest.bRequest)
487 case HID_REQ_GetReport:
488 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
490 Endpoint_ClearSETUP();
493 switch (USB_ControlRequest.wIndex) {
494 case KEYBOARD_INTERFACE:
496 ReportData = (uint8_t*)&keyboard_report_sent;
497 ReportSize = sizeof(keyboard_report_sent);
501 /* Write the report data to the control endpoint */
502 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
507 case HID_REQ_SetReport:
508 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
512 switch (USB_ControlRequest.wIndex) {
513 case KEYBOARD_INTERFACE:
517 Endpoint_ClearSETUP();
519 while (!(Endpoint_IsOUTReceived())) {
520 if (USB_DeviceState == DEVICE_STATE_Unattached)
523 keyboard_led_stats = Endpoint_Read_8();
526 Endpoint_ClearStatusStage();
534 case HID_REQ_GetProtocol:
535 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
537 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
538 Endpoint_ClearSETUP();
539 while (!(Endpoint_IsINReady()));
540 Endpoint_Write_8(keyboard_protocol);
542 Endpoint_ClearStatusStage();
547 case HID_REQ_SetProtocol:
548 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
550 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
551 Endpoint_ClearSETUP();
552 Endpoint_ClearStatusStage();
554 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
560 case HID_REQ_SetIdle:
561 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
563 Endpoint_ClearSETUP();
564 Endpoint_ClearStatusStage();
566 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
570 case HID_REQ_GetIdle:
571 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
573 Endpoint_ClearSETUP();
574 while (!(Endpoint_IsINReady()));
575 Endpoint_Write_8(keyboard_idle);
577 Endpoint_ClearStatusStage();
583 #ifdef VIRTSER_ENABLE
584 CDC_Device_ProcessControlRequest(&cdc_device);
588 /*******************************************************************************
590 ******************************************************************************/
591 /** \brief Keyboard LEDs
595 static uint8_t keyboard_leds(void)
597 return keyboard_led_stats;
600 /** \brief Send Keyboard
604 static void send_keyboard(report_keyboard_t *report)
606 uint8_t timeout = 255;
607 uint8_t where = where_to_send();
609 #ifdef BLUETOOTH_ENABLE
610 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
611 #ifdef MODULE_ADAFRUIT_BLE
612 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
614 bluefruit_serial_send(0xFD);
615 bluefruit_serial_send(0x09);
616 bluefruit_serial_send(0x01);
617 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
618 bluefruit_serial_send(report->raw[i]);
621 bluefruit_serial_send(0xFD);
622 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
623 bluefruit_serial_send(report->raw[i]);
629 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
633 /* Select the Keyboard Report Endpoint */
635 if (keyboard_protocol && keymap_config.nkro) {
636 /* Report protocol - NKRO */
637 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
639 /* Check if write ready for a polling interval around 1ms */
640 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
641 if (!Endpoint_IsReadWriteAllowed()) return;
643 /* Write Keyboard Report Data */
644 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
650 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
652 /* Check if write ready for a polling interval around 10ms */
653 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
654 if (!Endpoint_IsReadWriteAllowed()) return;
656 /* Write Keyboard Report Data */
657 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
660 /* Finalize the stream transfer to send the last packet */
663 keyboard_report_sent = *report;
666 /** \brief Send Mouse
670 static void send_mouse(report_mouse_t *report)
673 uint8_t timeout = 255;
674 uint8_t where = where_to_send();
676 #ifdef BLUETOOTH_ENABLE
677 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
678 #ifdef MODULE_ADAFRUIT_BLE
679 // FIXME: mouse buttons
680 adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
682 bluefruit_serial_send(0xFD);
683 bluefruit_serial_send(0x00);
684 bluefruit_serial_send(0x03);
685 bluefruit_serial_send(report->buttons);
686 bluefruit_serial_send(report->x);
687 bluefruit_serial_send(report->y);
688 bluefruit_serial_send(report->v); // should try sending the wheel v here
689 bluefruit_serial_send(report->h); // should try sending the wheel h here
690 bluefruit_serial_send(0x00);
695 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
699 /* Select the Mouse Report Endpoint */
700 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
702 /* Check if write ready for a polling interval around 10ms */
703 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
704 if (!Endpoint_IsReadWriteAllowed()) return;
706 /* Write Mouse Report Data */
707 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
709 /* Finalize the stream transfer to send the last packet */
714 /** \brief Send System
718 static void send_system(uint16_t data)
720 uint8_t timeout = 255;
722 if (USB_DeviceState != DEVICE_STATE_Configured)
726 .report_id = REPORT_ID_SYSTEM,
727 .usage = data - SYSTEM_POWER_DOWN + 1
729 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
731 /* Check if write ready for a polling interval around 10ms */
732 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
733 if (!Endpoint_IsReadWriteAllowed()) return;
735 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
739 /** \brief Send Consumer
743 static void send_consumer(uint16_t data)
745 uint8_t timeout = 255;
746 uint8_t where = where_to_send();
748 #ifdef BLUETOOTH_ENABLE
749 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
750 #ifdef MODULE_ADAFRUIT_BLE
751 adafruit_ble_send_consumer_key(data, 0);
753 static uint16_t last_data = 0;
754 if (data == last_data) return;
756 uint16_t bitmap = CONSUMER2RN42(data);
757 bluefruit_serial_send(0xFD);
758 bluefruit_serial_send(0x03);
759 bluefruit_serial_send(0x03);
760 bluefruit_serial_send(bitmap&0xFF);
761 bluefruit_serial_send((bitmap>>8)&0xFF);
763 static uint16_t last_data = 0;
764 if (data == last_data) return;
766 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
767 bluefruit_serial_send(0xFD);
768 bluefruit_serial_send(0x00);
769 bluefruit_serial_send(0x02);
770 bluefruit_serial_send((bitmap>>8)&0xFF);
771 bluefruit_serial_send(bitmap&0xFF);
772 bluefruit_serial_send(0x00);
773 bluefruit_serial_send(0x00);
774 bluefruit_serial_send(0x00);
775 bluefruit_serial_send(0x00);
780 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
785 .report_id = REPORT_ID_CONSUMER,
788 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
790 /* Check if write ready for a polling interval around 10ms */
791 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
792 if (!Endpoint_IsReadWriteAllowed()) return;
794 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
799 /*******************************************************************************
801 ******************************************************************************/
802 #ifdef CONSOLE_ENABLE
803 #define SEND_TIMEOUT 5
808 int8_t sendchar(uint8_t c)
810 // Not wait once timeouted.
811 // Because sendchar() is called so many times, waiting each call causes big lag.
812 static bool timeouted = false;
814 // prevents Console_Task() from running during sendchar() runs.
815 // or char will be lost. These two function is mutually exclusive.
816 CONSOLE_FLUSH_SET(false);
818 if (USB_DeviceState != DEVICE_STATE_Configured)
821 uint8_t ep = Endpoint_GetCurrentEndpoint();
822 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
823 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
827 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
833 uint8_t timeout = SEND_TIMEOUT;
834 while (!Endpoint_IsReadWriteAllowed()) {
835 if (USB_DeviceState != DEVICE_STATE_Configured) {
838 if (Endpoint_IsStalled()) {
850 // send when bank is full
851 if (!Endpoint_IsReadWriteAllowed()) {
852 while (!(Endpoint_IsINReady()));
855 CONSOLE_FLUSH_SET(true);
858 Endpoint_SelectEndpoint(ep);
861 Endpoint_SelectEndpoint(ep);
865 int8_t sendchar(uint8_t c)
871 /*******************************************************************************
873 ******************************************************************************/
876 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
880 .StreamingInterfaceNumber = AS_INTERFACE,
883 .Address = MIDI_STREAM_IN_EPADDR,
884 .Size = MIDI_STREAM_EPSIZE,
889 .Address = MIDI_STREAM_OUT_EPADDR,
890 .Size = MIDI_STREAM_EPSIZE,
896 void send_midi_packet(MIDI_EventPacket_t* event) {
897 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event);
900 bool recv_midi_packet(MIDI_EventPacket_t* const event) {
901 return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event);
906 /*******************************************************************************
908 ******************************************************************************/
910 #ifdef VIRTSER_ENABLE
911 /** \brief Virtual Serial Init
915 void virtser_init(void)
917 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
918 CDC_Device_SendControlLineStateChange(&cdc_device);
921 /** \brief Virtual Serial Receive
925 void virtser_recv(uint8_t c) __attribute__ ((weak));
926 void virtser_recv(uint8_t c)
931 /** \brief Virtual Serial Task
935 void virtser_task(void)
937 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
941 ch = CDC_Device_ReceiveByte(&cdc_device);
945 /** \brief Virtual Serial Send
949 void virtser_send(const uint8_t byte)
951 uint8_t timeout = 255;
952 uint8_t ep = Endpoint_GetCurrentEndpoint();
954 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
957 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
959 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
960 Endpoint_SelectEndpoint(ep);
964 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
966 Endpoint_Write_8(byte);
967 CDC_Device_Flush(&cdc_device);
969 if (Endpoint_IsINReady()) {
973 Endpoint_SelectEndpoint(ep);
978 /*******************************************************************************
980 ******************************************************************************/
985 static void setup_mcu(void)
987 /* Disable watchdog if enabled by bootloader/fuses */
988 MCUSR &= ~(1 << WDRF);
991 /* Disable clock division */
992 // clock_prescale_set(clock_div_1);
994 CLKPR = (1 << CLKPCE);
995 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
1002 static void setup_usb(void)
1004 // Leonardo needs. Without this USB device is not recognized.
1010 USB_Device_EnableSOFEvents();
1011 print_set_sendchar(sendchar);
1018 int main(void) __attribute__ ((weak));
1030 #if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
1034 /* wait for USB startup & debug output */
1037 while (USB_DeviceState != DEVICE_STATE_Configured) {
1038 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1044 print("USB configured.\n");
1050 host_set_driver(&lufa_driver);
1051 #ifdef SLEEP_LED_ENABLE
1055 #ifdef VIRTSER_ENABLE
1059 print("Keyboard start.\n");
1061 #if !defined(NO_USB_STARTUP_CHECK)
1062 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1064 suspend_power_down();
1065 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1066 USB_Device_SendRemoteWakeup();
1074 MIDI_Device_USBTask(&USB_MIDI_Interface);
1077 #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
1081 #ifdef MODULE_ADAFRUIT_BLE
1082 adafruit_ble_task();
1085 #ifdef VIRTSER_ENABLE
1087 CDC_Device_USBTask(&cdc_device);
1094 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1101 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
1102 const uint16_t wIndex,
1103 const void** const DescriptorAddress)
1105 return get_usb_descriptor(wValue, wIndex, DescriptorAddress);