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);
189 /*******************************************************************************
191 ******************************************************************************/
193 * Event Order of Plug in:
194 * 0) EVENT_USB_Device_Connect
195 * 1) EVENT_USB_Device_Suspend
196 * 2) EVENT_USB_Device_Reset
197 * 3) EVENT_USB_Device_Wake
199 void EVENT_USB_Device_Connect(void)
202 /* For battery powered device */
203 if (!USB_IsInitialized) {
206 USB_Device_EnableSOFEvents();
210 void EVENT_USB_Device_Disconnect(void)
213 /* For battery powered device */
214 USB_IsInitialized = false;
215 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
216 if (USB_IsInitialized) {
217 USB_Disable(); // Disable all interrupts
218 USB_Controller_Enable();
219 USB_INT_Enable(USB_INT_VBUSTI);
224 void EVENT_USB_Device_Reset(void)
229 void EVENT_USB_Device_Suspend()
232 #ifdef SLEEP_LED_ENABLE
237 void EVENT_USB_Device_WakeUp()
240 suspend_wakeup_init();
242 #ifdef SLEEP_LED_ENABLE
244 // NOTE: converters may not accept this
245 led_set(host_keyboard_leds());
249 #ifdef CONSOLE_ENABLE
250 static bool console_flush = false;
251 #define CONSOLE_FLUSH_SET(b) do { \
252 uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
256 void EVENT_USB_Device_StartOfFrame(void)
258 static uint8_t count;
259 if (++count % 50) return;
262 if (!console_flush) return;
264 console_flush = false;
268 /** Event handler for the USB_ConfigurationChanged event.
269 * This is fired when the host sets the current configuration of the USB device after enumeration.
271 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
272 * it is safe to use singl bank for all endpoints.
274 void EVENT_USB_Device_ConfigurationChanged(void)
276 bool ConfigSuccess = true;
278 /* Setup Keyboard HID Report Endpoints */
279 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
280 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
283 /* Setup Mouse HID Report Endpoint */
284 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
285 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
288 #ifdef EXTRAKEY_ENABLE
289 /* Setup Extra HID Report Endpoint */
290 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
291 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
294 #ifdef CONSOLE_ENABLE
295 /* Setup Console HID Report Endpoints */
296 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
297 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
299 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
300 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
305 /* Setup NKRO HID Report Endpoints */
306 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
307 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
311 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
312 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
317 Appendix G: HID Request Support Requirements
319 The following table enumerates the requests that need to be supported by various types of HID class devices.
321 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
322 ------------------------------------------------------------------------------------------
323 Boot Mouse Required Optional Optional Optional Required Required
324 Non-Boot Mouse Required Optional Optional Optional Optional Optional
325 Boot Keyboard Required Optional Required Required Required Required
326 Non-Boot Keybrd Required Optional Required Required Optional Optional
327 Other Device Required Optional Optional Optional Optional Optional
329 /** Event handler for the USB_ControlRequest event.
330 * This is fired before passing along unhandled control requests to the library for processing internally.
332 void EVENT_USB_Device_ControlRequest(void)
334 uint8_t* ReportData = NULL;
335 uint8_t ReportSize = 0;
337 /* Handle HID Class specific requests */
338 switch (USB_ControlRequest.bRequest)
340 case HID_REQ_GetReport:
341 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
343 Endpoint_ClearSETUP();
346 switch (USB_ControlRequest.wIndex) {
347 case KEYBOARD_INTERFACE:
349 ReportData = (uint8_t*)&keyboard_report_sent;
350 ReportSize = sizeof(keyboard_report_sent);
354 /* Write the report data to the control endpoint */
355 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
360 case HID_REQ_SetReport:
361 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
365 switch (USB_ControlRequest.wIndex) {
366 case KEYBOARD_INTERFACE:
370 Endpoint_ClearSETUP();
372 while (!(Endpoint_IsOUTReceived())) {
373 if (USB_DeviceState == DEVICE_STATE_Unattached)
376 keyboard_led_stats = Endpoint_Read_8();
379 Endpoint_ClearStatusStage();
387 case HID_REQ_GetProtocol:
388 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
390 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
391 Endpoint_ClearSETUP();
392 while (!(Endpoint_IsINReady()));
393 Endpoint_Write_8(keyboard_protocol);
395 Endpoint_ClearStatusStage();
400 case HID_REQ_SetProtocol:
401 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
403 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
404 Endpoint_ClearSETUP();
405 Endpoint_ClearStatusStage();
407 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
413 case HID_REQ_SetIdle:
414 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
416 Endpoint_ClearSETUP();
417 Endpoint_ClearStatusStage();
419 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
423 case HID_REQ_GetIdle:
424 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
426 Endpoint_ClearSETUP();
427 while (!(Endpoint_IsINReady()));
428 Endpoint_Write_8(keyboard_idle);
430 Endpoint_ClearStatusStage();
437 /*******************************************************************************
439 ******************************************************************************/
440 static uint8_t keyboard_leds(void)
442 return keyboard_led_stats;
445 static void send_keyboard(report_keyboard_t *report)
448 #ifdef BLUETOOTH_ENABLE
449 bluefruit_serial_send(0xFD);
450 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
451 bluefruit_serial_send(report->raw[i]);
455 uint8_t timeout = 255;
457 if (USB_DeviceState != DEVICE_STATE_Configured)
460 /* Select the Keyboard Report Endpoint */
462 if (keyboard_protocol && keyboard_nkro) {
463 /* Report protocol - NKRO */
464 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
466 /* Check if write ready for a polling interval around 1ms */
467 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
468 if (!Endpoint_IsReadWriteAllowed()) return;
470 /* Write Keyboard Report Data */
471 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
477 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
479 /* Check if write ready for a polling interval around 10ms */
480 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
481 if (!Endpoint_IsReadWriteAllowed()) return;
483 /* Write Keyboard Report Data */
484 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
487 /* Finalize the stream transfer to send the last packet */
490 keyboard_report_sent = *report;
493 static void send_mouse(report_mouse_t *report)
497 #ifdef BLUETOOTH_ENABLE
498 bluefruit_serial_send(0xFD);
499 bluefruit_serial_send(0x00);
500 bluefruit_serial_send(0x03);
501 bluefruit_serial_send(report->buttons);
502 bluefruit_serial_send(report->x);
503 bluefruit_serial_send(report->y);
504 bluefruit_serial_send(report->v); // should try sending the wheel v here
505 bluefruit_serial_send(report->h); // should try sending the wheel h here
506 bluefruit_serial_send(0x00);
509 uint8_t timeout = 255;
511 if (USB_DeviceState != DEVICE_STATE_Configured)
514 /* Select the Mouse Report Endpoint */
515 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
517 /* Check if write ready for a polling interval around 10ms */
518 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
519 if (!Endpoint_IsReadWriteAllowed()) return;
521 /* Write Mouse Report Data */
522 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
524 /* Finalize the stream transfer to send the last packet */
529 static void send_system(uint16_t data)
531 uint8_t timeout = 255;
533 if (USB_DeviceState != DEVICE_STATE_Configured)
537 .report_id = REPORT_ID_SYSTEM,
540 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
542 /* Check if write ready for a polling interval around 10ms */
543 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
544 if (!Endpoint_IsReadWriteAllowed()) return;
546 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
550 static void send_consumer(uint16_t data)
553 #ifdef BLUETOOTH_ENABLE
554 static uint16_t last_data = 0;
555 if (data == last_data) return;
557 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
558 bluefruit_serial_send(0xFD);
559 bluefruit_serial_send(0x00);
560 bluefruit_serial_send(0x02);
561 bluefruit_serial_send((bitmap>>8)&0xFF);
562 bluefruit_serial_send(bitmap&0xFF);
563 bluefruit_serial_send(0x00);
564 bluefruit_serial_send(0x00);
565 bluefruit_serial_send(0x00);
566 bluefruit_serial_send(0x00);
569 uint8_t timeout = 255;
571 if (USB_DeviceState != DEVICE_STATE_Configured)
575 .report_id = REPORT_ID_CONSUMER,
578 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
580 /* Check if write ready for a polling interval around 10ms */
581 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
582 if (!Endpoint_IsReadWriteAllowed()) return;
584 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
589 /*******************************************************************************
591 ******************************************************************************/
592 #ifdef CONSOLE_ENABLE
593 #define SEND_TIMEOUT 5
594 int8_t sendchar(uint8_t c)
596 // Not wait once timeouted.
597 // Because sendchar() is called so many times, waiting each call causes big lag.
598 static bool timeouted = false;
600 // prevents Console_Task() from running during sendchar() runs.
601 // or char will be lost. These two function is mutually exclusive.
602 CONSOLE_FLUSH_SET(false);
604 if (USB_DeviceState != DEVICE_STATE_Configured)
607 uint8_t ep = Endpoint_GetCurrentEndpoint();
608 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
609 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
613 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
619 uint8_t timeout = SEND_TIMEOUT;
620 while (!Endpoint_IsReadWriteAllowed()) {
621 if (USB_DeviceState != DEVICE_STATE_Configured) {
624 if (Endpoint_IsStalled()) {
636 // send when bank is full
637 if (!Endpoint_IsReadWriteAllowed()) {
638 while (!(Endpoint_IsINReady()));
641 CONSOLE_FLUSH_SET(true);
644 Endpoint_SelectEndpoint(ep);
647 Endpoint_SelectEndpoint(ep);
651 int8_t sendchar(uint8_t c)
657 /*******************************************************************************
659 ******************************************************************************/
662 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
663 MIDI_EventPacket_t event;
670 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
672 //if the length is undefined we assume it is a SYSEX message
673 if (midi_packet_length(byte0) == UNDEFINED) {
676 if (byte2 == SYSEX_END)
677 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
679 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
682 if (byte1 == SYSEX_END)
683 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
685 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
688 if (byte0 == SYSEX_END)
689 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
691 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
694 return; //invalid cnt
697 //deal with 'system common' messages
698 //TODO are there any more?
699 switch(byte0 & 0xF0){
700 case MIDI_SONGPOSITION:
701 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
703 case MIDI_SONGSELECT:
704 case MIDI_TC_QUARTERFRAME:
705 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
708 event.Event = MIDI_EVENT(cable, byte0);
713 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
714 // Endpoint_ClearIN();
716 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
717 MIDI_Device_Flush(&USB_MIDI_Interface);
718 MIDI_Device_USBTask(&USB_MIDI_Interface);
722 void usb_get_midi(MidiDevice * device) {
723 MIDI_EventPacket_t event;
724 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
726 midi_packet_length_t length = midi_packet_length(event.Data1);
728 input[0] = event.Data1;
729 input[1] = event.Data2;
730 input[2] = event.Data3;
731 if (length == UNDEFINED) {
733 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
735 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
737 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
744 //pass the data to the device input function
745 if (length != UNDEFINED)
746 midi_device_input(device, length, input);
748 MIDI_Device_USBTask(&USB_MIDI_Interface);
752 void midi_usb_init(MidiDevice * device){
753 midi_device_init(device);
754 midi_device_set_send_func(device, usb_send_func);
755 midi_device_set_pre_input_process_func(device, usb_get_midi);
764 /* Device must be connected and configured for the task to run */
765 dprint("in MIDI_TASK\n");
766 if (USB_DeviceState != DEVICE_STATE_Configured)
768 dprint("continuing in MIDI_TASK\n");
770 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
772 if (Endpoint_IsINReady())
775 dprint("Endpoint is ready\n");
777 uint8_t MIDICommand = 0;
780 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
781 uint8_t Channel = MIDI_CHANNEL(1);
783 MIDICommand = MIDI_COMMAND_NOTE_ON;
786 /* Check if a MIDI command is to be sent */
789 dprint("Command exists\n");
790 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
792 .Event = MIDI_EVENT(0, MIDICommand),
794 .Data1 = MIDICommand | Channel,
796 .Data3 = MIDI_STANDARD_VELOCITY,
799 /* Write the MIDI event packet to the endpoint */
800 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
802 /* Send the data in the endpoint to the host */
808 /* Select the MIDI OUT stream */
809 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
811 /* Check if a MIDI command has been received */
812 if (Endpoint_IsOUTReceived())
814 MIDI_EventPacket_t MIDIEvent;
816 /* Read the MIDI event packet from the endpoint */
817 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
819 /* If the endpoint is now empty, clear the bank */
820 if (!(Endpoint_BytesInEndpoint()))
822 /* Clear the endpoint ready for new packet */
831 /*******************************************************************************
833 ******************************************************************************/
834 static void setup_mcu(void)
836 /* Disable watchdog if enabled by bootloader/fuses */
837 MCUSR &= ~(1 << WDRF);
840 /* Disable clock division */
841 clock_prescale_set(clock_div_1);
844 static void setup_usb(void)
846 // Leonardo needs. Without this USB device is not recognized.
852 USB_Device_EnableSOFEvents();
853 print_set_sendchar(sendchar);
858 void fallthrough_callback(MidiDevice * device,
859 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
860 void cc_callback(MidiDevice * device,
861 uint8_t chan, uint8_t num, uint8_t val);
862 void sysex_callback(MidiDevice * device,
863 uint16_t start, uint8_t length, uint8_t * data);
866 int main(void) __attribute__ ((weak));
871 midi_device_init(&midi_device);
872 midi_device_set_send_func(&midi_device, usb_send_func);
873 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
882 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
883 midi_register_cc_callback(&midi_device, cc_callback);
884 midi_register_sysex_callback(&midi_device, sysex_callback);
887 // midi_send_cc(&midi_device, 0, 1, 2);
888 // midi_send_cc(&midi_device, 15, 1, 0);
889 // midi_send_noteon(&midi_device, 0, 64, 127);
890 // midi_send_noteoff(&midi_device, 0, 64, 127);
893 #ifdef BLUETOOTH_ENABLE
897 /* wait for USB startup & debug output */
900 while (USB_DeviceState != DEVICE_STATE_Configured) {
901 #if defined(INTERRUPT_CONTROL_ENDPOINT)
907 print("USB configured.\n");
913 host_set_driver(&lufa_driver);
914 #ifdef SLEEP_LED_ENABLE
918 print("Keyboard start.\n");
920 #ifndef BLUETOOTH_ENABLE
921 while (USB_DeviceState == DEVICE_STATE_Suspended) {
923 suspend_power_down();
924 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
925 USB_Device_SendRemoteWakeup();
931 midi_device_process(&midi_device);
936 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
943 void fallthrough_callback(MidiDevice * device,
944 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
948 switch (byte0 & 0xF0) {
950 play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
953 stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(byte1 & 0x7F)/12.0));
957 if (byte0 == MIDI_STOP) {
963 void cc_callback(MidiDevice * device,
964 uint8_t chan, uint8_t num, uint8_t val) {
965 //sending it back on the next channel
966 midi_send_cc(device, (chan + 1) % 16, num, val);
969 void sysex_callback(MidiDevice * device,
970 uint16_t start, uint8_t length, uint8_t * data) {
971 for (int i = 0; i < length; i++)
972 midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));