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"
55 #include <util/atomic.h>
58 #include "keycode_config.h"
60 extern keymap_config_t keymap_config;
68 #ifdef BLUETOOTH_ENABLE
69 #include "bluetooth.h"
71 #ifdef ADAFRUIT_BLE_ENABLE
72 #include "adafruit_ble.h"
79 #if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE)
84 #include "sysex_tools.h"
91 uint8_t keyboard_idle = 0;
92 /* 0: Boot Protocol, 1: Report Protocol(default) */
93 uint8_t keyboard_protocol = 1;
94 static uint8_t keyboard_led_stats = 0;
96 static report_keyboard_t keyboard_report_sent;
99 static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
100 static void usb_get_midi(MidiDevice * device);
101 static void midi_usb_init(MidiDevice * device);
105 static uint8_t keyboard_leds(void);
106 static void send_keyboard(report_keyboard_t *report);
107 static void send_mouse(report_mouse_t *report);
108 static void send_system(uint16_t data);
109 static void send_consumer(uint16_t data);
110 host_driver_t lufa_driver = {
123 /*******************************************************************************
125 ******************************************************************************/
128 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
132 .StreamingInterfaceNumber = AS_INTERFACE,
135 .Address = MIDI_STREAM_IN_EPADDR,
136 .Size = MIDI_STREAM_EPSIZE,
141 .Address = MIDI_STREAM_OUT_EPADDR,
142 .Size = MIDI_STREAM_EPSIZE,
148 #define SYSEX_START_OR_CONT 0x40
149 #define SYSEX_ENDS_IN_1 0x50
150 #define SYSEX_ENDS_IN_2 0x60
151 #define SYSEX_ENDS_IN_3 0x70
153 #define SYS_COMMON_1 0x50
154 #define SYS_COMMON_2 0x20
155 #define SYS_COMMON_3 0x30
158 #ifdef VIRTSER_ENABLE
159 USB_ClassInfo_CDC_Device_t cdc_device =
163 .ControlInterfaceNumber = CCI_INTERFACE,
166 .Address = CDC_IN_EPADDR,
172 .Address = CDC_OUT_EPADDR,
176 .NotificationEndpoint =
178 .Address = CDC_NOTIFICATION_EPADDR,
179 .Size = CDC_NOTIFICATION_EPSIZE,
188 void raw_hid_send( uint8_t *data, uint8_t length )
190 // TODO: implement variable size packet
191 if ( length != RAW_EPSIZE )
196 if (USB_DeviceState != DEVICE_STATE_Configured)
201 // TODO: decide if we allow calls to raw_hid_send() in the middle
202 // of other endpoint usage.
203 uint8_t ep = Endpoint_GetCurrentEndpoint();
205 Endpoint_SelectEndpoint(RAW_IN_EPNUM);
207 // Check to see if the host is ready to accept another packet
208 if (Endpoint_IsINReady())
211 Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL);
212 // Finalize the stream transfer to send the last packet
216 Endpoint_SelectEndpoint(ep);
219 __attribute__ ((weak))
220 void raw_hid_receive( uint8_t *data, uint8_t length )
222 // Users should #include "raw_hid.h" in their own code
223 // and implement this function there. Leave this as weak linkage
224 // so users can opt to not handle data coming in.
227 static void raw_hid_task(void)
229 // Create a temporary buffer to hold the read in data from the host
230 uint8_t data[RAW_EPSIZE];
231 bool data_read = false;
233 // Device must be connected and configured for the task to run
234 if (USB_DeviceState != DEVICE_STATE_Configured)
237 Endpoint_SelectEndpoint(RAW_OUT_EPNUM);
239 // Check to see if a packet has been sent from the host
240 if (Endpoint_IsOUTReceived())
242 // Check to see if the packet contains data
243 if (Endpoint_IsReadWriteAllowed())
246 Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
250 // Finalize the stream transfer to receive the last packet
255 raw_hid_receive( data, sizeof(data) );
261 /*******************************************************************************
263 ******************************************************************************/
264 #ifdef CONSOLE_ENABLE
265 static void Console_Task(void)
267 /* Device must be connected and configured for the task to run */
268 if (USB_DeviceState != DEVICE_STATE_Configured)
271 uint8_t ep = Endpoint_GetCurrentEndpoint();
274 // TODO: impl receivechar()/recvchar()
275 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
277 /* Check to see if a packet has been sent from the host */
278 if (Endpoint_IsOUTReceived())
280 /* Check to see if the packet contains data */
281 if (Endpoint_IsReadWriteAllowed())
283 /* Create a temporary buffer to hold the read in report from the host */
284 uint8_t ConsoleData[CONSOLE_EPSIZE];
286 /* Read Console Report Data */
287 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
289 /* Process Console Report Data */
290 //ProcessConsoleHIDReport(ConsoleData);
293 /* Finalize the stream transfer to send the last packet */
299 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
300 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
301 Endpoint_SelectEndpoint(ep);
306 while (Endpoint_IsReadWriteAllowed())
309 // flash senchar packet
310 if (Endpoint_IsINReady()) {
314 Endpoint_SelectEndpoint(ep);
319 /*******************************************************************************
321 ******************************************************************************/
323 * Event Order of Plug in:
324 * 0) EVENT_USB_Device_Connect
325 * 1) EVENT_USB_Device_Suspend
326 * 2) EVENT_USB_Device_Reset
327 * 3) EVENT_USB_Device_Wake
329 void EVENT_USB_Device_Connect(void)
332 /* For battery powered device */
333 if (!USB_IsInitialized) {
336 USB_Device_EnableSOFEvents();
340 void EVENT_USB_Device_Disconnect(void)
343 /* For battery powered device */
344 USB_IsInitialized = false;
345 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
346 if (USB_IsInitialized) {
347 USB_Disable(); // Disable all interrupts
348 USB_Controller_Enable();
349 USB_INT_Enable(USB_INT_VBUSTI);
354 void EVENT_USB_Device_Reset(void)
359 void EVENT_USB_Device_Suspend()
362 #ifdef SLEEP_LED_ENABLE
367 void EVENT_USB_Device_WakeUp()
370 suspend_wakeup_init();
372 #ifdef SLEEP_LED_ENABLE
374 // NOTE: converters may not accept this
375 led_set(host_keyboard_leds());
381 #ifdef CONSOLE_ENABLE
382 static bool console_flush = false;
383 #define CONSOLE_FLUSH_SET(b) do { \
384 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\
390 void EVENT_USB_Device_StartOfFrame(void)
392 static uint8_t count;
393 if (++count % 50) return;
396 if (!console_flush) return;
398 console_flush = false;
403 /** Event handler for the USB_ConfigurationChanged event.
404 * This is fired when the host sets the current configuration of the USB device after enumeration.
406 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
407 * it is safe to use singl bank for all endpoints.
409 void EVENT_USB_Device_ConfigurationChanged(void)
411 bool ConfigSuccess = true;
413 /* Setup Keyboard HID Report Endpoints */
414 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
415 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
418 /* Setup Mouse HID Report Endpoint */
419 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
420 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
423 #ifdef EXTRAKEY_ENABLE
424 /* Setup Extra HID Report Endpoint */
425 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
426 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
430 /* Setup Raw HID Report Endpoints */
431 ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
432 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
433 ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
434 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
437 #ifdef CONSOLE_ENABLE
438 /* Setup Console HID Report Endpoints */
439 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
440 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
442 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
443 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
448 /* Setup NKRO HID Report Endpoints */
449 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
450 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
454 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
455 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
458 #ifdef VIRTSER_ENABLE
459 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
460 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
461 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
466 Appendix G: HID Request Support Requirements
468 The following table enumerates the requests that need to be supported by various types of HID class devices.
470 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
471 ------------------------------------------------------------------------------------------
472 Boot Mouse Required Optional Optional Optional Required Required
473 Non-Boot Mouse Required Optional Optional Optional Optional Optional
474 Boot Keyboard Required Optional Required Required Required Required
475 Non-Boot Keybrd Required Optional Required Required Optional Optional
476 Other Device Required Optional Optional Optional Optional Optional
478 /** Event handler for the USB_ControlRequest event.
479 * This is fired before passing along unhandled control requests to the library for processing internally.
481 void EVENT_USB_Device_ControlRequest(void)
483 uint8_t* ReportData = NULL;
484 uint8_t ReportSize = 0;
486 /* Handle HID Class specific requests */
487 switch (USB_ControlRequest.bRequest)
489 case HID_REQ_GetReport:
490 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
492 Endpoint_ClearSETUP();
495 switch (USB_ControlRequest.wIndex) {
496 case KEYBOARD_INTERFACE:
498 ReportData = (uint8_t*)&keyboard_report_sent;
499 ReportSize = sizeof(keyboard_report_sent);
503 /* Write the report data to the control endpoint */
504 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
509 case HID_REQ_SetReport:
510 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
514 switch (USB_ControlRequest.wIndex) {
515 case KEYBOARD_INTERFACE:
519 Endpoint_ClearSETUP();
521 while (!(Endpoint_IsOUTReceived())) {
522 if (USB_DeviceState == DEVICE_STATE_Unattached)
525 keyboard_led_stats = Endpoint_Read_8();
528 Endpoint_ClearStatusStage();
536 case HID_REQ_GetProtocol:
537 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
539 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
540 Endpoint_ClearSETUP();
541 while (!(Endpoint_IsINReady()));
542 Endpoint_Write_8(keyboard_protocol);
544 Endpoint_ClearStatusStage();
549 case HID_REQ_SetProtocol:
550 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
552 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
553 Endpoint_ClearSETUP();
554 Endpoint_ClearStatusStage();
556 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
562 case HID_REQ_SetIdle:
563 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
565 Endpoint_ClearSETUP();
566 Endpoint_ClearStatusStage();
568 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
572 case HID_REQ_GetIdle:
573 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
575 Endpoint_ClearSETUP();
576 while (!(Endpoint_IsINReady()));
577 Endpoint_Write_8(keyboard_idle);
579 Endpoint_ClearStatusStage();
585 #ifdef VIRTSER_ENABLE
586 CDC_Device_ProcessControlRequest(&cdc_device);
590 /*******************************************************************************
593 ******************************************************************************/
594 static uint8_t keyboard_leds(void)
596 return keyboard_led_stats;
603 static inline uint8_t where_to_send(void) {
604 #ifdef ADAFRUIT_BLE_ENABLE
606 if (adafruit_ble_is_connected()) {
607 // For testing, send to BLE as a priority
612 // This is the real policy
613 if (USB_DeviceState != DEVICE_STATE_Configured) {
614 if (adafruit_ble_is_connected()) {
619 return ((USB_DeviceState == DEVICE_STATE_Configured) ? SendToUSB : 0)
620 #ifdef BLUETOOTH_ENABLE
626 static void send_keyboard(report_keyboard_t *report)
628 #ifdef BLUETOOTH_ENABLE
629 bluefruit_serial_send(0xFD);
630 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
631 bluefruit_serial_send(report->raw[i]);
635 uint8_t timeout = 255;
636 uint8_t where = where_to_send();
638 #ifdef ADAFRUIT_BLE_ENABLE
639 if (where & SendToBLE) {
640 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
644 if (!(where & SendToUSB)) {
648 /* Select the Keyboard Report Endpoint */
650 if (keyboard_protocol && keymap_config.nkro) {
651 /* Report protocol - NKRO */
652 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
654 /* Check if write ready for a polling interval around 1ms */
655 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
656 if (!Endpoint_IsReadWriteAllowed()) return;
658 /* Write Keyboard Report Data */
659 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
665 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
667 /* Check if write ready for a polling interval around 10ms */
668 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
669 if (!Endpoint_IsReadWriteAllowed()) return;
671 /* Write Keyboard Report Data */
672 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
675 /* Finalize the stream transfer to send the last packet */
678 keyboard_report_sent = *report;
681 static void send_mouse(report_mouse_t *report)
685 #ifdef BLUETOOTH_ENABLE
686 bluefruit_serial_send(0xFD);
687 bluefruit_serial_send(0x00);
688 bluefruit_serial_send(0x03);
689 bluefruit_serial_send(report->buttons);
690 bluefruit_serial_send(report->x);
691 bluefruit_serial_send(report->y);
692 bluefruit_serial_send(report->v); // should try sending the wheel v here
693 bluefruit_serial_send(report->h); // should try sending the wheel h here
694 bluefruit_serial_send(0x00);
697 uint8_t timeout = 255;
699 uint8_t where = where_to_send();
701 #ifdef ADAFRUIT_BLE_ENABLE
702 if (where & SendToBLE) {
703 // FIXME: mouse buttons
704 adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h);
707 if (!(where & SendToUSB)) {
711 /* Select the Mouse Report Endpoint */
712 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
714 /* Check if write ready for a polling interval around 10ms */
715 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
716 if (!Endpoint_IsReadWriteAllowed()) return;
718 /* Write Mouse Report Data */
719 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
721 /* Finalize the stream transfer to send the last packet */
726 static void send_system(uint16_t data)
728 uint8_t timeout = 255;
730 if (USB_DeviceState != DEVICE_STATE_Configured)
734 .report_id = REPORT_ID_SYSTEM,
735 .usage = data - SYSTEM_POWER_DOWN + 1
737 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
739 /* Check if write ready for a polling interval around 10ms */
740 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
741 if (!Endpoint_IsReadWriteAllowed()) return;
743 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
747 static void send_consumer(uint16_t data)
750 #ifdef BLUETOOTH_ENABLE
751 static uint16_t last_data = 0;
752 if (data == last_data) return;
754 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
755 bluefruit_serial_send(0xFD);
756 bluefruit_serial_send(0x00);
757 bluefruit_serial_send(0x02);
758 bluefruit_serial_send((bitmap>>8)&0xFF);
759 bluefruit_serial_send(bitmap&0xFF);
760 bluefruit_serial_send(0x00);
761 bluefruit_serial_send(0x00);
762 bluefruit_serial_send(0x00);
763 bluefruit_serial_send(0x00);
766 uint8_t timeout = 255;
767 uint8_t where = where_to_send();
769 #ifdef ADAFRUIT_BLE_ENABLE
770 if (where & SendToBLE) {
771 adafruit_ble_send_consumer_key(data, 0);
774 if (!(where & SendToUSB)) {
779 .report_id = REPORT_ID_CONSUMER,
782 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
784 /* Check if write ready for a polling interval around 10ms */
785 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
786 if (!Endpoint_IsReadWriteAllowed()) return;
788 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
793 /*******************************************************************************
795 ******************************************************************************/
796 #ifdef CONSOLE_ENABLE
797 #define SEND_TIMEOUT 5
798 int8_t sendchar(uint8_t c)
800 // Not wait once timeouted.
801 // Because sendchar() is called so many times, waiting each call causes big lag.
802 static bool timeouted = false;
804 // prevents Console_Task() from running during sendchar() runs.
805 // or char will be lost. These two function is mutually exclusive.
806 CONSOLE_FLUSH_SET(false);
808 if (USB_DeviceState != DEVICE_STATE_Configured)
811 uint8_t ep = Endpoint_GetCurrentEndpoint();
812 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
813 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
817 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
823 uint8_t timeout = SEND_TIMEOUT;
824 while (!Endpoint_IsReadWriteAllowed()) {
825 if (USB_DeviceState != DEVICE_STATE_Configured) {
828 if (Endpoint_IsStalled()) {
840 // send when bank is full
841 if (!Endpoint_IsReadWriteAllowed()) {
842 while (!(Endpoint_IsINReady()));
845 CONSOLE_FLUSH_SET(true);
848 Endpoint_SelectEndpoint(ep);
851 Endpoint_SelectEndpoint(ep);
855 int8_t sendchar(uint8_t c)
861 /*******************************************************************************
863 ******************************************************************************/
866 static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
867 MIDI_EventPacket_t event;
874 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
876 //if the length is undefined we assume it is a SYSEX message
877 if (midi_packet_length(byte0) == UNDEFINED) {
880 if (byte2 == SYSEX_END)
881 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
883 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
886 if (byte1 == SYSEX_END)
887 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
889 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
892 if (byte0 == SYSEX_END)
893 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
895 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
898 return; //invalid cnt
901 //deal with 'system common' messages
902 //TODO are there any more?
903 switch(byte0 & 0xF0){
904 case MIDI_SONGPOSITION:
905 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
907 case MIDI_SONGSELECT:
908 case MIDI_TC_QUARTERFRAME:
909 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
912 event.Event = MIDI_EVENT(cable, byte0);
917 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
918 // Endpoint_ClearIN();
920 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
921 MIDI_Device_Flush(&USB_MIDI_Interface);
922 MIDI_Device_USBTask(&USB_MIDI_Interface);
926 static void usb_get_midi(MidiDevice * device) {
927 MIDI_EventPacket_t event;
928 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
930 midi_packet_length_t length = midi_packet_length(event.Data1);
932 input[0] = event.Data1;
933 input[1] = event.Data2;
934 input[2] = event.Data3;
935 if (length == UNDEFINED) {
937 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
939 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
941 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
948 //pass the data to the device input function
949 if (length != UNDEFINED)
950 midi_device_input(device, length, input);
952 MIDI_Device_USBTask(&USB_MIDI_Interface);
956 static void midi_usb_init(MidiDevice * device){
957 midi_device_init(device);
958 midi_device_set_send_func(device, usb_send_func);
959 midi_device_set_pre_input_process_func(device, usb_get_midi);
968 /* Device must be connected and configured for the task to run */
969 dprint("in MIDI_TASK\n");
970 if (USB_DeviceState != DEVICE_STATE_Configured)
972 dprint("continuing in MIDI_TASK\n");
974 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
976 if (Endpoint_IsINReady())
979 dprint("Endpoint is ready\n");
981 uint8_t MIDICommand = 0;
984 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
985 uint8_t Channel = MIDI_CHANNEL(1);
987 MIDICommand = MIDI_COMMAND_NOTE_ON;
990 /* Check if a MIDI command is to be sent */
993 dprint("Command exists\n");
994 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
996 .Event = MIDI_EVENT(0, MIDICommand),
998 .Data1 = MIDICommand | Channel,
1000 .Data3 = MIDI_STANDARD_VELOCITY,
1003 /* Write the MIDI event packet to the endpoint */
1004 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
1006 /* Send the data in the endpoint to the host */
1012 /* Select the MIDI OUT stream */
1013 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
1015 /* Check if a MIDI command has been received */
1016 if (Endpoint_IsOUTReceived())
1018 MIDI_EventPacket_t MIDIEvent;
1020 /* Read the MIDI event packet from the endpoint */
1021 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
1023 /* If the endpoint is now empty, clear the bank */
1024 if (!(Endpoint_BytesInEndpoint()))
1026 /* Clear the endpoint ready for new packet */
1027 Endpoint_ClearOUT();
1034 /*******************************************************************************
1036 ******************************************************************************/
1038 #ifdef VIRTSER_ENABLE
1039 void virtser_init(void)
1041 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
1042 CDC_Device_SendControlLineStateChange(&cdc_device);
1045 void virtser_recv(uint8_t c) __attribute__ ((weak));
1046 void virtser_recv(uint8_t c)
1048 // Ignore by default
1051 void virtser_task(void)
1053 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
1057 ch = CDC_Device_ReceiveByte(&cdc_device);
1061 void virtser_send(const uint8_t byte)
1063 uint8_t timeout = 255;
1064 uint8_t ep = Endpoint_GetCurrentEndpoint();
1066 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
1069 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
1071 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
1072 Endpoint_SelectEndpoint(ep);
1076 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
1078 Endpoint_Write_8(byte);
1079 CDC_Device_Flush(&cdc_device);
1081 if (Endpoint_IsINReady()) {
1085 Endpoint_SelectEndpoint(ep);
1090 /*******************************************************************************
1092 ******************************************************************************/
1093 static void setup_mcu(void)
1095 /* Disable watchdog if enabled by bootloader/fuses */
1096 MCUSR &= ~(1 << WDRF);
1099 /* Disable clock division */
1100 // clock_prescale_set(clock_div_1);
1102 CLKPR = (1 << CLKPCE);
1103 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
1106 static void setup_usb(void)
1108 // Leonardo needs. Without this USB device is not recognized.
1114 USB_Device_EnableSOFEvents();
1115 print_set_sendchar(sendchar);
1120 void fallthrough_callback(MidiDevice * device,
1121 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
1122 void cc_callback(MidiDevice * device,
1123 uint8_t chan, uint8_t num, uint8_t val);
1124 void sysex_callback(MidiDevice * device,
1125 uint16_t start, uint8_t length, uint8_t * data);
1128 int main(void) __attribute__ ((weak));
1133 midi_device_init(&midi_device);
1134 midi_device_set_send_func(&midi_device, usb_send_func);
1135 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
1144 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
1145 midi_register_cc_callback(&midi_device, cc_callback);
1146 midi_register_sysex_callback(&midi_device, sysex_callback);
1149 // midi_send_cc(&midi_device, 0, 1, 2);
1150 // midi_send_cc(&midi_device, 15, 1, 0);
1151 // midi_send_noteon(&midi_device, 0, 64, 127);
1152 // midi_send_noteoff(&midi_device, 0, 64, 127);
1155 #ifdef BLUETOOTH_ENABLE
1159 /* wait for USB startup & debug output */
1162 while (USB_DeviceState != DEVICE_STATE_Configured) {
1163 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1169 print("USB configured.\n");
1175 host_set_driver(&lufa_driver);
1176 #ifdef SLEEP_LED_ENABLE
1180 #ifdef VIRTSER_ENABLE
1184 print("Keyboard start.\n");
1186 #if !defined(BLUETOOTH_ENABLE) && !defined(ADAFRUIT_BLE_ENABLE)
1187 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1189 suspend_power_down();
1190 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1191 USB_Device_SendRemoteWakeup();
1199 midi_device_process(&midi_device);
1203 #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
1207 #ifdef ADAFRUIT_BLE_ENABLE
1208 adafruit_ble_task();
1211 #ifdef VIRTSER_ENABLE
1213 CDC_Device_USBTask(&cdc_device);
1220 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1228 void fallthrough_callback(MidiDevice * device,
1229 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
1233 switch (byte0 & 0xF0) {
1235 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1238 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1242 if (byte0 == MIDI_STOP) {
1249 void cc_callback(MidiDevice * device,
1250 uint8_t chan, uint8_t num, uint8_t val) {
1251 //sending it back on the next channel
1252 // midi_send_cc(device, (chan + 1) % 16, num, val);
1255 uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
1257 void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
1258 #ifdef API_SYSEX_ENABLE
1259 // SEND_STRING("\n");
1260 // send_word(start);
1261 // SEND_STRING(": ");
1262 for (uint8_t place = 0; place < length; place++) {
1263 // send_byte(*data);
1264 midi_buffer[start + place] = *data;
1265 if (*data == 0xF7) {
1266 // SEND_STRING("\nRD: ");
1267 // for (uint8_t i = 0; i < start + place + 1; i++){
1268 // send_byte(midi_buffer[i]);
1269 // SEND_STRING(" ");
1271 uint8_t * decoded = malloc(sizeof(uint8_t) * (sysex_decoded_length(start + place - 4)));
1272 uint16_t decode_length = sysex_decode(decoded, midi_buffer + 4, start + place - 4);
1273 process_api(decode_length, decoded);
1275 // SEND_STRING(" ");