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 "descriptor.h"
56 #include "keycode_config.h"
58 extern keymap_config_t keymap_config;
66 #ifdef BLUETOOTH_ENABLE
67 #include "bluetooth.h"
78 uint8_t keyboard_idle = 0;
79 /* 0: Boot Protocol, 1: Report Protocol(default) */
80 uint8_t keyboard_protocol = 1;
81 static uint8_t keyboard_led_stats = 0;
83 static report_keyboard_t keyboard_report_sent;
86 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
87 void usb_get_midi(MidiDevice * device);
88 void midi_usb_init(MidiDevice * device);
92 static uint8_t keyboard_leds(void);
93 static void send_keyboard(report_keyboard_t *report);
94 static void send_mouse(report_mouse_t *report);
95 static void send_system(uint16_t data);
96 static void send_consumer(uint16_t data);
97 host_driver_t lufa_driver = {
110 /*******************************************************************************
112 ******************************************************************************/
115 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
119 .StreamingInterfaceNumber = AS_INTERFACE,
122 .Address = MIDI_STREAM_IN_EPADDR,
123 .Size = MIDI_STREAM_EPSIZE,
128 .Address = MIDI_STREAM_OUT_EPADDR,
129 .Size = MIDI_STREAM_EPSIZE,
135 #define SYSEX_START_OR_CONT 0x40
136 #define SYSEX_ENDS_IN_1 0x50
137 #define SYSEX_ENDS_IN_2 0x60
138 #define SYSEX_ENDS_IN_3 0x70
140 #define SYS_COMMON_1 0x50
141 #define SYS_COMMON_2 0x20
142 #define SYS_COMMON_3 0x30
145 #ifdef VIRTSER_ENABLE
146 USB_ClassInfo_CDC_Device_t cdc_device =
150 .ControlInterfaceNumber = CCI_INTERFACE,
153 .Address = CDC_IN_EPADDR,
159 .Address = CDC_OUT_EPADDR,
163 .NotificationEndpoint =
165 .Address = CDC_NOTIFICATION_EPADDR,
166 .Size = CDC_NOTIFICATION_EPSIZE,
174 /*******************************************************************************
176 ******************************************************************************/
177 #ifdef CONSOLE_ENABLE
178 static void Console_Task(void)
180 /* Device must be connected and configured for the task to run */
181 if (USB_DeviceState != DEVICE_STATE_Configured)
184 uint8_t ep = Endpoint_GetCurrentEndpoint();
187 // TODO: impl receivechar()/recvchar()
188 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
190 /* Check to see if a packet has been sent from the host */
191 if (Endpoint_IsOUTReceived())
193 /* Check to see if the packet contains data */
194 if (Endpoint_IsReadWriteAllowed())
196 /* Create a temporary buffer to hold the read in report from the host */
197 uint8_t ConsoleData[CONSOLE_EPSIZE];
199 /* Read Console Report Data */
200 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
202 /* Process Console Report Data */
203 //ProcessConsoleHIDReport(ConsoleData);
206 /* Finalize the stream transfer to send the last packet */
212 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
213 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
214 Endpoint_SelectEndpoint(ep);
219 while (Endpoint_IsReadWriteAllowed())
222 // flash senchar packet
223 if (Endpoint_IsINReady()) {
227 Endpoint_SelectEndpoint(ep);
232 /*******************************************************************************
234 ******************************************************************************/
236 * Event Order of Plug in:
237 * 0) EVENT_USB_Device_Connect
238 * 1) EVENT_USB_Device_Suspend
239 * 2) EVENT_USB_Device_Reset
240 * 3) EVENT_USB_Device_Wake
242 void EVENT_USB_Device_Connect(void)
245 /* For battery powered device */
246 if (!USB_IsInitialized) {
249 USB_Device_EnableSOFEvents();
253 void EVENT_USB_Device_Disconnect(void)
256 /* For battery powered device */
257 USB_IsInitialized = false;
258 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
259 if (USB_IsInitialized) {
260 USB_Disable(); // Disable all interrupts
261 USB_Controller_Enable();
262 USB_INT_Enable(USB_INT_VBUSTI);
267 void EVENT_USB_Device_Reset(void)
272 void EVENT_USB_Device_Suspend()
275 #ifdef SLEEP_LED_ENABLE
280 void EVENT_USB_Device_WakeUp()
283 suspend_wakeup_init();
285 #ifdef SLEEP_LED_ENABLE
287 // NOTE: converters may not accept this
288 led_set(host_keyboard_leds());
292 #ifdef CONSOLE_ENABLE
293 static bool console_flush = false;
294 #define CONSOLE_FLUSH_SET(b) do { \
295 uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
299 void EVENT_USB_Device_StartOfFrame(void)
301 static uint8_t count;
302 if (++count % 50) return;
305 if (!console_flush) return;
307 console_flush = false;
311 /** Event handler for the USB_ConfigurationChanged event.
312 * This is fired when the host sets the current configuration of the USB device after enumeration.
314 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
315 * it is safe to use singl bank for all endpoints.
317 void EVENT_USB_Device_ConfigurationChanged(void)
319 bool ConfigSuccess = true;
321 /* Setup Keyboard HID Report Endpoints */
322 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
323 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
326 /* Setup Mouse HID Report Endpoint */
327 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
328 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
331 #ifdef EXTRAKEY_ENABLE
332 /* Setup Extra HID Report Endpoint */
333 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
334 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
337 #ifdef CONSOLE_ENABLE
338 /* Setup Console HID Report Endpoints */
339 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
340 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
342 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
343 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
348 /* Setup NKRO HID Report Endpoints */
349 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
350 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
354 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
355 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
358 #ifdef VIRTSER_ENABLE
359 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
360 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
361 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
366 Appendix G: HID Request Support Requirements
368 The following table enumerates the requests that need to be supported by various types of HID class devices.
370 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
371 ------------------------------------------------------------------------------------------
372 Boot Mouse Required Optional Optional Optional Required Required
373 Non-Boot Mouse Required Optional Optional Optional Optional Optional
374 Boot Keyboard Required Optional Required Required Required Required
375 Non-Boot Keybrd Required Optional Required Required Optional Optional
376 Other Device Required Optional Optional Optional Optional Optional
378 /** Event handler for the USB_ControlRequest event.
379 * This is fired before passing along unhandled control requests to the library for processing internally.
381 void EVENT_USB_Device_ControlRequest(void)
383 uint8_t* ReportData = NULL;
384 uint8_t ReportSize = 0;
386 /* Handle HID Class specific requests */
387 switch (USB_ControlRequest.bRequest)
389 case HID_REQ_GetReport:
390 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
392 Endpoint_ClearSETUP();
395 switch (USB_ControlRequest.wIndex) {
396 case KEYBOARD_INTERFACE:
398 ReportData = (uint8_t*)&keyboard_report_sent;
399 ReportSize = sizeof(keyboard_report_sent);
403 /* Write the report data to the control endpoint */
404 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
409 case HID_REQ_SetReport:
410 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
414 switch (USB_ControlRequest.wIndex) {
415 case KEYBOARD_INTERFACE:
419 Endpoint_ClearSETUP();
421 while (!(Endpoint_IsOUTReceived())) {
422 if (USB_DeviceState == DEVICE_STATE_Unattached)
425 keyboard_led_stats = Endpoint_Read_8();
428 Endpoint_ClearStatusStage();
436 case HID_REQ_GetProtocol:
437 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
439 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
440 Endpoint_ClearSETUP();
441 while (!(Endpoint_IsINReady()));
442 Endpoint_Write_8(keyboard_protocol);
444 Endpoint_ClearStatusStage();
449 case HID_REQ_SetProtocol:
450 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
452 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
453 Endpoint_ClearSETUP();
454 Endpoint_ClearStatusStage();
456 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
462 case HID_REQ_SetIdle:
463 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
465 Endpoint_ClearSETUP();
466 Endpoint_ClearStatusStage();
468 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
472 case HID_REQ_GetIdle:
473 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
475 Endpoint_ClearSETUP();
476 while (!(Endpoint_IsINReady()));
477 Endpoint_Write_8(keyboard_idle);
479 Endpoint_ClearStatusStage();
485 #ifdef VIRTSER_ENABLE
486 CDC_Device_ProcessControlRequest(&cdc_device);
490 /*******************************************************************************
493 ******************************************************************************/
494 static uint8_t keyboard_leds(void)
496 return keyboard_led_stats;
499 static void send_keyboard(report_keyboard_t *report)
502 #ifdef BLUETOOTH_ENABLE
503 bluefruit_serial_send(0xFD);
504 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
505 bluefruit_serial_send(report->raw[i]);
509 uint8_t timeout = 255;
511 if (USB_DeviceState != DEVICE_STATE_Configured)
514 /* Select the Keyboard Report Endpoint */
516 if (keyboard_protocol && keymap_config.nkro) {
517 /* Report protocol - NKRO */
518 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
520 /* Check if write ready for a polling interval around 1ms */
521 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
522 if (!Endpoint_IsReadWriteAllowed()) return;
524 /* Write Keyboard Report Data */
525 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
531 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
533 /* Check if write ready for a polling interval around 10ms */
534 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
535 if (!Endpoint_IsReadWriteAllowed()) return;
537 /* Write Keyboard Report Data */
538 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
541 /* Finalize the stream transfer to send the last packet */
544 keyboard_report_sent = *report;
547 static void send_mouse(report_mouse_t *report)
551 #ifdef BLUETOOTH_ENABLE
552 bluefruit_serial_send(0xFD);
553 bluefruit_serial_send(0x00);
554 bluefruit_serial_send(0x03);
555 bluefruit_serial_send(report->buttons);
556 bluefruit_serial_send(report->x);
557 bluefruit_serial_send(report->y);
558 bluefruit_serial_send(report->v); // should try sending the wheel v here
559 bluefruit_serial_send(report->h); // should try sending the wheel h here
560 bluefruit_serial_send(0x00);
563 uint8_t timeout = 255;
565 if (USB_DeviceState != DEVICE_STATE_Configured)
568 /* Select the Mouse Report Endpoint */
569 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
571 /* Check if write ready for a polling interval around 10ms */
572 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
573 if (!Endpoint_IsReadWriteAllowed()) return;
575 /* Write Mouse Report Data */
576 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
578 /* Finalize the stream transfer to send the last packet */
583 static void send_system(uint16_t data)
585 uint8_t timeout = 255;
587 if (USB_DeviceState != DEVICE_STATE_Configured)
591 .report_id = REPORT_ID_SYSTEM,
594 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
596 /* Check if write ready for a polling interval around 10ms */
597 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
598 if (!Endpoint_IsReadWriteAllowed()) return;
600 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
604 static void send_consumer(uint16_t data)
607 #ifdef BLUETOOTH_ENABLE
608 static uint16_t last_data = 0;
609 if (data == last_data) return;
611 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
612 bluefruit_serial_send(0xFD);
613 bluefruit_serial_send(0x00);
614 bluefruit_serial_send(0x02);
615 bluefruit_serial_send((bitmap>>8)&0xFF);
616 bluefruit_serial_send(bitmap&0xFF);
617 bluefruit_serial_send(0x00);
618 bluefruit_serial_send(0x00);
619 bluefruit_serial_send(0x00);
620 bluefruit_serial_send(0x00);
623 uint8_t timeout = 255;
625 if (USB_DeviceState != DEVICE_STATE_Configured)
629 .report_id = REPORT_ID_CONSUMER,
632 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
634 /* Check if write ready for a polling interval around 10ms */
635 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
636 if (!Endpoint_IsReadWriteAllowed()) return;
638 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
643 /*******************************************************************************
645 ******************************************************************************/
646 #ifdef CONSOLE_ENABLE
647 #define SEND_TIMEOUT 5
648 int8_t sendchar(uint8_t c)
650 // Not wait once timeouted.
651 // Because sendchar() is called so many times, waiting each call causes big lag.
652 static bool timeouted = false;
654 // prevents Console_Task() from running during sendchar() runs.
655 // or char will be lost. These two function is mutually exclusive.
656 CONSOLE_FLUSH_SET(false);
658 if (USB_DeviceState != DEVICE_STATE_Configured)
661 uint8_t ep = Endpoint_GetCurrentEndpoint();
662 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
663 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
667 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
673 uint8_t timeout = SEND_TIMEOUT;
674 while (!Endpoint_IsReadWriteAllowed()) {
675 if (USB_DeviceState != DEVICE_STATE_Configured) {
678 if (Endpoint_IsStalled()) {
690 // send when bank is full
691 if (!Endpoint_IsReadWriteAllowed()) {
692 while (!(Endpoint_IsINReady()));
695 CONSOLE_FLUSH_SET(true);
698 Endpoint_SelectEndpoint(ep);
701 Endpoint_SelectEndpoint(ep);
705 int8_t sendchar(uint8_t c)
711 /*******************************************************************************
713 ******************************************************************************/
716 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
717 MIDI_EventPacket_t event;
724 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
726 //if the length is undefined we assume it is a SYSEX message
727 if (midi_packet_length(byte0) == UNDEFINED) {
730 if (byte2 == SYSEX_END)
731 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
733 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
736 if (byte1 == SYSEX_END)
737 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
739 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
742 if (byte0 == SYSEX_END)
743 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
745 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
748 return; //invalid cnt
751 //deal with 'system common' messages
752 //TODO are there any more?
753 switch(byte0 & 0xF0){
754 case MIDI_SONGPOSITION:
755 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
757 case MIDI_SONGSELECT:
758 case MIDI_TC_QUARTERFRAME:
759 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
762 event.Event = MIDI_EVENT(cable, byte0);
767 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
768 // Endpoint_ClearIN();
770 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
771 MIDI_Device_Flush(&USB_MIDI_Interface);
772 MIDI_Device_USBTask(&USB_MIDI_Interface);
776 void usb_get_midi(MidiDevice * device) {
777 MIDI_EventPacket_t event;
778 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
780 midi_packet_length_t length = midi_packet_length(event.Data1);
782 input[0] = event.Data1;
783 input[1] = event.Data2;
784 input[2] = event.Data3;
785 if (length == UNDEFINED) {
787 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
789 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
791 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
798 //pass the data to the device input function
799 if (length != UNDEFINED)
800 midi_device_input(device, length, input);
802 MIDI_Device_USBTask(&USB_MIDI_Interface);
806 void midi_usb_init(MidiDevice * device){
807 midi_device_init(device);
808 midi_device_set_send_func(device, usb_send_func);
809 midi_device_set_pre_input_process_func(device, usb_get_midi);
818 /* Device must be connected and configured for the task to run */
819 dprint("in MIDI_TASK\n");
820 if (USB_DeviceState != DEVICE_STATE_Configured)
822 dprint("continuing in MIDI_TASK\n");
824 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
826 if (Endpoint_IsINReady())
829 dprint("Endpoint is ready\n");
831 uint8_t MIDICommand = 0;
834 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
835 uint8_t Channel = MIDI_CHANNEL(1);
837 MIDICommand = MIDI_COMMAND_NOTE_ON;
840 /* Check if a MIDI command is to be sent */
843 dprint("Command exists\n");
844 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
846 .Event = MIDI_EVENT(0, MIDICommand),
848 .Data1 = MIDICommand | Channel,
850 .Data3 = MIDI_STANDARD_VELOCITY,
853 /* Write the MIDI event packet to the endpoint */
854 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
856 /* Send the data in the endpoint to the host */
862 /* Select the MIDI OUT stream */
863 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
865 /* Check if a MIDI command has been received */
866 if (Endpoint_IsOUTReceived())
868 MIDI_EventPacket_t MIDIEvent;
870 /* Read the MIDI event packet from the endpoint */
871 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
873 /* If the endpoint is now empty, clear the bank */
874 if (!(Endpoint_BytesInEndpoint()))
876 /* Clear the endpoint ready for new packet */
884 /*******************************************************************************
886 ******************************************************************************/
888 #ifdef VIRTSER_ENABLE
889 void virtser_init(void)
891 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
892 CDC_Device_SendControlLineStateChange(&cdc_device);
895 void virtser_recv(uint8_t c) __attribute__ ((weak));
896 void virtser_recv(uint8_t c)
901 void virtser_task(void)
903 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
907 ch = CDC_Device_ReceiveByte(&cdc_device);
911 void virtser_send(const uint8_t byte)
913 uint8_t timeout = 255;
914 uint8_t ep = Endpoint_GetCurrentEndpoint();
916 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
919 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
921 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
922 Endpoint_SelectEndpoint(ep);
926 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
928 Endpoint_Write_8(byte);
929 CDC_Device_Flush(&cdc_device);
931 if (Endpoint_IsINReady()) {
935 Endpoint_SelectEndpoint(ep);
940 /*******************************************************************************
942 ******************************************************************************/
943 static void setup_mcu(void)
945 /* Disable watchdog if enabled by bootloader/fuses */
946 MCUSR &= ~(1 << WDRF);
949 /* Disable clock division */
950 // clock_prescale_set(clock_div_1);
952 CLKPR = (1 << CLKPCE);
953 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
956 static void setup_usb(void)
958 // Leonardo needs. Without this USB device is not recognized.
964 USB_Device_EnableSOFEvents();
965 print_set_sendchar(sendchar);
970 void fallthrough_callback(MidiDevice * device,
971 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
972 void cc_callback(MidiDevice * device,
973 uint8_t chan, uint8_t num, uint8_t val);
974 void sysex_callback(MidiDevice * device,
975 uint16_t start, uint8_t length, uint8_t * data);
978 int main(void) __attribute__ ((weak));
983 midi_device_init(&midi_device);
984 midi_device_set_send_func(&midi_device, usb_send_func);
985 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
994 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
995 midi_register_cc_callback(&midi_device, cc_callback);
996 midi_register_sysex_callback(&midi_device, sysex_callback);
999 // midi_send_cc(&midi_device, 0, 1, 2);
1000 // midi_send_cc(&midi_device, 15, 1, 0);
1001 // midi_send_noteon(&midi_device, 0, 64, 127);
1002 // midi_send_noteoff(&midi_device, 0, 64, 127);
1005 #ifdef BLUETOOTH_ENABLE
1009 /* wait for USB startup & debug output */
1012 while (USB_DeviceState != DEVICE_STATE_Configured) {
1013 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1019 print("USB configured.\n");
1025 host_set_driver(&lufa_driver);
1026 #ifdef SLEEP_LED_ENABLE
1030 #ifdef VIRTSER_ENABLE
1034 print("Keyboard start.\n");
1036 #ifndef BLUETOOTH_ENABLE
1037 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1039 suspend_power_down();
1040 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1041 USB_Device_SendRemoteWakeup();
1047 midi_device_process(&midi_device);
1052 #ifdef RGBLIGHT_ENABLE
1056 #ifdef VIRTSER_ENABLE
1058 CDC_Device_USBTask(&cdc_device);
1061 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1068 void fallthrough_callback(MidiDevice * device,
1069 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
1073 switch (byte0 & 0xF0) {
1075 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1078 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1082 if (byte0 == MIDI_STOP) {
1089 rgblight_config_t rgblight_config;
1092 void cc_callback(MidiDevice * device,
1093 uint8_t chan, uint8_t num, uint8_t val) {
1094 //sending it back on the next channel
1095 // midi_send_cc(device, (chan + 1) % 16, num, val);
1097 rgblight_config.raw = eeconfig_read_rgblight();
1100 rgblight_config.hue = val * 360 / 127;
1103 rgblight_config.sat = val << 1;
1106 rgblight_config.val = val << 1;
1109 rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
1113 void sysex_callback(MidiDevice * device,
1114 uint16_t start, uint8_t length, uint8_t * data) {
1115 // for (int i = 0; i < length; i++)
1116 // midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));