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 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
612 bluefruit_serial_send(report->raw[i]);
618 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
622 /* Select the Keyboard Report Endpoint */
624 if (keyboard_protocol && keymap_config.nkro) {
625 /* Report protocol - NKRO */
626 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
628 /* Check if write ready for a polling interval around 1ms */
629 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
630 if (!Endpoint_IsReadWriteAllowed()) return;
632 /* Write Keyboard Report Data */
633 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
639 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
641 /* Check if write ready for a polling interval around 10ms */
642 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
643 if (!Endpoint_IsReadWriteAllowed()) return;
645 /* Write Keyboard Report Data */
646 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
649 /* Finalize the stream transfer to send the last packet */
652 keyboard_report_sent = *report;
655 static void send_mouse(report_mouse_t *report)
658 uint8_t timeout = 255;
659 uint8_t where = where_to_send();
661 #ifdef BLUETOOTH_ENABLE
662 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
663 #ifdef MODULE_ADAFRUIT_BLE
664 // FIXME: mouse buttons
665 adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h);
667 bluefruit_serial_send(0xFD);
668 bluefruit_serial_send(0x00);
669 bluefruit_serial_send(0x03);
670 bluefruit_serial_send(report->buttons);
671 bluefruit_serial_send(report->x);
672 bluefruit_serial_send(report->y);
673 bluefruit_serial_send(report->v); // should try sending the wheel v here
674 bluefruit_serial_send(report->h); // should try sending the wheel h here
675 bluefruit_serial_send(0x00);
680 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
684 /* Select the Mouse Report Endpoint */
685 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
687 /* Check if write ready for a polling interval around 10ms */
688 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
689 if (!Endpoint_IsReadWriteAllowed()) return;
691 /* Write Mouse Report Data */
692 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
694 /* Finalize the stream transfer to send the last packet */
699 static void send_system(uint16_t data)
701 uint8_t timeout = 255;
703 if (USB_DeviceState != DEVICE_STATE_Configured)
707 .report_id = REPORT_ID_SYSTEM,
708 .usage = data - SYSTEM_POWER_DOWN + 1
710 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
712 /* Check if write ready for a polling interval around 10ms */
713 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
714 if (!Endpoint_IsReadWriteAllowed()) return;
716 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
720 static void send_consumer(uint16_t data)
722 uint8_t timeout = 255;
723 uint8_t where = where_to_send();
725 #ifdef BLUETOOTH_ENABLE
726 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
727 #ifdef MODULE_ADAFRUIT_BLE
728 adafruit_ble_send_consumer_key(data, 0);
730 static uint16_t last_data = 0;
731 if (data == last_data) return;
733 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
734 bluefruit_serial_send(0xFD);
735 bluefruit_serial_send(0x00);
736 bluefruit_serial_send(0x02);
737 bluefruit_serial_send((bitmap>>8)&0xFF);
738 bluefruit_serial_send(bitmap&0xFF);
739 bluefruit_serial_send(0x00);
740 bluefruit_serial_send(0x00);
741 bluefruit_serial_send(0x00);
742 bluefruit_serial_send(0x00);
747 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
752 .report_id = REPORT_ID_CONSUMER,
755 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
757 /* Check if write ready for a polling interval around 10ms */
758 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
759 if (!Endpoint_IsReadWriteAllowed()) return;
761 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
766 /*******************************************************************************
768 ******************************************************************************/
769 #ifdef CONSOLE_ENABLE
770 #define SEND_TIMEOUT 5
771 int8_t sendchar(uint8_t c)
773 // Not wait once timeouted.
774 // Because sendchar() is called so many times, waiting each call causes big lag.
775 static bool timeouted = false;
777 // prevents Console_Task() from running during sendchar() runs.
778 // or char will be lost. These two function is mutually exclusive.
779 CONSOLE_FLUSH_SET(false);
781 if (USB_DeviceState != DEVICE_STATE_Configured)
784 uint8_t ep = Endpoint_GetCurrentEndpoint();
785 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
786 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
790 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
796 uint8_t timeout = SEND_TIMEOUT;
797 while (!Endpoint_IsReadWriteAllowed()) {
798 if (USB_DeviceState != DEVICE_STATE_Configured) {
801 if (Endpoint_IsStalled()) {
813 // send when bank is full
814 if (!Endpoint_IsReadWriteAllowed()) {
815 while (!(Endpoint_IsINReady()));
818 CONSOLE_FLUSH_SET(true);
821 Endpoint_SelectEndpoint(ep);
824 Endpoint_SelectEndpoint(ep);
828 int8_t sendchar(uint8_t c)
834 /*******************************************************************************
836 ******************************************************************************/
839 static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
840 MIDI_EventPacket_t event;
847 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
849 //if the length is undefined we assume it is a SYSEX message
850 if (midi_packet_length(byte0) == UNDEFINED) {
853 if (byte2 == SYSEX_END)
854 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
856 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
859 if (byte1 == SYSEX_END)
860 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
862 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
865 if (byte0 == SYSEX_END)
866 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
868 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
871 return; //invalid cnt
874 //deal with 'system common' messages
875 //TODO are there any more?
876 switch(byte0 & 0xF0){
877 case MIDI_SONGPOSITION:
878 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
880 case MIDI_SONGSELECT:
881 case MIDI_TC_QUARTERFRAME:
882 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
885 event.Event = MIDI_EVENT(cable, byte0);
890 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
891 // Endpoint_ClearIN();
893 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
894 MIDI_Device_Flush(&USB_MIDI_Interface);
895 MIDI_Device_USBTask(&USB_MIDI_Interface);
899 static void usb_get_midi(MidiDevice * device) {
900 MIDI_EventPacket_t event;
901 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
903 midi_packet_length_t length = midi_packet_length(event.Data1);
905 input[0] = event.Data1;
906 input[1] = event.Data2;
907 input[2] = event.Data3;
908 if (length == UNDEFINED) {
910 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
912 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
914 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
921 //pass the data to the device input function
922 if (length != UNDEFINED)
923 midi_device_input(device, length, input);
925 MIDI_Device_USBTask(&USB_MIDI_Interface);
929 static void midi_usb_init(MidiDevice * device){
930 midi_device_init(device);
931 midi_device_set_send_func(device, usb_send_func);
932 midi_device_set_pre_input_process_func(device, usb_get_midi);
941 /* Device must be connected and configured for the task to run */
942 dprint("in MIDI_TASK\n");
943 if (USB_DeviceState != DEVICE_STATE_Configured)
945 dprint("continuing in MIDI_TASK\n");
947 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
949 if (Endpoint_IsINReady())
952 dprint("Endpoint is ready\n");
954 uint8_t MIDICommand = 0;
957 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
958 uint8_t Channel = MIDI_CHANNEL(1);
960 MIDICommand = MIDI_COMMAND_NOTE_ON;
963 /* Check if a MIDI command is to be sent */
966 dprint("Command exists\n");
967 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
969 .Event = MIDI_EVENT(0, MIDICommand),
971 .Data1 = MIDICommand | Channel,
973 .Data3 = MIDI_STANDARD_VELOCITY,
976 /* Write the MIDI event packet to the endpoint */
977 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
979 /* Send the data in the endpoint to the host */
985 /* Select the MIDI OUT stream */
986 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
988 /* Check if a MIDI command has been received */
989 if (Endpoint_IsOUTReceived())
991 MIDI_EventPacket_t MIDIEvent;
993 /* Read the MIDI event packet from the endpoint */
994 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
996 /* If the endpoint is now empty, clear the bank */
997 if (!(Endpoint_BytesInEndpoint()))
999 /* Clear the endpoint ready for new packet */
1000 Endpoint_ClearOUT();
1007 /*******************************************************************************
1009 ******************************************************************************/
1011 #ifdef VIRTSER_ENABLE
1012 void virtser_init(void)
1014 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
1015 CDC_Device_SendControlLineStateChange(&cdc_device);
1018 void virtser_recv(uint8_t c) __attribute__ ((weak));
1019 void virtser_recv(uint8_t c)
1021 // Ignore by default
1024 void virtser_task(void)
1026 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
1030 ch = CDC_Device_ReceiveByte(&cdc_device);
1034 void virtser_send(const uint8_t byte)
1036 uint8_t timeout = 255;
1037 uint8_t ep = Endpoint_GetCurrentEndpoint();
1039 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
1042 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
1044 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
1045 Endpoint_SelectEndpoint(ep);
1049 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
1051 Endpoint_Write_8(byte);
1052 CDC_Device_Flush(&cdc_device);
1054 if (Endpoint_IsINReady()) {
1058 Endpoint_SelectEndpoint(ep);
1063 /*******************************************************************************
1065 ******************************************************************************/
1066 static void setup_mcu(void)
1068 /* Disable watchdog if enabled by bootloader/fuses */
1069 MCUSR &= ~(1 << WDRF);
1072 /* Disable clock division */
1073 // clock_prescale_set(clock_div_1);
1075 CLKPR = (1 << CLKPCE);
1076 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
1079 static void setup_usb(void)
1081 // Leonardo needs. Without this USB device is not recognized.
1087 USB_Device_EnableSOFEvents();
1088 print_set_sendchar(sendchar);
1093 void fallthrough_callback(MidiDevice * device,
1094 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
1095 void cc_callback(MidiDevice * device,
1096 uint8_t chan, uint8_t num, uint8_t val);
1097 void sysex_callback(MidiDevice * device,
1098 uint16_t start, uint8_t length, uint8_t * data);
1101 int main(void) __attribute__ ((weak));
1106 midi_device_init(&midi_device);
1107 midi_device_set_send_func(&midi_device, usb_send_func);
1108 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
1117 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
1118 midi_register_cc_callback(&midi_device, cc_callback);
1119 midi_register_sysex_callback(&midi_device, sysex_callback);
1122 // midi_send_cc(&midi_device, 0, 1, 2);
1123 // midi_send_cc(&midi_device, 15, 1, 0);
1124 // midi_send_noteon(&midi_device, 0, 64, 127);
1125 // midi_send_noteoff(&midi_device, 0, 64, 127);
1128 #ifdef MODULE_ADAFRUIT_EZKEY
1132 /* wait for USB startup & debug output */
1135 while (USB_DeviceState != DEVICE_STATE_Configured) {
1136 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1142 print("USB configured.\n");
1148 host_set_driver(&lufa_driver);
1149 #ifdef SLEEP_LED_ENABLE
1153 #ifdef VIRTSER_ENABLE
1157 print("Keyboard start.\n");
1159 #if !defined(BLUETOOTH_ENABLE)
1160 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1162 suspend_power_down();
1163 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1164 USB_Device_SendRemoteWakeup();
1172 midi_device_process(&midi_device);
1176 #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
1180 #ifdef MODULE_ADAFRUIT_BLE
1181 adafruit_ble_task();
1184 #ifdef VIRTSER_ENABLE
1186 CDC_Device_USBTask(&cdc_device);
1193 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1201 void fallthrough_callback(MidiDevice * device,
1202 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
1206 switch (byte0 & 0xF0) {
1208 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1211 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1215 if (byte0 == MIDI_STOP) {
1222 void cc_callback(MidiDevice * device,
1223 uint8_t chan, uint8_t num, uint8_t val) {
1224 //sending it back on the next channel
1225 // midi_send_cc(device, (chan + 1) % 16, num, val);
1228 #ifdef API_SYSEX_ENABLE
1229 uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
1232 void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
1233 #ifdef API_SYSEX_ENABLE
1234 // SEND_STRING("\n");
1235 // send_word(start);
1236 // SEND_STRING(": ");
1237 // Don't store the header
1238 int16_t pos = start - 4;
1239 for (uint8_t place = 0; place < length; place++) {
1240 // send_byte(*data);
1242 if (*data == 0xF7) {
1243 // SEND_STRING("\nRD: ");
1244 // for (uint8_t i = 0; i < start + place + 1; i++){
1245 // send_byte(midi_buffer[i]);
1246 // SEND_STRING(" ");
1248 const unsigned decoded_length = sysex_decoded_length(pos);
1249 uint8_t decoded[API_SYSEX_MAX_SIZE];
1250 sysex_decode(decoded, midi_buffer, pos);
1251 process_api(decoded_length, decoded);
1254 else if (pos >= MIDI_SYSEX_BUFFER) {
1257 midi_buffer[pos] = *data;
1259 // SEND_STRING(" ");