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>
56 #include "outputselect.h"
59 #include "keycode_config.h"
61 extern keymap_config_t keymap_config;
69 #ifdef BLUETOOTH_ENABLE
70 #ifdef MODULE_ADAFRUIT_BLE
71 #include "adafruit_ble.h"
73 #include "bluetooth.h"
81 #if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE)
86 #include "sysex_tools.h"
93 uint8_t keyboard_idle = 0;
94 /* 0: Boot Protocol, 1: Report Protocol(default) */
95 uint8_t keyboard_protocol = 1;
96 static uint8_t keyboard_led_stats = 0;
98 static report_keyboard_t keyboard_report_sent;
101 static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
102 static void usb_get_midi(MidiDevice * device);
103 static void midi_usb_init(MidiDevice * device);
107 static uint8_t keyboard_leds(void);
108 static void send_keyboard(report_keyboard_t *report);
109 static void send_mouse(report_mouse_t *report);
110 static void send_system(uint16_t data);
111 static void send_consumer(uint16_t data);
112 host_driver_t lufa_driver = {
125 /*******************************************************************************
127 ******************************************************************************/
130 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
134 .StreamingInterfaceNumber = AS_INTERFACE,
137 .Address = MIDI_STREAM_IN_EPADDR,
138 .Size = MIDI_STREAM_EPSIZE,
143 .Address = MIDI_STREAM_OUT_EPADDR,
144 .Size = MIDI_STREAM_EPSIZE,
150 #define SYSEX_START_OR_CONT 0x40
151 #define SYSEX_ENDS_IN_1 0x50
152 #define SYSEX_ENDS_IN_2 0x60
153 #define SYSEX_ENDS_IN_3 0x70
155 #define SYS_COMMON_1 0x50
156 #define SYS_COMMON_2 0x20
157 #define SYS_COMMON_3 0x30
160 #ifdef VIRTSER_ENABLE
161 USB_ClassInfo_CDC_Device_t cdc_device =
165 .ControlInterfaceNumber = CCI_INTERFACE,
168 .Address = CDC_IN_EPADDR,
174 .Address = CDC_OUT_EPADDR,
178 .NotificationEndpoint =
180 .Address = CDC_NOTIFICATION_EPADDR,
181 .Size = CDC_NOTIFICATION_EPSIZE,
190 void raw_hid_send( uint8_t *data, uint8_t length )
192 // TODO: implement variable size packet
193 if ( length != RAW_EPSIZE )
198 if (USB_DeviceState != DEVICE_STATE_Configured)
203 // TODO: decide if we allow calls to raw_hid_send() in the middle
204 // of other endpoint usage.
205 uint8_t ep = Endpoint_GetCurrentEndpoint();
207 Endpoint_SelectEndpoint(RAW_IN_EPNUM);
209 // Check to see if the host is ready to accept another packet
210 if (Endpoint_IsINReady())
213 Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL);
214 // Finalize the stream transfer to send the last packet
218 Endpoint_SelectEndpoint(ep);
221 __attribute__ ((weak))
222 void raw_hid_receive( uint8_t *data, uint8_t length )
224 // Users should #include "raw_hid.h" in their own code
225 // and implement this function there. Leave this as weak linkage
226 // so users can opt to not handle data coming in.
229 static void raw_hid_task(void)
231 // Create a temporary buffer to hold the read in data from the host
232 uint8_t data[RAW_EPSIZE];
233 bool data_read = false;
235 // Device must be connected and configured for the task to run
236 if (USB_DeviceState != DEVICE_STATE_Configured)
239 Endpoint_SelectEndpoint(RAW_OUT_EPNUM);
241 // Check to see if a packet has been sent from the host
242 if (Endpoint_IsOUTReceived())
244 // Check to see if the packet contains data
245 if (Endpoint_IsReadWriteAllowed())
248 Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
252 // Finalize the stream transfer to receive the last packet
257 raw_hid_receive( data, sizeof(data) );
263 /*******************************************************************************
265 ******************************************************************************/
266 #ifdef CONSOLE_ENABLE
267 static void Console_Task(void)
269 /* Device must be connected and configured for the task to run */
270 if (USB_DeviceState != DEVICE_STATE_Configured)
273 uint8_t ep = Endpoint_GetCurrentEndpoint();
276 // TODO: impl receivechar()/recvchar()
277 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
279 /* Check to see if a packet has been sent from the host */
280 if (Endpoint_IsOUTReceived())
282 /* Check to see if the packet contains data */
283 if (Endpoint_IsReadWriteAllowed())
285 /* Create a temporary buffer to hold the read in report from the host */
286 uint8_t ConsoleData[CONSOLE_EPSIZE];
288 /* Read Console Report Data */
289 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
291 /* Process Console Report Data */
292 //ProcessConsoleHIDReport(ConsoleData);
295 /* Finalize the stream transfer to send the last packet */
301 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
302 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
303 Endpoint_SelectEndpoint(ep);
308 while (Endpoint_IsReadWriteAllowed())
311 // flash senchar packet
312 if (Endpoint_IsINReady()) {
316 Endpoint_SelectEndpoint(ep);
321 /*******************************************************************************
323 ******************************************************************************/
325 * Event Order of Plug in:
326 * 0) EVENT_USB_Device_Connect
327 * 1) EVENT_USB_Device_Suspend
328 * 2) EVENT_USB_Device_Reset
329 * 3) EVENT_USB_Device_Wake
331 void EVENT_USB_Device_Connect(void)
334 /* For battery powered device */
335 if (!USB_IsInitialized) {
338 USB_Device_EnableSOFEvents();
342 void EVENT_USB_Device_Disconnect(void)
345 /* For battery powered device */
346 USB_IsInitialized = false;
347 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
348 if (USB_IsInitialized) {
349 USB_Disable(); // Disable all interrupts
350 USB_Controller_Enable();
351 USB_INT_Enable(USB_INT_VBUSTI);
356 void EVENT_USB_Device_Reset(void)
361 void EVENT_USB_Device_Suspend()
364 #ifdef SLEEP_LED_ENABLE
369 void EVENT_USB_Device_WakeUp()
372 suspend_wakeup_init();
374 #ifdef SLEEP_LED_ENABLE
376 // NOTE: converters may not accept this
377 led_set(host_keyboard_leds());
383 #ifdef CONSOLE_ENABLE
384 static bool console_flush = false;
385 #define CONSOLE_FLUSH_SET(b) do { \
386 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\
392 void EVENT_USB_Device_StartOfFrame(void)
394 static uint8_t count;
395 if (++count % 50) return;
398 if (!console_flush) return;
400 console_flush = false;
405 /** Event handler for the USB_ConfigurationChanged event.
406 * This is fired when the host sets the current configuration of the USB device after enumeration.
408 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
409 * it is safe to use singl bank for all endpoints.
411 void EVENT_USB_Device_ConfigurationChanged(void)
413 bool ConfigSuccess = true;
415 /* Setup Keyboard HID Report Endpoints */
416 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
417 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
420 /* Setup Mouse HID Report Endpoint */
421 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
422 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
425 #ifdef EXTRAKEY_ENABLE
426 /* Setup Extra HID Report Endpoint */
427 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
428 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
432 /* Setup Raw HID Report Endpoints */
433 ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
434 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
435 ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
436 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
439 #ifdef CONSOLE_ENABLE
440 /* Setup Console HID Report Endpoints */
441 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
442 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
444 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
445 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
450 /* Setup NKRO HID Report Endpoints */
451 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
452 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
456 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
457 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
460 #ifdef VIRTSER_ENABLE
461 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
462 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
463 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
468 Appendix G: HID Request Support Requirements
470 The following table enumerates the requests that need to be supported by various types of HID class devices.
472 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
473 ------------------------------------------------------------------------------------------
474 Boot Mouse Required Optional Optional Optional Required Required
475 Non-Boot Mouse Required Optional Optional Optional Optional Optional
476 Boot Keyboard Required Optional Required Required Required Required
477 Non-Boot Keybrd Required Optional Required Required Optional Optional
478 Other Device Required Optional Optional Optional Optional Optional
480 /** Event handler for the USB_ControlRequest event.
481 * This is fired before passing along unhandled control requests to the library for processing internally.
483 void EVENT_USB_Device_ControlRequest(void)
485 uint8_t* ReportData = NULL;
486 uint8_t ReportSize = 0;
488 /* Handle HID Class specific requests */
489 switch (USB_ControlRequest.bRequest)
491 case HID_REQ_GetReport:
492 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
494 Endpoint_ClearSETUP();
497 switch (USB_ControlRequest.wIndex) {
498 case KEYBOARD_INTERFACE:
500 ReportData = (uint8_t*)&keyboard_report_sent;
501 ReportSize = sizeof(keyboard_report_sent);
505 /* Write the report data to the control endpoint */
506 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
511 case HID_REQ_SetReport:
512 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
516 switch (USB_ControlRequest.wIndex) {
517 case KEYBOARD_INTERFACE:
521 Endpoint_ClearSETUP();
523 while (!(Endpoint_IsOUTReceived())) {
524 if (USB_DeviceState == DEVICE_STATE_Unattached)
527 keyboard_led_stats = Endpoint_Read_8();
530 Endpoint_ClearStatusStage();
538 case HID_REQ_GetProtocol:
539 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
541 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
542 Endpoint_ClearSETUP();
543 while (!(Endpoint_IsINReady()));
544 Endpoint_Write_8(keyboard_protocol);
546 Endpoint_ClearStatusStage();
551 case HID_REQ_SetProtocol:
552 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
554 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
555 Endpoint_ClearSETUP();
556 Endpoint_ClearStatusStage();
558 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
564 case HID_REQ_SetIdle:
565 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
567 Endpoint_ClearSETUP();
568 Endpoint_ClearStatusStage();
570 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
574 case HID_REQ_GetIdle:
575 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
577 Endpoint_ClearSETUP();
578 while (!(Endpoint_IsINReady()));
579 Endpoint_Write_8(keyboard_idle);
581 Endpoint_ClearStatusStage();
587 #ifdef VIRTSER_ENABLE
588 CDC_Device_ProcessControlRequest(&cdc_device);
592 /*******************************************************************************
594 ******************************************************************************/
595 static uint8_t keyboard_leds(void)
597 return keyboard_led_stats;
600 static void send_keyboard(report_keyboard_t *report)
602 uint8_t timeout = 255;
603 uint8_t where = where_to_send();
605 #ifdef BLUETOOTH_ENABLE
606 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
607 #ifdef MODULE_ADAFRUIT_BLE
608 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
610 bluefruit_serial_send(0xFD);
611 bluefruit_serial_send(0x09);
612 bluefruit_serial_send(0x01);
613 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
614 bluefruit_serial_send(report->raw[i]);
617 bluefruit_serial_send(0xFD);
618 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
619 bluefruit_serial_send(report->raw[i]);
625 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
629 /* Select the Keyboard Report Endpoint */
631 if (keyboard_protocol && keymap_config.nkro) {
632 /* Report protocol - NKRO */
633 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
635 /* Check if write ready for a polling interval around 1ms */
636 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
637 if (!Endpoint_IsReadWriteAllowed()) return;
639 /* Write Keyboard Report Data */
640 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
646 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
648 /* Check if write ready for a polling interval around 10ms */
649 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
650 if (!Endpoint_IsReadWriteAllowed()) return;
652 /* Write Keyboard Report Data */
653 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
656 /* Finalize the stream transfer to send the last packet */
659 keyboard_report_sent = *report;
662 static void send_mouse(report_mouse_t *report)
665 uint8_t timeout = 255;
666 uint8_t where = where_to_send();
668 #ifdef BLUETOOTH_ENABLE
669 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
670 #ifdef MODULE_ADAFRUIT_BLE
671 // FIXME: mouse buttons
672 adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
674 bluefruit_serial_send(0xFD);
675 bluefruit_serial_send(0x00);
676 bluefruit_serial_send(0x03);
677 bluefruit_serial_send(report->buttons);
678 bluefruit_serial_send(report->x);
679 bluefruit_serial_send(report->y);
680 bluefruit_serial_send(report->v); // should try sending the wheel v here
681 bluefruit_serial_send(report->h); // should try sending the wheel h here
682 bluefruit_serial_send(0x00);
687 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
691 /* Select the Mouse Report Endpoint */
692 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
694 /* Check if write ready for a polling interval around 10ms */
695 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
696 if (!Endpoint_IsReadWriteAllowed()) return;
698 /* Write Mouse Report Data */
699 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
701 /* Finalize the stream transfer to send the last packet */
706 static void send_system(uint16_t data)
708 uint8_t timeout = 255;
710 if (USB_DeviceState != DEVICE_STATE_Configured)
714 .report_id = REPORT_ID_SYSTEM,
715 .usage = data - SYSTEM_POWER_DOWN + 1
717 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
719 /* Check if write ready for a polling interval around 10ms */
720 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
721 if (!Endpoint_IsReadWriteAllowed()) return;
723 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
727 static void send_consumer(uint16_t data)
729 uint8_t timeout = 255;
730 uint8_t where = where_to_send();
732 #ifdef BLUETOOTH_ENABLE
733 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
734 #ifdef MODULE_ADAFRUIT_BLE
735 adafruit_ble_send_consumer_key(data, 0);
737 static uint16_t last_data = 0;
738 if (data == last_data) return;
740 uint16_t bitmap = CONSUMER2RN42(data);
741 bluefruit_serial_send(0xFD);
742 bluefruit_serial_send(0x03);
743 bluefruit_serial_send(0x03);
744 bluefruit_serial_send(bitmap&0xFF);
745 bluefruit_serial_send((bitmap>>8)&0xFF);
747 static uint16_t last_data = 0;
748 if (data == last_data) return;
750 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
751 bluefruit_serial_send(0xFD);
752 bluefruit_serial_send(0x00);
753 bluefruit_serial_send(0x02);
754 bluefruit_serial_send((bitmap>>8)&0xFF);
755 bluefruit_serial_send(bitmap&0xFF);
756 bluefruit_serial_send(0x00);
757 bluefruit_serial_send(0x00);
758 bluefruit_serial_send(0x00);
759 bluefruit_serial_send(0x00);
764 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
769 .report_id = REPORT_ID_CONSUMER,
772 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
774 /* Check if write ready for a polling interval around 10ms */
775 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
776 if (!Endpoint_IsReadWriteAllowed()) return;
778 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
783 /*******************************************************************************
785 ******************************************************************************/
786 #ifdef CONSOLE_ENABLE
787 #define SEND_TIMEOUT 5
788 int8_t sendchar(uint8_t c)
790 // Not wait once timeouted.
791 // Because sendchar() is called so many times, waiting each call causes big lag.
792 static bool timeouted = false;
794 // prevents Console_Task() from running during sendchar() runs.
795 // or char will be lost. These two function is mutually exclusive.
796 CONSOLE_FLUSH_SET(false);
798 if (USB_DeviceState != DEVICE_STATE_Configured)
801 uint8_t ep = Endpoint_GetCurrentEndpoint();
802 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
803 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
807 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
813 uint8_t timeout = SEND_TIMEOUT;
814 while (!Endpoint_IsReadWriteAllowed()) {
815 if (USB_DeviceState != DEVICE_STATE_Configured) {
818 if (Endpoint_IsStalled()) {
830 // send when bank is full
831 if (!Endpoint_IsReadWriteAllowed()) {
832 while (!(Endpoint_IsINReady()));
835 CONSOLE_FLUSH_SET(true);
838 Endpoint_SelectEndpoint(ep);
841 Endpoint_SelectEndpoint(ep);
845 int8_t sendchar(uint8_t c)
851 /*******************************************************************************
853 ******************************************************************************/
856 static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
857 MIDI_EventPacket_t event;
864 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
866 //if the length is undefined we assume it is a SYSEX message
867 if (midi_packet_length(byte0) == UNDEFINED) {
870 if (byte2 == SYSEX_END)
871 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
873 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
876 if (byte1 == SYSEX_END)
877 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
879 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
882 if (byte0 == SYSEX_END)
883 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
885 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
888 return; //invalid cnt
891 //deal with 'system common' messages
892 //TODO are there any more?
893 switch(byte0 & 0xF0){
894 case MIDI_SONGPOSITION:
895 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
897 case MIDI_SONGSELECT:
898 case MIDI_TC_QUARTERFRAME:
899 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
902 event.Event = MIDI_EVENT(cable, byte0);
907 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
908 // Endpoint_ClearIN();
910 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
911 MIDI_Device_Flush(&USB_MIDI_Interface);
912 MIDI_Device_USBTask(&USB_MIDI_Interface);
916 static void usb_get_midi(MidiDevice * device) {
917 MIDI_EventPacket_t event;
918 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
920 midi_packet_length_t length = midi_packet_length(event.Data1);
922 input[0] = event.Data1;
923 input[1] = event.Data2;
924 input[2] = event.Data3;
925 if (length == UNDEFINED) {
927 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
929 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
931 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
938 //pass the data to the device input function
939 if (length != UNDEFINED)
940 midi_device_input(device, length, input);
942 MIDI_Device_USBTask(&USB_MIDI_Interface);
946 static void midi_usb_init(MidiDevice * device){
947 midi_device_init(device);
948 midi_device_set_send_func(device, usb_send_func);
949 midi_device_set_pre_input_process_func(device, usb_get_midi);
958 /* Device must be connected and configured for the task to run */
959 dprint("in MIDI_TASK\n");
960 if (USB_DeviceState != DEVICE_STATE_Configured)
962 dprint("continuing in MIDI_TASK\n");
964 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
966 if (Endpoint_IsINReady())
969 dprint("Endpoint is ready\n");
971 uint8_t MIDICommand = 0;
974 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
975 uint8_t Channel = MIDI_CHANNEL(1);
977 MIDICommand = MIDI_COMMAND_NOTE_ON;
980 /* Check if a MIDI command is to be sent */
983 dprint("Command exists\n");
984 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
986 .Event = MIDI_EVENT(0, MIDICommand),
988 .Data1 = MIDICommand | Channel,
990 .Data3 = MIDI_STANDARD_VELOCITY,
993 /* Write the MIDI event packet to the endpoint */
994 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
996 /* Send the data in the endpoint to the host */
1002 /* Select the MIDI OUT stream */
1003 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
1005 /* Check if a MIDI command has been received */
1006 if (Endpoint_IsOUTReceived())
1008 MIDI_EventPacket_t MIDIEvent;
1010 /* Read the MIDI event packet from the endpoint */
1011 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
1013 /* If the endpoint is now empty, clear the bank */
1014 if (!(Endpoint_BytesInEndpoint()))
1016 /* Clear the endpoint ready for new packet */
1017 Endpoint_ClearOUT();
1024 /*******************************************************************************
1026 ******************************************************************************/
1028 #ifdef VIRTSER_ENABLE
1029 void virtser_init(void)
1031 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
1032 CDC_Device_SendControlLineStateChange(&cdc_device);
1035 void virtser_recv(uint8_t c) __attribute__ ((weak));
1036 void virtser_recv(uint8_t c)
1038 // Ignore by default
1041 void virtser_task(void)
1043 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
1047 ch = CDC_Device_ReceiveByte(&cdc_device);
1051 void virtser_send(const uint8_t byte)
1053 uint8_t timeout = 255;
1054 uint8_t ep = Endpoint_GetCurrentEndpoint();
1056 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
1059 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
1061 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
1062 Endpoint_SelectEndpoint(ep);
1066 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
1068 Endpoint_Write_8(byte);
1069 CDC_Device_Flush(&cdc_device);
1071 if (Endpoint_IsINReady()) {
1075 Endpoint_SelectEndpoint(ep);
1080 /*******************************************************************************
1082 ******************************************************************************/
1083 static void setup_mcu(void)
1085 /* Disable watchdog if enabled by bootloader/fuses */
1086 MCUSR &= ~(1 << WDRF);
1089 /* Disable clock division */
1090 // clock_prescale_set(clock_div_1);
1092 CLKPR = (1 << CLKPCE);
1093 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
1096 static void setup_usb(void)
1098 // Leonardo needs. Without this USB device is not recognized.
1104 USB_Device_EnableSOFEvents();
1105 print_set_sendchar(sendchar);
1110 void fallthrough_callback(MidiDevice * device,
1111 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
1112 void cc_callback(MidiDevice * device,
1113 uint8_t chan, uint8_t num, uint8_t val);
1114 void sysex_callback(MidiDevice * device,
1115 uint16_t start, uint8_t length, uint8_t * data);
1117 void setup_midi(void)
1119 #ifdef MIDI_ADVANCED
1122 midi_device_init(&midi_device);
1123 midi_device_set_send_func(&midi_device, usb_send_func);
1124 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
1128 int main(void) __attribute__ ((weak));
1141 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
1142 midi_register_cc_callback(&midi_device, cc_callback);
1143 midi_register_sysex_callback(&midi_device, sysex_callback);
1146 // midi_send_cc(&midi_device, 0, 1, 2);
1147 // midi_send_cc(&midi_device, 15, 1, 0);
1148 // midi_send_noteon(&midi_device, 0, 64, 127);
1149 // midi_send_noteoff(&midi_device, 0, 64, 127);
1152 #if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
1156 /* wait for USB startup & debug output */
1159 while (USB_DeviceState != DEVICE_STATE_Configured) {
1160 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1166 print("USB configured.\n");
1172 host_set_driver(&lufa_driver);
1173 #ifdef SLEEP_LED_ENABLE
1177 #ifdef VIRTSER_ENABLE
1181 print("Keyboard start.\n");
1183 #if !defined(NO_USB_STARTUP_CHECK)
1184 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1186 suspend_power_down();
1187 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1188 USB_Device_SendRemoteWakeup();
1196 midi_device_process(&midi_device);
1197 #ifdef MIDI_ADVANCED
1202 #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
1206 #ifdef MODULE_ADAFRUIT_BLE
1207 adafruit_ble_task();
1210 #ifdef VIRTSER_ENABLE
1212 CDC_Device_USBTask(&cdc_device);
1219 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1227 void fallthrough_callback(MidiDevice * device,
1228 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
1232 switch (byte0 & 0xF0) {
1234 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1237 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1241 if (byte0 == MIDI_STOP) {
1248 void cc_callback(MidiDevice * device,
1249 uint8_t chan, uint8_t num, uint8_t val) {
1250 //sending it back on the next channel
1251 // midi_send_cc(device, (chan + 1) % 16, num, val);
1254 #ifdef API_SYSEX_ENABLE
1255 uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
1258 void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
1259 #ifdef API_SYSEX_ENABLE
1260 // SEND_STRING("\n");
1261 // send_word(start);
1262 // SEND_STRING(": ");
1263 // Don't store the header
1264 int16_t pos = start - 4;
1265 for (uint8_t place = 0; place < length; place++) {
1266 // send_byte(*data);
1268 if (*data == 0xF7) {
1269 // SEND_STRING("\nRD: ");
1270 // for (uint8_t i = 0; i < start + place + 1; i++){
1271 // send_byte(midi_buffer[i]);
1272 // SEND_STRING(" ");
1274 const unsigned decoded_length = sysex_decoded_length(pos);
1275 uint8_t decoded[API_SYSEX_MAX_SIZE];
1276 sysex_decode(decoded, midi_buffer, pos);
1277 process_api(decoded_length, decoded);
1280 else if (pos >= MIDI_SYSEX_BUFFER) {
1283 midi_buffer[pos] = *data;
1285 // SEND_STRING(" ");