2 * Copyright 2012 Jun Wako <wakojun@gmail.com>
3 * This file is based on:
4 * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
5 * LUFA-120219/Demos/Device/Lowlevel/GenericHID
10 Copyright (C) Dean Camera, 2012.
12 dean [at] fourwalledcubicle [dot] com
17 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
18 Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
20 Permission to use, copy, modify, distribute, and sell this
21 software and its documentation for any purpose is hereby granted
22 without fee, provided that the above copyright notice appear in
23 all copies and that both that the copyright notice and this
24 permission notice and warranty disclaimer appear in supporting
25 documentation, and that the name of the author not be used in
26 advertising or publicity pertaining to distribution of the
27 software without specific, written prior permission.
29 The author disclaim all warranties with regard to this
30 software, including all implied warranties of merchantability
31 and fitness. In no event shall the author be liable for any
32 special, indirect or consequential damages or any damages
33 whatsoever resulting from loss of use, data or profits, whether
34 in an action of contract, negligence or other tortious action,
35 arising out of or in connection with the use or performance of
41 #include "host_driver.h"
47 #ifdef SLEEP_LED_ENABLE
48 #include "sleep_led.h"
52 #include "descriptor.h"
59 #ifdef BLUETOOTH_ENABLE
60 #include "bluetooth.h"
63 uint8_t keyboard_idle = 0;
64 /* 0: Boot Protocol, 1: Report Protocol(default) */
65 uint8_t keyboard_protocol = 1;
66 static uint8_t keyboard_led_stats = 0;
68 static report_keyboard_t keyboard_report_sent;
71 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
72 void usb_get_midi(MidiDevice * device);
73 void midi_usb_init(MidiDevice * device);
77 static uint8_t keyboard_leds(void);
78 static void send_keyboard(report_keyboard_t *report);
79 static void send_mouse(report_mouse_t *report);
80 static void send_system(uint16_t data);
81 static void send_consumer(uint16_t data);
82 host_driver_t lufa_driver = {
95 /*******************************************************************************
97 ******************************************************************************/
100 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
104 .StreamingInterfaceNumber = AS_INTERFACE,
107 .Address = MIDI_STREAM_IN_EPADDR,
108 .Size = MIDI_STREAM_EPSIZE,
113 .Address = MIDI_STREAM_OUT_EPADDR,
114 .Size = MIDI_STREAM_EPSIZE,
120 #define SYSEX_START_OR_CONT 0x40
121 #define SYSEX_ENDS_IN_1 0x50
122 #define SYSEX_ENDS_IN_2 0x60
123 #define SYSEX_ENDS_IN_3 0x70
125 #define SYS_COMMON_1 0x50
126 #define SYS_COMMON_2 0x20
127 #define SYS_COMMON_3 0x30
131 /*******************************************************************************
133 ******************************************************************************/
134 #ifdef CONSOLE_ENABLE
135 static void Console_Task(void)
137 /* Device must be connected and configured for the task to run */
138 if (USB_DeviceState != DEVICE_STATE_Configured)
141 uint8_t ep = Endpoint_GetCurrentEndpoint();
144 // TODO: impl receivechar()/recvchar()
145 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
147 /* Check to see if a packet has been sent from the host */
148 if (Endpoint_IsOUTReceived())
150 /* Check to see if the packet contains data */
151 if (Endpoint_IsReadWriteAllowed())
153 /* Create a temporary buffer to hold the read in report from the host */
154 uint8_t ConsoleData[CONSOLE_EPSIZE];
156 /* Read Console Report Data */
157 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
159 /* Process Console Report Data */
160 //ProcessConsoleHIDReport(ConsoleData);
163 /* Finalize the stream transfer to send the last packet */
169 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
170 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
171 Endpoint_SelectEndpoint(ep);
176 while (Endpoint_IsReadWriteAllowed())
179 // flash senchar packet
180 if (Endpoint_IsINReady()) {
184 Endpoint_SelectEndpoint(ep);
187 static void Console_Task(void)
193 /*******************************************************************************
195 ******************************************************************************/
197 * Event Order of Plug in:
198 * 0) EVENT_USB_Device_Connect
199 * 1) EVENT_USB_Device_Suspend
200 * 2) EVENT_USB_Device_Reset
201 * 3) EVENT_USB_Device_Wake
203 void EVENT_USB_Device_Connect(void)
206 /* For battery powered device */
207 if (!USB_IsInitialized) {
210 USB_Device_EnableSOFEvents();
214 void EVENT_USB_Device_Disconnect(void)
217 /* For battery powered device */
218 USB_IsInitialized = false;
219 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
220 if (USB_IsInitialized) {
221 USB_Disable(); // Disable all interrupts
222 USB_Controller_Enable();
223 USB_INT_Enable(USB_INT_VBUSTI);
228 void EVENT_USB_Device_Reset(void)
233 void EVENT_USB_Device_Suspend()
236 #ifdef SLEEP_LED_ENABLE
241 void EVENT_USB_Device_WakeUp()
244 suspend_wakeup_init();
246 #ifdef SLEEP_LED_ENABLE
248 // NOTE: converters may not accept this
249 led_set(host_keyboard_leds());
253 #ifdef CONSOLE_ENABLE
254 static bool console_flush = false;
255 #define CONSOLE_FLUSH_SET(b) do { \
256 uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
260 void EVENT_USB_Device_StartOfFrame(void)
262 static uint8_t count;
263 if (++count % 50) return;
266 if (!console_flush) return;
268 console_flush = false;
272 /** Event handler for the USB_ConfigurationChanged event.
273 * This is fired when the host sets the current configuration of the USB device after enumeration.
275 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
276 * it is safe to use singl bank for all endpoints.
278 void EVENT_USB_Device_ConfigurationChanged(void)
280 bool ConfigSuccess = true;
282 /* Setup Keyboard HID Report Endpoints */
283 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
284 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
287 /* Setup Mouse HID Report Endpoint */
288 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
289 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
292 #ifdef EXTRAKEY_ENABLE
293 /* Setup Extra HID Report Endpoint */
294 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
295 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
298 #ifdef CONSOLE_ENABLE
299 /* Setup Console HID Report Endpoints */
300 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
301 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
303 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
304 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
309 /* Setup NKRO HID Report Endpoints */
310 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
311 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
315 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
316 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
321 Appendix G: HID Request Support Requirements
323 The following table enumerates the requests that need to be supported by various types of HID class devices.
325 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
326 ------------------------------------------------------------------------------------------
327 Boot Mouse Required Optional Optional Optional Required Required
328 Non-Boot Mouse Required Optional Optional Optional Optional Optional
329 Boot Keyboard Required Optional Required Required Required Required
330 Non-Boot Keybrd Required Optional Required Required Optional Optional
331 Other Device Required Optional Optional Optional Optional Optional
333 /** Event handler for the USB_ControlRequest event.
334 * This is fired before passing along unhandled control requests to the library for processing internally.
336 void EVENT_USB_Device_ControlRequest(void)
338 uint8_t* ReportData = NULL;
339 uint8_t ReportSize = 0;
341 /* Handle HID Class specific requests */
342 switch (USB_ControlRequest.bRequest)
344 case HID_REQ_GetReport:
345 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
347 Endpoint_ClearSETUP();
350 switch (USB_ControlRequest.wIndex) {
351 case KEYBOARD_INTERFACE:
353 ReportData = (uint8_t*)&keyboard_report_sent;
354 ReportSize = sizeof(keyboard_report_sent);
358 /* Write the report data to the control endpoint */
359 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
364 case HID_REQ_SetReport:
365 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
369 switch (USB_ControlRequest.wIndex) {
370 case KEYBOARD_INTERFACE:
374 Endpoint_ClearSETUP();
376 while (!(Endpoint_IsOUTReceived())) {
377 if (USB_DeviceState == DEVICE_STATE_Unattached)
380 keyboard_led_stats = Endpoint_Read_8();
383 Endpoint_ClearStatusStage();
391 case HID_REQ_GetProtocol:
392 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
394 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
395 Endpoint_ClearSETUP();
396 while (!(Endpoint_IsINReady()));
397 Endpoint_Write_8(keyboard_protocol);
399 Endpoint_ClearStatusStage();
404 case HID_REQ_SetProtocol:
405 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
407 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
408 Endpoint_ClearSETUP();
409 Endpoint_ClearStatusStage();
411 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
417 case HID_REQ_SetIdle:
418 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
420 Endpoint_ClearSETUP();
421 Endpoint_ClearStatusStage();
423 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
427 case HID_REQ_GetIdle:
428 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
430 Endpoint_ClearSETUP();
431 while (!(Endpoint_IsINReady()));
432 Endpoint_Write_8(keyboard_idle);
434 Endpoint_ClearStatusStage();
441 /*******************************************************************************
443 ******************************************************************************/
444 static uint8_t keyboard_leds(void)
446 return keyboard_led_stats;
449 static void send_keyboard(report_keyboard_t *report)
452 #ifdef BLUETOOTH_ENABLE
453 bluefruit_serial_send(0xFD);
454 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
455 bluefruit_serial_send(report->raw[i]);
459 uint8_t timeout = 255;
461 if (USB_DeviceState != DEVICE_STATE_Configured)
464 /* Select the Keyboard Report Endpoint */
466 if (keyboard_protocol && keyboard_nkro) {
467 /* Report protocol - NKRO */
468 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
470 /* Check if write ready for a polling interval around 1ms */
471 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
472 if (!Endpoint_IsReadWriteAllowed()) return;
474 /* Write Keyboard Report Data */
475 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
481 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
483 /* Check if write ready for a polling interval around 10ms */
484 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
485 if (!Endpoint_IsReadWriteAllowed()) return;
487 /* Write Keyboard Report Data */
488 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
491 /* Finalize the stream transfer to send the last packet */
494 keyboard_report_sent = *report;
497 static void send_mouse(report_mouse_t *report)
501 #ifdef BLUETOOTH_ENABLE
502 bluefruit_serial_send(0xFD);
503 bluefruit_serial_send(0x00);
504 bluefruit_serial_send(0x03);
505 bluefruit_serial_send(report->buttons);
506 bluefruit_serial_send(report->x);
507 bluefruit_serial_send(report->y);
508 bluefruit_serial_send(report->v); // should try sending the wheel v here
509 bluefruit_serial_send(report->h); // should try sending the wheel h here
510 bluefruit_serial_send(0x00);
513 uint8_t timeout = 255;
515 if (USB_DeviceState != DEVICE_STATE_Configured)
518 /* Select the Mouse Report Endpoint */
519 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
521 /* Check if write ready for a polling interval around 10ms */
522 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
523 if (!Endpoint_IsReadWriteAllowed()) return;
525 /* Write Mouse Report Data */
526 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
528 /* Finalize the stream transfer to send the last packet */
533 static void send_system(uint16_t data)
535 uint8_t timeout = 255;
537 if (USB_DeviceState != DEVICE_STATE_Configured)
541 .report_id = REPORT_ID_SYSTEM,
544 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
546 /* Check if write ready for a polling interval around 10ms */
547 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
548 if (!Endpoint_IsReadWriteAllowed()) return;
550 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
554 static void send_consumer(uint16_t data)
557 #ifdef BLUETOOTH_ENABLE
558 static uint16_t last_data = 0;
559 if (data == last_data) return;
561 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
562 bluefruit_serial_send(0xFD);
563 bluefruit_serial_send(0x00);
564 bluefruit_serial_send(0x02);
565 bluefruit_serial_send((bitmap>>8)&0xFF);
566 bluefruit_serial_send(bitmap&0xFF);
567 bluefruit_serial_send(0x00);
568 bluefruit_serial_send(0x00);
569 bluefruit_serial_send(0x00);
570 bluefruit_serial_send(0x00);
573 uint8_t timeout = 255;
575 if (USB_DeviceState != DEVICE_STATE_Configured)
579 .report_id = REPORT_ID_CONSUMER,
582 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
584 /* Check if write ready for a polling interval around 10ms */
585 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
586 if (!Endpoint_IsReadWriteAllowed()) return;
588 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
593 /*******************************************************************************
595 ******************************************************************************/
596 #ifdef CONSOLE_ENABLE
597 #define SEND_TIMEOUT 5
598 int8_t sendchar(uint8_t c)
600 // Not wait once timeouted.
601 // Because sendchar() is called so many times, waiting each call causes big lag.
602 static bool timeouted = false;
604 // prevents Console_Task() from running during sendchar() runs.
605 // or char will be lost. These two function is mutually exclusive.
606 CONSOLE_FLUSH_SET(false);
608 if (USB_DeviceState != DEVICE_STATE_Configured)
611 uint8_t ep = Endpoint_GetCurrentEndpoint();
612 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
613 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
617 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
623 uint8_t timeout = SEND_TIMEOUT;
624 while (!Endpoint_IsReadWriteAllowed()) {
625 if (USB_DeviceState != DEVICE_STATE_Configured) {
628 if (Endpoint_IsStalled()) {
640 // send when bank is full
641 if (!Endpoint_IsReadWriteAllowed()) {
642 while (!(Endpoint_IsINReady()));
645 CONSOLE_FLUSH_SET(true);
648 Endpoint_SelectEndpoint(ep);
651 Endpoint_SelectEndpoint(ep);
655 int8_t sendchar(uint8_t c)
661 /*******************************************************************************
663 ******************************************************************************/
666 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
667 MIDI_EventPacket_t event;
674 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
676 //if the length is undefined we assume it is a SYSEX message
677 if (midi_packet_length(byte0) == UNDEFINED) {
680 if (byte2 == SYSEX_END)
681 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
683 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
686 if (byte1 == SYSEX_END)
687 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
689 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
692 if (byte0 == SYSEX_END)
693 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
695 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
698 return; //invalid cnt
701 //deal with 'system common' messages
702 //TODO are there any more?
703 switch(byte0 & 0xF0){
704 case MIDI_SONGPOSITION:
705 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
707 case MIDI_SONGSELECT:
708 case MIDI_TC_QUARTERFRAME:
709 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
712 event.Event = MIDI_EVENT(cable, byte0);
717 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
718 // Endpoint_ClearIN();
720 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
721 MIDI_Device_Flush(&USB_MIDI_Interface);
722 MIDI_Device_USBTask(&USB_MIDI_Interface);
726 void usb_get_midi(MidiDevice * device) {
727 MIDI_EventPacket_t event;
728 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
730 midi_packet_length_t length = midi_packet_length(event.Data1);
732 input[0] = event.Data1;
733 input[1] = event.Data2;
734 input[2] = event.Data3;
735 if (length == UNDEFINED) {
737 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
739 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
741 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
748 //pass the data to the device input function
749 if (length != UNDEFINED)
750 midi_device_input(device, length, input);
752 MIDI_Device_USBTask(&USB_MIDI_Interface);
756 void midi_usb_init(MidiDevice * device){
757 midi_device_init(device);
758 midi_device_set_send_func(device, usb_send_func);
759 midi_device_set_pre_input_process_func(device, usb_get_midi);
768 /* Device must be connected and configured for the task to run */
769 dprint("in MIDI_TASK\n");
770 if (USB_DeviceState != DEVICE_STATE_Configured)
772 dprint("continuing in MIDI_TASK\n");
774 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
776 if (Endpoint_IsINReady())
779 dprint("Endpoint is ready\n");
781 uint8_t MIDICommand = 0;
784 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
785 uint8_t Channel = MIDI_CHANNEL(1);
787 MIDICommand = MIDI_COMMAND_NOTE_ON;
790 /* Check if a MIDI command is to be sent */
793 dprint("Command exists\n");
794 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
796 .Event = MIDI_EVENT(0, MIDICommand),
798 .Data1 = MIDICommand | Channel,
800 .Data3 = MIDI_STANDARD_VELOCITY,
803 /* Write the MIDI event packet to the endpoint */
804 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
806 /* Send the data in the endpoint to the host */
812 /* Select the MIDI OUT stream */
813 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
815 /* Check if a MIDI command has been received */
816 if (Endpoint_IsOUTReceived())
818 MIDI_EventPacket_t MIDIEvent;
820 /* Read the MIDI event packet from the endpoint */
821 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
823 /* If the endpoint is now empty, clear the bank */
824 if (!(Endpoint_BytesInEndpoint()))
826 /* Clear the endpoint ready for new packet */
835 /*******************************************************************************
837 ******************************************************************************/
838 static void setup_mcu(void)
840 /* Disable watchdog if enabled by bootloader/fuses */
841 MCUSR &= ~(1 << WDRF);
844 /* Disable clock division */
845 clock_prescale_set(clock_div_1);
848 static void setup_usb(void)
850 // Leonardo needs. Without this USB device is not recognized.
856 USB_Device_EnableSOFEvents();
857 print_set_sendchar(sendchar);
862 void fallthrough_callback(MidiDevice * device,
863 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
864 void cc_callback(MidiDevice * device,
865 uint8_t chan, uint8_t num, uint8_t val);
866 void sysex_callback(MidiDevice * device,
867 uint16_t start, uint8_t length, uint8_t * data);
870 int main(void) __attribute__ ((weak));
875 midi_device_init(&midi_device);
876 midi_device_set_send_func(&midi_device, usb_send_func);
877 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
886 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
887 midi_register_cc_callback(&midi_device, cc_callback);
888 midi_register_sysex_callback(&midi_device, sysex_callback);
891 // midi_send_cc(&midi_device, 0, 1, 2);
892 // midi_send_cc(&midi_device, 15, 1, 0);
893 // midi_send_noteon(&midi_device, 0, 64, 127);
894 // midi_send_noteoff(&midi_device, 0, 64, 127);
897 #ifdef BLUETOOTH_ENABLE
901 /* wait for USB startup & debug output */
904 while (USB_DeviceState != DEVICE_STATE_Configured) {
905 #if defined(INTERRUPT_CONTROL_ENDPOINT)
911 print("USB configured.\n");
917 host_set_driver(&lufa_driver);
918 #ifdef SLEEP_LED_ENABLE
922 print("Keyboard start.\n");
924 #ifndef BLUETOOTH_ENABLE
925 while (USB_DeviceState == DEVICE_STATE_Suspended) {
927 suspend_power_down();
928 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
929 USB_Device_SendRemoteWakeup();
935 midi_device_process(&midi_device);
940 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
947 void fallthrough_callback(MidiDevice * device,
948 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
952 switch (byte0 & 0xF0) {
954 play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
957 stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(byte1 & 0x7F)/12.0));
961 if (byte0 == MIDI_STOP) {
967 void cc_callback(MidiDevice * device,
968 uint8_t chan, uint8_t num, uint8_t val) {
969 //sending it back on the next channel
970 midi_send_cc(device, (chan + 1) % 16, num, val);
973 void sysex_callback(MidiDevice * device,
974 uint16_t start, uint8_t length, uint8_t * data) {
975 for (int i = 0; i < length; i++)
976 midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));