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"
74 uint8_t keyboard_idle = 0;
75 /* 0: Boot Protocol, 1: Report Protocol(default) */
76 uint8_t keyboard_protocol = 1;
77 static uint8_t keyboard_led_stats = 0;
79 static report_keyboard_t keyboard_report_sent;
82 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
83 void usb_get_midi(MidiDevice * device);
84 void midi_usb_init(MidiDevice * device);
88 static uint8_t keyboard_leds(void);
89 static void send_keyboard(report_keyboard_t *report);
90 static void send_mouse(report_mouse_t *report);
91 static void send_system(uint16_t data);
92 static void send_consumer(uint16_t data);
93 host_driver_t lufa_driver = {
106 /*******************************************************************************
108 ******************************************************************************/
111 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
115 .StreamingInterfaceNumber = AS_INTERFACE,
118 .Address = MIDI_STREAM_IN_EPADDR,
119 .Size = MIDI_STREAM_EPSIZE,
124 .Address = MIDI_STREAM_OUT_EPADDR,
125 .Size = MIDI_STREAM_EPSIZE,
131 #define SYSEX_START_OR_CONT 0x40
132 #define SYSEX_ENDS_IN_1 0x50
133 #define SYSEX_ENDS_IN_2 0x60
134 #define SYSEX_ENDS_IN_3 0x70
136 #define SYS_COMMON_1 0x50
137 #define SYS_COMMON_2 0x20
138 #define SYS_COMMON_3 0x30
141 #ifdef VIRTSER_ENABLE
142 USB_ClassInfo_CDC_Device_t cdc_device =
146 .ControlInterfaceNumber = CCI_INTERFACE,
149 .Address = CDC_IN_EPADDR,
155 .Address = CDC_OUT_EPADDR,
159 .NotificationEndpoint =
161 .Address = CDC_NOTIFICATION_EPADDR,
162 .Size = CDC_NOTIFICATION_EPSIZE,
170 /*******************************************************************************
172 ******************************************************************************/
173 #ifdef CONSOLE_ENABLE
174 static void Console_Task(void)
176 /* Device must be connected and configured for the task to run */
177 if (USB_DeviceState != DEVICE_STATE_Configured)
180 uint8_t ep = Endpoint_GetCurrentEndpoint();
183 // TODO: impl receivechar()/recvchar()
184 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
186 /* Check to see if a packet has been sent from the host */
187 if (Endpoint_IsOUTReceived())
189 /* Check to see if the packet contains data */
190 if (Endpoint_IsReadWriteAllowed())
192 /* Create a temporary buffer to hold the read in report from the host */
193 uint8_t ConsoleData[CONSOLE_EPSIZE];
195 /* Read Console Report Data */
196 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
198 /* Process Console Report Data */
199 //ProcessConsoleHIDReport(ConsoleData);
202 /* Finalize the stream transfer to send the last packet */
208 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
209 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
210 Endpoint_SelectEndpoint(ep);
215 while (Endpoint_IsReadWriteAllowed())
218 // flash senchar packet
219 if (Endpoint_IsINReady()) {
223 Endpoint_SelectEndpoint(ep);
228 /*******************************************************************************
230 ******************************************************************************/
232 * Event Order of Plug in:
233 * 0) EVENT_USB_Device_Connect
234 * 1) EVENT_USB_Device_Suspend
235 * 2) EVENT_USB_Device_Reset
236 * 3) EVENT_USB_Device_Wake
238 void EVENT_USB_Device_Connect(void)
241 /* For battery powered device */
242 if (!USB_IsInitialized) {
245 USB_Device_EnableSOFEvents();
249 void EVENT_USB_Device_Disconnect(void)
252 /* For battery powered device */
253 USB_IsInitialized = false;
254 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
255 if (USB_IsInitialized) {
256 USB_Disable(); // Disable all interrupts
257 USB_Controller_Enable();
258 USB_INT_Enable(USB_INT_VBUSTI);
263 void EVENT_USB_Device_Reset(void)
268 void EVENT_USB_Device_Suspend()
271 #ifdef SLEEP_LED_ENABLE
276 void EVENT_USB_Device_WakeUp()
279 suspend_wakeup_init();
281 #ifdef SLEEP_LED_ENABLE
283 // NOTE: converters may not accept this
284 led_set(host_keyboard_leds());
288 #ifdef CONSOLE_ENABLE
289 static bool console_flush = false;
290 #define CONSOLE_FLUSH_SET(b) do { \
291 uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
295 void EVENT_USB_Device_StartOfFrame(void)
297 static uint8_t count;
298 if (++count % 50) return;
301 if (!console_flush) return;
303 console_flush = false;
307 /** Event handler for the USB_ConfigurationChanged event.
308 * This is fired when the host sets the current configuration of the USB device after enumeration.
310 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
311 * it is safe to use singl bank for all endpoints.
313 void EVENT_USB_Device_ConfigurationChanged(void)
315 bool ConfigSuccess = true;
317 /* Setup Keyboard HID Report Endpoints */
318 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
319 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
322 /* Setup Mouse HID Report Endpoint */
323 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
324 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
327 #ifdef EXTRAKEY_ENABLE
328 /* Setup Extra HID Report Endpoint */
329 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
330 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
333 #ifdef CONSOLE_ENABLE
334 /* Setup Console HID Report Endpoints */
335 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
336 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
338 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
339 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
344 /* Setup NKRO HID Report Endpoints */
345 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
346 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
350 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
351 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
354 #ifdef VIRTSER_ENABLE
355 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
356 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
357 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
362 Appendix G: HID Request Support Requirements
364 The following table enumerates the requests that need to be supported by various types of HID class devices.
366 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
367 ------------------------------------------------------------------------------------------
368 Boot Mouse Required Optional Optional Optional Required Required
369 Non-Boot Mouse Required Optional Optional Optional Optional Optional
370 Boot Keyboard Required Optional Required Required Required Required
371 Non-Boot Keybrd Required Optional Required Required Optional Optional
372 Other Device Required Optional Optional Optional Optional Optional
374 /** Event handler for the USB_ControlRequest event.
375 * This is fired before passing along unhandled control requests to the library for processing internally.
377 void EVENT_USB_Device_ControlRequest(void)
379 uint8_t* ReportData = NULL;
380 uint8_t ReportSize = 0;
382 /* Handle HID Class specific requests */
383 switch (USB_ControlRequest.bRequest)
385 case HID_REQ_GetReport:
386 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
388 Endpoint_ClearSETUP();
391 switch (USB_ControlRequest.wIndex) {
392 case KEYBOARD_INTERFACE:
394 ReportData = (uint8_t*)&keyboard_report_sent;
395 ReportSize = sizeof(keyboard_report_sent);
399 /* Write the report data to the control endpoint */
400 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
405 case HID_REQ_SetReport:
406 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
410 switch (USB_ControlRequest.wIndex) {
411 case KEYBOARD_INTERFACE:
415 Endpoint_ClearSETUP();
417 while (!(Endpoint_IsOUTReceived())) {
418 if (USB_DeviceState == DEVICE_STATE_Unattached)
421 keyboard_led_stats = Endpoint_Read_8();
424 Endpoint_ClearStatusStage();
432 case HID_REQ_GetProtocol:
433 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
435 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
436 Endpoint_ClearSETUP();
437 while (!(Endpoint_IsINReady()));
438 Endpoint_Write_8(keyboard_protocol);
440 Endpoint_ClearStatusStage();
445 case HID_REQ_SetProtocol:
446 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
448 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
449 Endpoint_ClearSETUP();
450 Endpoint_ClearStatusStage();
452 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
458 case HID_REQ_SetIdle:
459 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
461 Endpoint_ClearSETUP();
462 Endpoint_ClearStatusStage();
464 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
468 case HID_REQ_GetIdle:
469 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
471 Endpoint_ClearSETUP();
472 while (!(Endpoint_IsINReady()));
473 Endpoint_Write_8(keyboard_idle);
475 Endpoint_ClearStatusStage();
481 #ifdef VIRTSER_ENABLE
482 CDC_Device_ProcessControlRequest(&cdc_device);
486 /*******************************************************************************
489 ******************************************************************************/
490 static uint8_t keyboard_leds(void)
492 return keyboard_led_stats;
495 static void send_keyboard(report_keyboard_t *report)
498 #ifdef BLUETOOTH_ENABLE
499 bluefruit_serial_send(0xFD);
500 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
501 bluefruit_serial_send(report->raw[i]);
505 uint8_t timeout = 255;
507 if (USB_DeviceState != DEVICE_STATE_Configured)
510 /* Select the Keyboard Report Endpoint */
512 if (keyboard_protocol && keymap_config.nkro) {
513 /* Report protocol - NKRO */
514 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
516 /* Check if write ready for a polling interval around 1ms */
517 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
518 if (!Endpoint_IsReadWriteAllowed()) return;
520 /* Write Keyboard Report Data */
521 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
527 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
529 /* Check if write ready for a polling interval around 10ms */
530 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
531 if (!Endpoint_IsReadWriteAllowed()) return;
533 /* Write Keyboard Report Data */
534 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
537 /* Finalize the stream transfer to send the last packet */
540 keyboard_report_sent = *report;
543 static void send_mouse(report_mouse_t *report)
547 #ifdef BLUETOOTH_ENABLE
548 bluefruit_serial_send(0xFD);
549 bluefruit_serial_send(0x00);
550 bluefruit_serial_send(0x03);
551 bluefruit_serial_send(report->buttons);
552 bluefruit_serial_send(report->x);
553 bluefruit_serial_send(report->y);
554 bluefruit_serial_send(report->v); // should try sending the wheel v here
555 bluefruit_serial_send(report->h); // should try sending the wheel h here
556 bluefruit_serial_send(0x00);
559 uint8_t timeout = 255;
561 if (USB_DeviceState != DEVICE_STATE_Configured)
564 /* Select the Mouse Report Endpoint */
565 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
567 /* Check if write ready for a polling interval around 10ms */
568 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
569 if (!Endpoint_IsReadWriteAllowed()) return;
571 /* Write Mouse Report Data */
572 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
574 /* Finalize the stream transfer to send the last packet */
579 static void send_system(uint16_t data)
581 uint8_t timeout = 255;
583 if (USB_DeviceState != DEVICE_STATE_Configured)
587 .report_id = REPORT_ID_SYSTEM,
590 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
592 /* Check if write ready for a polling interval around 10ms */
593 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
594 if (!Endpoint_IsReadWriteAllowed()) return;
596 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
600 static void send_consumer(uint16_t data)
603 #ifdef BLUETOOTH_ENABLE
604 static uint16_t last_data = 0;
605 if (data == last_data) return;
607 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
608 bluefruit_serial_send(0xFD);
609 bluefruit_serial_send(0x00);
610 bluefruit_serial_send(0x02);
611 bluefruit_serial_send((bitmap>>8)&0xFF);
612 bluefruit_serial_send(bitmap&0xFF);
613 bluefruit_serial_send(0x00);
614 bluefruit_serial_send(0x00);
615 bluefruit_serial_send(0x00);
616 bluefruit_serial_send(0x00);
619 uint8_t timeout = 255;
621 if (USB_DeviceState != DEVICE_STATE_Configured)
625 .report_id = REPORT_ID_CONSUMER,
628 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
630 /* Check if write ready for a polling interval around 10ms */
631 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
632 if (!Endpoint_IsReadWriteAllowed()) return;
634 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
639 /*******************************************************************************
641 ******************************************************************************/
642 #ifdef CONSOLE_ENABLE
643 #define SEND_TIMEOUT 5
644 int8_t sendchar(uint8_t c)
646 // Not wait once timeouted.
647 // Because sendchar() is called so many times, waiting each call causes big lag.
648 static bool timeouted = false;
650 // prevents Console_Task() from running during sendchar() runs.
651 // or char will be lost. These two function is mutually exclusive.
652 CONSOLE_FLUSH_SET(false);
654 if (USB_DeviceState != DEVICE_STATE_Configured)
657 uint8_t ep = Endpoint_GetCurrentEndpoint();
658 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
659 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
663 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
669 uint8_t timeout = SEND_TIMEOUT;
670 while (!Endpoint_IsReadWriteAllowed()) {
671 if (USB_DeviceState != DEVICE_STATE_Configured) {
674 if (Endpoint_IsStalled()) {
686 // send when bank is full
687 if (!Endpoint_IsReadWriteAllowed()) {
688 while (!(Endpoint_IsINReady()));
691 CONSOLE_FLUSH_SET(true);
694 Endpoint_SelectEndpoint(ep);
697 Endpoint_SelectEndpoint(ep);
701 int8_t sendchar(uint8_t c)
707 /*******************************************************************************
709 ******************************************************************************/
712 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
713 MIDI_EventPacket_t event;
720 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
722 //if the length is undefined we assume it is a SYSEX message
723 if (midi_packet_length(byte0) == UNDEFINED) {
726 if (byte2 == SYSEX_END)
727 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
729 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
732 if (byte1 == SYSEX_END)
733 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
735 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
738 if (byte0 == SYSEX_END)
739 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
741 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
744 return; //invalid cnt
747 //deal with 'system common' messages
748 //TODO are there any more?
749 switch(byte0 & 0xF0){
750 case MIDI_SONGPOSITION:
751 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
753 case MIDI_SONGSELECT:
754 case MIDI_TC_QUARTERFRAME:
755 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
758 event.Event = MIDI_EVENT(cable, byte0);
763 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
764 // Endpoint_ClearIN();
766 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
767 MIDI_Device_Flush(&USB_MIDI_Interface);
768 MIDI_Device_USBTask(&USB_MIDI_Interface);
772 void usb_get_midi(MidiDevice * device) {
773 MIDI_EventPacket_t event;
774 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
776 midi_packet_length_t length = midi_packet_length(event.Data1);
778 input[0] = event.Data1;
779 input[1] = event.Data2;
780 input[2] = event.Data3;
781 if (length == UNDEFINED) {
783 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
785 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
787 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
794 //pass the data to the device input function
795 if (length != UNDEFINED)
796 midi_device_input(device, length, input);
798 MIDI_Device_USBTask(&USB_MIDI_Interface);
802 void midi_usb_init(MidiDevice * device){
803 midi_device_init(device);
804 midi_device_set_send_func(device, usb_send_func);
805 midi_device_set_pre_input_process_func(device, usb_get_midi);
814 /* Device must be connected and configured for the task to run */
815 dprint("in MIDI_TASK\n");
816 if (USB_DeviceState != DEVICE_STATE_Configured)
818 dprint("continuing in MIDI_TASK\n");
820 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
822 if (Endpoint_IsINReady())
825 dprint("Endpoint is ready\n");
827 uint8_t MIDICommand = 0;
830 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
831 uint8_t Channel = MIDI_CHANNEL(1);
833 MIDICommand = MIDI_COMMAND_NOTE_ON;
836 /* Check if a MIDI command is to be sent */
839 dprint("Command exists\n");
840 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
842 .Event = MIDI_EVENT(0, MIDICommand),
844 .Data1 = MIDICommand | Channel,
846 .Data3 = MIDI_STANDARD_VELOCITY,
849 /* Write the MIDI event packet to the endpoint */
850 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
852 /* Send the data in the endpoint to the host */
858 /* Select the MIDI OUT stream */
859 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
861 /* Check if a MIDI command has been received */
862 if (Endpoint_IsOUTReceived())
864 MIDI_EventPacket_t MIDIEvent;
866 /* Read the MIDI event packet from the endpoint */
867 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
869 /* If the endpoint is now empty, clear the bank */
870 if (!(Endpoint_BytesInEndpoint()))
872 /* Clear the endpoint ready for new packet */
880 /*******************************************************************************
882 ******************************************************************************/
884 #ifdef VIRTSER_ENABLE
885 void virtser_init(void)
887 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
888 CDC_Device_SendControlLineStateChange(&cdc_device);
891 void virtser_recv(uint8_t c) __attribute__ ((weak));
892 void virtser_recv(uint8_t c)
897 void virtser_task(void)
899 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
903 ch = CDC_Device_ReceiveByte(&cdc_device);
907 void virtser_send(const uint8_t byte)
909 uint8_t timeout = 255;
910 uint8_t ep = Endpoint_GetCurrentEndpoint();
912 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
915 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
917 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
918 Endpoint_SelectEndpoint(ep);
922 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
924 Endpoint_Write_8(byte);
925 CDC_Device_Flush(&cdc_device);
927 if (Endpoint_IsINReady()) {
931 Endpoint_SelectEndpoint(ep);
936 /*******************************************************************************
938 ******************************************************************************/
939 static void setup_mcu(void)
941 /* Disable watchdog if enabled by bootloader/fuses */
942 MCUSR &= ~(1 << WDRF);
945 /* Disable clock division */
946 // clock_prescale_set(clock_div_1);
948 CLKPR = (1 << CLKPCE);
949 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
952 static void setup_usb(void)
954 // Leonardo needs. Without this USB device is not recognized.
960 USB_Device_EnableSOFEvents();
961 print_set_sendchar(sendchar);
966 void fallthrough_callback(MidiDevice * device,
967 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
968 void cc_callback(MidiDevice * device,
969 uint8_t chan, uint8_t num, uint8_t val);
970 void sysex_callback(MidiDevice * device,
971 uint16_t start, uint8_t length, uint8_t * data);
974 int main(void) __attribute__ ((weak));
979 midi_device_init(&midi_device);
980 midi_device_set_send_func(&midi_device, usb_send_func);
981 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
990 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
991 midi_register_cc_callback(&midi_device, cc_callback);
992 midi_register_sysex_callback(&midi_device, sysex_callback);
995 // midi_send_cc(&midi_device, 0, 1, 2);
996 // midi_send_cc(&midi_device, 15, 1, 0);
997 // midi_send_noteon(&midi_device, 0, 64, 127);
998 // midi_send_noteoff(&midi_device, 0, 64, 127);
1001 #ifdef BLUETOOTH_ENABLE
1005 /* wait for USB startup & debug output */
1008 while (USB_DeviceState != DEVICE_STATE_Configured) {
1009 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1015 print("USB configured.\n");
1021 host_set_driver(&lufa_driver);
1022 #ifdef SLEEP_LED_ENABLE
1026 #ifdef VIRTSER_ENABLE
1030 print("Keyboard start.\n");
1032 #ifndef BLUETOOTH_ENABLE
1033 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1035 suspend_power_down();
1036 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1037 USB_Device_SendRemoteWakeup();
1043 midi_device_process(&midi_device);
1048 #ifdef VIRTSER_ENABLE
1050 CDC_Device_USBTask(&cdc_device);
1053 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1060 void fallthrough_callback(MidiDevice * device,
1061 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
1065 switch (byte0 & 0xF0) {
1067 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1070 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1074 if (byte0 == MIDI_STOP) {
1080 void cc_callback(MidiDevice * device,
1081 uint8_t chan, uint8_t num, uint8_t val) {
1082 //sending it back on the next channel
1083 midi_send_cc(device, (chan + 1) % 16, num, val);
1086 void sysex_callback(MidiDevice * device,
1087 uint16_t start, uint8_t length, uint8_t * data) {
1088 for (int i = 0; i < length; i++)
1089 midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));