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"
59 #ifdef BLUETOOTH_ENABLE
60 #include "bluetooth.h"
67 uint8_t keyboard_idle = 0;
68 /* 0: Boot Protocol, 1: Report Protocol(default) */
69 uint8_t keyboard_protocol = 1;
70 static uint8_t keyboard_led_stats = 0;
72 static report_keyboard_t keyboard_report_sent;
75 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
76 void usb_get_midi(MidiDevice * device);
77 void midi_usb_init(MidiDevice * device);
81 static uint8_t keyboard_leds(void);
82 static void send_keyboard(report_keyboard_t *report);
83 static void send_mouse(report_mouse_t *report);
84 static void send_system(uint16_t data);
85 static void send_consumer(uint16_t data);
86 host_driver_t lufa_driver = {
99 /*******************************************************************************
101 ******************************************************************************/
104 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
108 .StreamingInterfaceNumber = AS_INTERFACE,
111 .Address = MIDI_STREAM_IN_EPADDR,
112 .Size = MIDI_STREAM_EPSIZE,
117 .Address = MIDI_STREAM_OUT_EPADDR,
118 .Size = MIDI_STREAM_EPSIZE,
124 #define SYSEX_START_OR_CONT 0x40
125 #define SYSEX_ENDS_IN_1 0x50
126 #define SYSEX_ENDS_IN_2 0x60
127 #define SYSEX_ENDS_IN_3 0x70
129 #define SYS_COMMON_1 0x50
130 #define SYS_COMMON_2 0x20
131 #define SYS_COMMON_3 0x30
134 #ifdef VIRTSER_ENABLE
135 USB_ClassInfo_CDC_Device_t cdc_device =
139 .ControlInterfaceNumber = CCI_INTERFACE,
142 .Address = CDC_IN_EPADDR,
148 .Address = CDC_OUT_EPADDR,
152 .NotificationEndpoint =
154 .Address = CDC_NOTIFICATION_EPADDR,
155 .Size = CDC_NOTIFICATION_EPSIZE,
163 /*******************************************************************************
165 ******************************************************************************/
166 #ifdef CONSOLE_ENABLE
167 static void Console_Task(void)
169 /* Device must be connected and configured for the task to run */
170 if (USB_DeviceState != DEVICE_STATE_Configured)
173 uint8_t ep = Endpoint_GetCurrentEndpoint();
176 // TODO: impl receivechar()/recvchar()
177 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
179 /* Check to see if a packet has been sent from the host */
180 if (Endpoint_IsOUTReceived())
182 /* Check to see if the packet contains data */
183 if (Endpoint_IsReadWriteAllowed())
185 /* Create a temporary buffer to hold the read in report from the host */
186 uint8_t ConsoleData[CONSOLE_EPSIZE];
188 /* Read Console Report Data */
189 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
191 /* Process Console Report Data */
192 //ProcessConsoleHIDReport(ConsoleData);
195 /* Finalize the stream transfer to send the last packet */
201 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
202 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
203 Endpoint_SelectEndpoint(ep);
208 while (Endpoint_IsReadWriteAllowed())
211 // flash senchar packet
212 if (Endpoint_IsINReady()) {
216 Endpoint_SelectEndpoint(ep);
221 /*******************************************************************************
223 ******************************************************************************/
225 * Event Order of Plug in:
226 * 0) EVENT_USB_Device_Connect
227 * 1) EVENT_USB_Device_Suspend
228 * 2) EVENT_USB_Device_Reset
229 * 3) EVENT_USB_Device_Wake
231 void EVENT_USB_Device_Connect(void)
234 /* For battery powered device */
235 if (!USB_IsInitialized) {
238 USB_Device_EnableSOFEvents();
242 void EVENT_USB_Device_Disconnect(void)
245 /* For battery powered device */
246 USB_IsInitialized = false;
247 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
248 if (USB_IsInitialized) {
249 USB_Disable(); // Disable all interrupts
250 USB_Controller_Enable();
251 USB_INT_Enable(USB_INT_VBUSTI);
256 void EVENT_USB_Device_Reset(void)
261 void EVENT_USB_Device_Suspend()
264 #ifdef SLEEP_LED_ENABLE
269 void EVENT_USB_Device_WakeUp()
272 suspend_wakeup_init();
274 #ifdef SLEEP_LED_ENABLE
276 // NOTE: converters may not accept this
277 led_set(host_keyboard_leds());
281 #ifdef CONSOLE_ENABLE
282 static bool console_flush = false;
283 #define CONSOLE_FLUSH_SET(b) do { \
284 uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
288 void EVENT_USB_Device_StartOfFrame(void)
290 static uint8_t count;
291 if (++count % 50) return;
294 if (!console_flush) return;
296 console_flush = false;
300 /** Event handler for the USB_ConfigurationChanged event.
301 * This is fired when the host sets the current configuration of the USB device after enumeration.
303 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
304 * it is safe to use singl bank for all endpoints.
306 void EVENT_USB_Device_ConfigurationChanged(void)
308 bool ConfigSuccess = true;
310 /* Setup Keyboard HID Report Endpoints */
311 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
312 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
315 /* Setup Mouse HID Report Endpoint */
316 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
317 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
320 #ifdef EXTRAKEY_ENABLE
321 /* Setup Extra HID Report Endpoint */
322 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
323 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
326 #ifdef CONSOLE_ENABLE
327 /* Setup Console HID Report Endpoints */
328 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
329 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
331 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
332 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
337 /* Setup NKRO HID Report Endpoints */
338 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
339 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
343 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
344 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
347 #ifdef VIRTSER_ENABLE
348 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
349 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
350 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
355 Appendix G: HID Request Support Requirements
357 The following table enumerates the requests that need to be supported by various types of HID class devices.
359 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
360 ------------------------------------------------------------------------------------------
361 Boot Mouse Required Optional Optional Optional Required Required
362 Non-Boot Mouse Required Optional Optional Optional Optional Optional
363 Boot Keyboard Required Optional Required Required Required Required
364 Non-Boot Keybrd Required Optional Required Required Optional Optional
365 Other Device Required Optional Optional Optional Optional Optional
367 /** Event handler for the USB_ControlRequest event.
368 * This is fired before passing along unhandled control requests to the library for processing internally.
370 void EVENT_USB_Device_ControlRequest(void)
372 uint8_t* ReportData = NULL;
373 uint8_t ReportSize = 0;
375 /* Handle HID Class specific requests */
376 switch (USB_ControlRequest.bRequest)
378 case HID_REQ_GetReport:
379 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
381 Endpoint_ClearSETUP();
384 switch (USB_ControlRequest.wIndex) {
385 case KEYBOARD_INTERFACE:
387 ReportData = (uint8_t*)&keyboard_report_sent;
388 ReportSize = sizeof(keyboard_report_sent);
392 /* Write the report data to the control endpoint */
393 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
398 case HID_REQ_SetReport:
399 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
403 switch (USB_ControlRequest.wIndex) {
404 case KEYBOARD_INTERFACE:
408 Endpoint_ClearSETUP();
410 while (!(Endpoint_IsOUTReceived())) {
411 if (USB_DeviceState == DEVICE_STATE_Unattached)
414 keyboard_led_stats = Endpoint_Read_8();
417 Endpoint_ClearStatusStage();
425 case HID_REQ_GetProtocol:
426 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
428 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
429 Endpoint_ClearSETUP();
430 while (!(Endpoint_IsINReady()));
431 Endpoint_Write_8(keyboard_protocol);
433 Endpoint_ClearStatusStage();
438 case HID_REQ_SetProtocol:
439 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
441 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
442 Endpoint_ClearSETUP();
443 Endpoint_ClearStatusStage();
445 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
451 case HID_REQ_SetIdle:
452 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
454 Endpoint_ClearSETUP();
455 Endpoint_ClearStatusStage();
457 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
461 case HID_REQ_GetIdle:
462 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
464 Endpoint_ClearSETUP();
465 while (!(Endpoint_IsINReady()));
466 Endpoint_Write_8(keyboard_idle);
468 Endpoint_ClearStatusStage();
474 #ifdef VIRTSER_ENABLE
475 CDC_Device_ProcessControlRequest(&cdc_device);
479 /*******************************************************************************
482 ******************************************************************************/
483 static uint8_t keyboard_leds(void)
485 return keyboard_led_stats;
488 static void send_keyboard(report_keyboard_t *report)
491 #ifdef BLUETOOTH_ENABLE
492 bluefruit_serial_send(0xFD);
493 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
494 bluefruit_serial_send(report->raw[i]);
498 uint8_t timeout = 255;
500 if (USB_DeviceState != DEVICE_STATE_Configured)
503 /* Select the Keyboard Report Endpoint */
505 if (keyboard_protocol && keyboard_nkro) {
506 /* Report protocol - NKRO */
507 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
509 /* Check if write ready for a polling interval around 1ms */
510 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
511 if (!Endpoint_IsReadWriteAllowed()) return;
513 /* Write Keyboard Report Data */
514 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
520 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
522 /* Check if write ready for a polling interval around 10ms */
523 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
524 if (!Endpoint_IsReadWriteAllowed()) return;
526 /* Write Keyboard Report Data */
527 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
530 /* Finalize the stream transfer to send the last packet */
533 keyboard_report_sent = *report;
536 static void send_mouse(report_mouse_t *report)
540 #ifdef BLUETOOTH_ENABLE
541 bluefruit_serial_send(0xFD);
542 bluefruit_serial_send(0x00);
543 bluefruit_serial_send(0x03);
544 bluefruit_serial_send(report->buttons);
545 bluefruit_serial_send(report->x);
546 bluefruit_serial_send(report->y);
547 bluefruit_serial_send(report->v); // should try sending the wheel v here
548 bluefruit_serial_send(report->h); // should try sending the wheel h here
549 bluefruit_serial_send(0x00);
552 uint8_t timeout = 255;
554 if (USB_DeviceState != DEVICE_STATE_Configured)
557 /* Select the Mouse Report Endpoint */
558 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
560 /* Check if write ready for a polling interval around 10ms */
561 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
562 if (!Endpoint_IsReadWriteAllowed()) return;
564 /* Write Mouse Report Data */
565 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
567 /* Finalize the stream transfer to send the last packet */
572 static void send_system(uint16_t data)
574 uint8_t timeout = 255;
576 if (USB_DeviceState != DEVICE_STATE_Configured)
580 .report_id = REPORT_ID_SYSTEM,
583 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
585 /* Check if write ready for a polling interval around 10ms */
586 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
587 if (!Endpoint_IsReadWriteAllowed()) return;
589 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
593 static void send_consumer(uint16_t data)
596 #ifdef BLUETOOTH_ENABLE
597 static uint16_t last_data = 0;
598 if (data == last_data) return;
600 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
601 bluefruit_serial_send(0xFD);
602 bluefruit_serial_send(0x00);
603 bluefruit_serial_send(0x02);
604 bluefruit_serial_send((bitmap>>8)&0xFF);
605 bluefruit_serial_send(bitmap&0xFF);
606 bluefruit_serial_send(0x00);
607 bluefruit_serial_send(0x00);
608 bluefruit_serial_send(0x00);
609 bluefruit_serial_send(0x00);
612 uint8_t timeout = 255;
614 if (USB_DeviceState != DEVICE_STATE_Configured)
618 .report_id = REPORT_ID_CONSUMER,
621 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
623 /* Check if write ready for a polling interval around 10ms */
624 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
625 if (!Endpoint_IsReadWriteAllowed()) return;
627 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
632 /*******************************************************************************
634 ******************************************************************************/
635 #ifdef CONSOLE_ENABLE
636 #define SEND_TIMEOUT 5
637 int8_t sendchar(uint8_t c)
639 // Not wait once timeouted.
640 // Because sendchar() is called so many times, waiting each call causes big lag.
641 static bool timeouted = false;
643 // prevents Console_Task() from running during sendchar() runs.
644 // or char will be lost. These two function is mutually exclusive.
645 CONSOLE_FLUSH_SET(false);
647 if (USB_DeviceState != DEVICE_STATE_Configured)
650 uint8_t ep = Endpoint_GetCurrentEndpoint();
651 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
652 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
656 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
662 uint8_t timeout = SEND_TIMEOUT;
663 while (!Endpoint_IsReadWriteAllowed()) {
664 if (USB_DeviceState != DEVICE_STATE_Configured) {
667 if (Endpoint_IsStalled()) {
679 // send when bank is full
680 if (!Endpoint_IsReadWriteAllowed()) {
681 while (!(Endpoint_IsINReady()));
684 CONSOLE_FLUSH_SET(true);
687 Endpoint_SelectEndpoint(ep);
690 Endpoint_SelectEndpoint(ep);
694 int8_t sendchar(uint8_t c)
700 /*******************************************************************************
702 ******************************************************************************/
705 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
706 MIDI_EventPacket_t event;
713 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
715 //if the length is undefined we assume it is a SYSEX message
716 if (midi_packet_length(byte0) == UNDEFINED) {
719 if (byte2 == SYSEX_END)
720 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
722 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
725 if (byte1 == SYSEX_END)
726 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
728 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
731 if (byte0 == SYSEX_END)
732 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
734 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
737 return; //invalid cnt
740 //deal with 'system common' messages
741 //TODO are there any more?
742 switch(byte0 & 0xF0){
743 case MIDI_SONGPOSITION:
744 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
746 case MIDI_SONGSELECT:
747 case MIDI_TC_QUARTERFRAME:
748 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
751 event.Event = MIDI_EVENT(cable, byte0);
756 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
757 // Endpoint_ClearIN();
759 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
760 MIDI_Device_Flush(&USB_MIDI_Interface);
761 MIDI_Device_USBTask(&USB_MIDI_Interface);
765 void usb_get_midi(MidiDevice * device) {
766 MIDI_EventPacket_t event;
767 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
769 midi_packet_length_t length = midi_packet_length(event.Data1);
771 input[0] = event.Data1;
772 input[1] = event.Data2;
773 input[2] = event.Data3;
774 if (length == UNDEFINED) {
776 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
778 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
780 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
787 //pass the data to the device input function
788 if (length != UNDEFINED)
789 midi_device_input(device, length, input);
791 MIDI_Device_USBTask(&USB_MIDI_Interface);
795 void midi_usb_init(MidiDevice * device){
796 midi_device_init(device);
797 midi_device_set_send_func(device, usb_send_func);
798 midi_device_set_pre_input_process_func(device, usb_get_midi);
807 /* Device must be connected and configured for the task to run */
808 dprint("in MIDI_TASK\n");
809 if (USB_DeviceState != DEVICE_STATE_Configured)
811 dprint("continuing in MIDI_TASK\n");
813 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
815 if (Endpoint_IsINReady())
818 dprint("Endpoint is ready\n");
820 uint8_t MIDICommand = 0;
823 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
824 uint8_t Channel = MIDI_CHANNEL(1);
826 MIDICommand = MIDI_COMMAND_NOTE_ON;
829 /* Check if a MIDI command is to be sent */
832 dprint("Command exists\n");
833 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
835 .Event = MIDI_EVENT(0, MIDICommand),
837 .Data1 = MIDICommand | Channel,
839 .Data3 = MIDI_STANDARD_VELOCITY,
842 /* Write the MIDI event packet to the endpoint */
843 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
845 /* Send the data in the endpoint to the host */
851 /* Select the MIDI OUT stream */
852 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
854 /* Check if a MIDI command has been received */
855 if (Endpoint_IsOUTReceived())
857 MIDI_EventPacket_t MIDIEvent;
859 /* Read the MIDI event packet from the endpoint */
860 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
862 /* If the endpoint is now empty, clear the bank */
863 if (!(Endpoint_BytesInEndpoint()))
865 /* Clear the endpoint ready for new packet */
873 /*******************************************************************************
875 ******************************************************************************/
877 #ifdef VIRTSER_ENABLE
878 void virtser_init(void)
880 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
881 CDC_Device_SendControlLineStateChange(&cdc_device);
884 void virtser_recv(uint8_t c) __attribute__ ((weak));
885 void virtser_recv(uint8_t c)
890 void virtser_task(void)
892 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
896 ch = CDC_Device_ReceiveByte(&cdc_device);
900 void virtser_send(const uint8_t byte)
902 uint8_t timeout = 255;
903 uint8_t ep = Endpoint_GetCurrentEndpoint();
905 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
908 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
910 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
911 Endpoint_SelectEndpoint(ep);
915 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
917 Endpoint_Write_8(byte);
918 CDC_Device_Flush(&cdc_device);
920 if (Endpoint_IsINReady()) {
924 Endpoint_SelectEndpoint(ep);
929 /*******************************************************************************
931 ******************************************************************************/
932 static void setup_mcu(void)
934 /* Disable watchdog if enabled by bootloader/fuses */
935 MCUSR &= ~(1 << WDRF);
938 /* Disable clock division */
939 // clock_prescale_set(clock_div_1);
941 CLKPR = (1 << CLKPCE);
942 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
945 static void setup_usb(void)
947 // Leonardo needs. Without this USB device is not recognized.
953 USB_Device_EnableSOFEvents();
954 print_set_sendchar(sendchar);
959 void fallthrough_callback(MidiDevice * device,
960 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
961 void cc_callback(MidiDevice * device,
962 uint8_t chan, uint8_t num, uint8_t val);
963 void sysex_callback(MidiDevice * device,
964 uint16_t start, uint8_t length, uint8_t * data);
967 int main(void) __attribute__ ((weak));
972 midi_device_init(&midi_device);
973 midi_device_set_send_func(&midi_device, usb_send_func);
974 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
983 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
984 midi_register_cc_callback(&midi_device, cc_callback);
985 midi_register_sysex_callback(&midi_device, sysex_callback);
988 // midi_send_cc(&midi_device, 0, 1, 2);
989 // midi_send_cc(&midi_device, 15, 1, 0);
990 // midi_send_noteon(&midi_device, 0, 64, 127);
991 // midi_send_noteoff(&midi_device, 0, 64, 127);
994 #ifdef BLUETOOTH_ENABLE
998 /* wait for USB startup & debug output */
1001 while (USB_DeviceState != DEVICE_STATE_Configured) {
1002 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1008 print("USB configured.\n");
1014 host_set_driver(&lufa_driver);
1015 #ifdef SLEEP_LED_ENABLE
1019 #ifdef VIRTSER_ENABLE
1023 print("Keyboard start.\n");
1025 #ifndef BLUETOOTH_ENABLE
1026 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1028 suspend_power_down();
1029 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1030 USB_Device_SendRemoteWakeup();
1036 midi_device_process(&midi_device);
1041 #ifdef VIRTSER_ENABLE
1043 CDC_Device_USBTask(&cdc_device);
1046 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1053 void fallthrough_callback(MidiDevice * device,
1054 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
1058 switch (byte0 & 0xF0) {
1060 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1063 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1067 if (byte0 == MIDI_STOP) {
1073 void cc_callback(MidiDevice * device,
1074 uint8_t chan, uint8_t num, uint8_t val) {
1075 //sending it back on the next channel
1076 midi_send_cc(device, (chan + 1) % 16, num, val);
1079 void sysex_callback(MidiDevice * device,
1080 uint16_t start, uint8_t length, uint8_t * data) {
1081 for (int i = 0; i < length; i++)
1082 midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));