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"
57 #include "keycode_config.h"
59 extern keymap_config_t keymap_config;
67 #ifdef BLUETOOTH_ENABLE
68 #include "bluetooth.h"
79 uint8_t keyboard_idle = 0;
80 /* 0: Boot Protocol, 1: Report Protocol(default) */
81 uint8_t keyboard_protocol = 1;
82 static uint8_t keyboard_led_stats = 0;
84 static report_keyboard_t keyboard_report_sent;
87 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
88 void usb_get_midi(MidiDevice * device);
89 void midi_usb_init(MidiDevice * device);
93 static uint8_t keyboard_leds(void);
94 static void send_keyboard(report_keyboard_t *report);
95 static void send_mouse(report_mouse_t *report);
96 static void send_system(uint16_t data);
97 static void send_consumer(uint16_t data);
98 host_driver_t lufa_driver = {
111 /*******************************************************************************
113 ******************************************************************************/
116 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
120 .StreamingInterfaceNumber = AS_INTERFACE,
123 .Address = MIDI_STREAM_IN_EPADDR,
124 .Size = MIDI_STREAM_EPSIZE,
129 .Address = MIDI_STREAM_OUT_EPADDR,
130 .Size = MIDI_STREAM_EPSIZE,
136 #define SYSEX_START_OR_CONT 0x40
137 #define SYSEX_ENDS_IN_1 0x50
138 #define SYSEX_ENDS_IN_2 0x60
139 #define SYSEX_ENDS_IN_3 0x70
141 #define SYS_COMMON_1 0x50
142 #define SYS_COMMON_2 0x20
143 #define SYS_COMMON_3 0x30
146 #ifdef VIRTSER_ENABLE
147 USB_ClassInfo_CDC_Device_t cdc_device =
151 .ControlInterfaceNumber = CCI_INTERFACE,
154 .Address = CDC_IN_EPADDR,
160 .Address = CDC_OUT_EPADDR,
164 .NotificationEndpoint =
166 .Address = CDC_NOTIFICATION_EPADDR,
167 .Size = CDC_NOTIFICATION_EPSIZE,
175 /*******************************************************************************
177 ******************************************************************************/
178 #ifdef CONSOLE_ENABLE
179 static void Console_Task(void)
181 /* Device must be connected and configured for the task to run */
182 if (USB_DeviceState != DEVICE_STATE_Configured)
185 uint8_t ep = Endpoint_GetCurrentEndpoint();
188 // TODO: impl receivechar()/recvchar()
189 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
191 /* Check to see if a packet has been sent from the host */
192 if (Endpoint_IsOUTReceived())
194 /* Check to see if the packet contains data */
195 if (Endpoint_IsReadWriteAllowed())
197 /* Create a temporary buffer to hold the read in report from the host */
198 uint8_t ConsoleData[CONSOLE_EPSIZE];
200 /* Read Console Report Data */
201 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
203 /* Process Console Report Data */
204 //ProcessConsoleHIDReport(ConsoleData);
207 /* Finalize the stream transfer to send the last packet */
213 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
214 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
215 Endpoint_SelectEndpoint(ep);
220 while (Endpoint_IsReadWriteAllowed())
223 // flash senchar packet
224 if (Endpoint_IsINReady()) {
228 Endpoint_SelectEndpoint(ep);
233 /*******************************************************************************
235 ******************************************************************************/
237 * Event Order of Plug in:
238 * 0) EVENT_USB_Device_Connect
239 * 1) EVENT_USB_Device_Suspend
240 * 2) EVENT_USB_Device_Reset
241 * 3) EVENT_USB_Device_Wake
243 void EVENT_USB_Device_Connect(void)
246 /* For battery powered device */
247 if (!USB_IsInitialized) {
250 USB_Device_EnableSOFEvents();
254 void EVENT_USB_Device_Disconnect(void)
257 /* For battery powered device */
258 USB_IsInitialized = false;
259 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
260 if (USB_IsInitialized) {
261 USB_Disable(); // Disable all interrupts
262 USB_Controller_Enable();
263 USB_INT_Enable(USB_INT_VBUSTI);
268 void EVENT_USB_Device_Reset(void)
273 void EVENT_USB_Device_Suspend()
276 #ifdef SLEEP_LED_ENABLE
281 void EVENT_USB_Device_WakeUp()
284 suspend_wakeup_init();
286 #ifdef SLEEP_LED_ENABLE
288 // NOTE: converters may not accept this
289 led_set(host_keyboard_leds());
293 #ifdef CONSOLE_ENABLE
294 static bool console_flush = false;
295 #define CONSOLE_FLUSH_SET(b) do { \
296 uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
300 void EVENT_USB_Device_StartOfFrame(void)
302 static uint8_t count;
303 if (++count % 50) return;
306 if (!console_flush) return;
308 console_flush = false;
312 /** Event handler for the USB_ConfigurationChanged event.
313 * This is fired when the host sets the current configuration of the USB device after enumeration.
315 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
316 * it is safe to use singl bank for all endpoints.
318 void EVENT_USB_Device_ConfigurationChanged(void)
320 bool ConfigSuccess = true;
322 /* Setup Keyboard HID Report Endpoints */
323 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
324 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
327 /* Setup Mouse HID Report Endpoint */
328 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
329 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
332 #ifdef EXTRAKEY_ENABLE
333 /* Setup Extra HID Report Endpoint */
334 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
335 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
338 #ifdef CONSOLE_ENABLE
339 /* Setup Console HID Report Endpoints */
340 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
341 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
343 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
344 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
349 /* Setup NKRO HID Report Endpoints */
350 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
351 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
355 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
356 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
359 #ifdef VIRTSER_ENABLE
360 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
361 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
362 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
367 Appendix G: HID Request Support Requirements
369 The following table enumerates the requests that need to be supported by various types of HID class devices.
371 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
372 ------------------------------------------------------------------------------------------
373 Boot Mouse Required Optional Optional Optional Required Required
374 Non-Boot Mouse Required Optional Optional Optional Optional Optional
375 Boot Keyboard Required Optional Required Required Required Required
376 Non-Boot Keybrd Required Optional Required Required Optional Optional
377 Other Device Required Optional Optional Optional Optional Optional
379 /** Event handler for the USB_ControlRequest event.
380 * This is fired before passing along unhandled control requests to the library for processing internally.
382 void EVENT_USB_Device_ControlRequest(void)
384 uint8_t* ReportData = NULL;
385 uint8_t ReportSize = 0;
387 /* Handle HID Class specific requests */
388 switch (USB_ControlRequest.bRequest)
390 case HID_REQ_GetReport:
391 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
393 Endpoint_ClearSETUP();
396 switch (USB_ControlRequest.wIndex) {
397 case KEYBOARD_INTERFACE:
399 ReportData = (uint8_t*)&keyboard_report_sent;
400 ReportSize = sizeof(keyboard_report_sent);
404 /* Write the report data to the control endpoint */
405 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
410 case HID_REQ_SetReport:
411 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
415 switch (USB_ControlRequest.wIndex) {
416 case KEYBOARD_INTERFACE:
420 Endpoint_ClearSETUP();
422 while (!(Endpoint_IsOUTReceived())) {
423 if (USB_DeviceState == DEVICE_STATE_Unattached)
426 keyboard_led_stats = Endpoint_Read_8();
429 Endpoint_ClearStatusStage();
437 case HID_REQ_GetProtocol:
438 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
440 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
441 Endpoint_ClearSETUP();
442 while (!(Endpoint_IsINReady()));
443 Endpoint_Write_8(keyboard_protocol);
445 Endpoint_ClearStatusStage();
450 case HID_REQ_SetProtocol:
451 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
453 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
454 Endpoint_ClearSETUP();
455 Endpoint_ClearStatusStage();
457 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
463 case HID_REQ_SetIdle:
464 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
466 Endpoint_ClearSETUP();
467 Endpoint_ClearStatusStage();
469 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
473 case HID_REQ_GetIdle:
474 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
476 Endpoint_ClearSETUP();
477 while (!(Endpoint_IsINReady()));
478 Endpoint_Write_8(keyboard_idle);
480 Endpoint_ClearStatusStage();
486 #ifdef VIRTSER_ENABLE
487 CDC_Device_ProcessControlRequest(&cdc_device);
491 /*******************************************************************************
494 ******************************************************************************/
495 static uint8_t keyboard_leds(void)
497 return keyboard_led_stats;
500 static void send_keyboard(report_keyboard_t *report)
503 #ifdef BLUETOOTH_ENABLE
504 bluefruit_serial_send(0xFD);
505 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
506 bluefruit_serial_send(report->raw[i]);
510 uint8_t timeout = 255;
512 if (USB_DeviceState != DEVICE_STATE_Configured)
515 /* Select the Keyboard Report Endpoint */
517 if (keyboard_protocol && keymap_config.nkro) {
518 /* Report protocol - NKRO */
519 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
521 /* Check if write ready for a polling interval around 1ms */
522 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
523 if (!Endpoint_IsReadWriteAllowed()) return;
525 /* Write Keyboard Report Data */
526 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
532 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
534 /* Check if write ready for a polling interval around 10ms */
535 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
536 if (!Endpoint_IsReadWriteAllowed()) return;
538 /* Write Keyboard Report Data */
539 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
542 /* Finalize the stream transfer to send the last packet */
545 keyboard_report_sent = *report;
548 static void send_mouse(report_mouse_t *report)
552 #ifdef BLUETOOTH_ENABLE
553 bluefruit_serial_send(0xFD);
554 bluefruit_serial_send(0x00);
555 bluefruit_serial_send(0x03);
556 bluefruit_serial_send(report->buttons);
557 bluefruit_serial_send(report->x);
558 bluefruit_serial_send(report->y);
559 bluefruit_serial_send(report->v); // should try sending the wheel v here
560 bluefruit_serial_send(report->h); // should try sending the wheel h here
561 bluefruit_serial_send(0x00);
564 uint8_t timeout = 255;
566 if (USB_DeviceState != DEVICE_STATE_Configured)
569 /* Select the Mouse Report Endpoint */
570 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
572 /* Check if write ready for a polling interval around 10ms */
573 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
574 if (!Endpoint_IsReadWriteAllowed()) return;
576 /* Write Mouse Report Data */
577 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
579 /* Finalize the stream transfer to send the last packet */
584 static void send_system(uint16_t data)
586 uint8_t timeout = 255;
588 if (USB_DeviceState != DEVICE_STATE_Configured)
592 .report_id = REPORT_ID_SYSTEM,
595 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
597 /* Check if write ready for a polling interval around 10ms */
598 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
599 if (!Endpoint_IsReadWriteAllowed()) return;
601 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
605 static void send_consumer(uint16_t data)
608 #ifdef BLUETOOTH_ENABLE
609 static uint16_t last_data = 0;
610 if (data == last_data) return;
612 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
613 bluefruit_serial_send(0xFD);
614 bluefruit_serial_send(0x00);
615 bluefruit_serial_send(0x02);
616 bluefruit_serial_send((bitmap>>8)&0xFF);
617 bluefruit_serial_send(bitmap&0xFF);
618 bluefruit_serial_send(0x00);
619 bluefruit_serial_send(0x00);
620 bluefruit_serial_send(0x00);
621 bluefruit_serial_send(0x00);
624 uint8_t timeout = 255;
626 if (USB_DeviceState != DEVICE_STATE_Configured)
630 .report_id = REPORT_ID_CONSUMER,
633 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
635 /* Check if write ready for a polling interval around 10ms */
636 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
637 if (!Endpoint_IsReadWriteAllowed()) return;
639 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
644 /*******************************************************************************
646 ******************************************************************************/
647 #ifdef CONSOLE_ENABLE
648 #define SEND_TIMEOUT 5
649 int8_t sendchar(uint8_t c)
651 // Not wait once timeouted.
652 // Because sendchar() is called so many times, waiting each call causes big lag.
653 static bool timeouted = false;
655 // prevents Console_Task() from running during sendchar() runs.
656 // or char will be lost. These two function is mutually exclusive.
657 CONSOLE_FLUSH_SET(false);
659 if (USB_DeviceState != DEVICE_STATE_Configured)
662 uint8_t ep = Endpoint_GetCurrentEndpoint();
663 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
664 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
668 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
674 uint8_t timeout = SEND_TIMEOUT;
675 while (!Endpoint_IsReadWriteAllowed()) {
676 if (USB_DeviceState != DEVICE_STATE_Configured) {
679 if (Endpoint_IsStalled()) {
691 // send when bank is full
692 if (!Endpoint_IsReadWriteAllowed()) {
693 while (!(Endpoint_IsINReady()));
696 CONSOLE_FLUSH_SET(true);
699 Endpoint_SelectEndpoint(ep);
702 Endpoint_SelectEndpoint(ep);
706 int8_t sendchar(uint8_t c)
712 /*******************************************************************************
714 ******************************************************************************/
717 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
718 MIDI_EventPacket_t event;
725 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
727 //if the length is undefined we assume it is a SYSEX message
728 if (midi_packet_length(byte0) == UNDEFINED) {
731 if (byte2 == SYSEX_END)
732 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
734 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
737 if (byte1 == SYSEX_END)
738 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
740 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
743 if (byte0 == SYSEX_END)
744 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
746 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
749 return; //invalid cnt
752 //deal with 'system common' messages
753 //TODO are there any more?
754 switch(byte0 & 0xF0){
755 case MIDI_SONGPOSITION:
756 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
758 case MIDI_SONGSELECT:
759 case MIDI_TC_QUARTERFRAME:
760 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
763 event.Event = MIDI_EVENT(cable, byte0);
768 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
769 // Endpoint_ClearIN();
771 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
772 MIDI_Device_Flush(&USB_MIDI_Interface);
773 MIDI_Device_USBTask(&USB_MIDI_Interface);
777 void usb_get_midi(MidiDevice * device) {
778 MIDI_EventPacket_t event;
779 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
781 midi_packet_length_t length = midi_packet_length(event.Data1);
783 input[0] = event.Data1;
784 input[1] = event.Data2;
785 input[2] = event.Data3;
786 if (length == UNDEFINED) {
788 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
790 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
792 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
799 //pass the data to the device input function
800 if (length != UNDEFINED)
801 midi_device_input(device, length, input);
803 MIDI_Device_USBTask(&USB_MIDI_Interface);
807 void midi_usb_init(MidiDevice * device){
808 midi_device_init(device);
809 midi_device_set_send_func(device, usb_send_func);
810 midi_device_set_pre_input_process_func(device, usb_get_midi);
819 /* Device must be connected and configured for the task to run */
820 dprint("in MIDI_TASK\n");
821 if (USB_DeviceState != DEVICE_STATE_Configured)
823 dprint("continuing in MIDI_TASK\n");
825 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
827 if (Endpoint_IsINReady())
830 dprint("Endpoint is ready\n");
832 uint8_t MIDICommand = 0;
835 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
836 uint8_t Channel = MIDI_CHANNEL(1);
838 MIDICommand = MIDI_COMMAND_NOTE_ON;
841 /* Check if a MIDI command is to be sent */
844 dprint("Command exists\n");
845 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
847 .Event = MIDI_EVENT(0, MIDICommand),
849 .Data1 = MIDICommand | Channel,
851 .Data3 = MIDI_STANDARD_VELOCITY,
854 /* Write the MIDI event packet to the endpoint */
855 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
857 /* Send the data in the endpoint to the host */
863 /* Select the MIDI OUT stream */
864 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
866 /* Check if a MIDI command has been received */
867 if (Endpoint_IsOUTReceived())
869 MIDI_EventPacket_t MIDIEvent;
871 /* Read the MIDI event packet from the endpoint */
872 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
874 /* If the endpoint is now empty, clear the bank */
875 if (!(Endpoint_BytesInEndpoint()))
877 /* Clear the endpoint ready for new packet */
885 /*******************************************************************************
887 ******************************************************************************/
889 #ifdef VIRTSER_ENABLE
890 void virtser_init(void)
892 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
893 CDC_Device_SendControlLineStateChange(&cdc_device);
896 void virtser_recv(uint8_t c) __attribute__ ((weak));
897 void virtser_recv(uint8_t c)
902 void virtser_task(void)
904 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
908 ch = CDC_Device_ReceiveByte(&cdc_device);
912 void virtser_send(const uint8_t byte)
914 uint8_t timeout = 255;
915 uint8_t ep = Endpoint_GetCurrentEndpoint();
917 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
920 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
922 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
923 Endpoint_SelectEndpoint(ep);
927 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
929 Endpoint_Write_8(byte);
930 CDC_Device_Flush(&cdc_device);
932 if (Endpoint_IsINReady()) {
936 Endpoint_SelectEndpoint(ep);
941 /*******************************************************************************
943 ******************************************************************************/
944 static void setup_mcu(void)
946 /* Disable watchdog if enabled by bootloader/fuses */
947 MCUSR &= ~(1 << WDRF);
950 /* Disable clock division */
951 // clock_prescale_set(clock_div_1);
953 CLKPR = (1 << CLKPCE);
954 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
957 static void setup_usb(void)
959 // Leonardo needs. Without this USB device is not recognized.
965 USB_Device_EnableSOFEvents();
966 print_set_sendchar(sendchar);
971 void fallthrough_callback(MidiDevice * device,
972 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
973 void cc_callback(MidiDevice * device,
974 uint8_t chan, uint8_t num, uint8_t val);
975 void sysex_callback(MidiDevice * device,
976 uint16_t start, uint8_t length, uint8_t * data);
979 int main(void) __attribute__ ((weak));
984 midi_device_init(&midi_device);
985 midi_device_set_send_func(&midi_device, usb_send_func);
986 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
995 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
996 midi_register_cc_callback(&midi_device, cc_callback);
997 midi_register_sysex_callback(&midi_device, sysex_callback);
1000 // midi_send_cc(&midi_device, 0, 1, 2);
1001 // midi_send_cc(&midi_device, 15, 1, 0);
1002 // midi_send_noteon(&midi_device, 0, 64, 127);
1003 // midi_send_noteoff(&midi_device, 0, 64, 127);
1006 #ifdef BLUETOOTH_ENABLE
1010 /* wait for USB startup & debug output */
1013 while (USB_DeviceState != DEVICE_STATE_Configured) {
1014 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1020 print("USB configured.\n");
1026 host_set_driver(&lufa_driver);
1027 #ifdef SLEEP_LED_ENABLE
1031 #ifdef VIRTSER_ENABLE
1035 print("Keyboard start.\n");
1037 #ifndef BLUETOOTH_ENABLE
1038 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1040 suspend_power_down();
1041 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1042 USB_Device_SendRemoteWakeup();
1050 midi_device_process(&midi_device);
1054 #ifdef RGBLIGHT_ENABLE
1058 #ifdef VIRTSER_ENABLE
1060 CDC_Device_USBTask(&cdc_device);
1063 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1070 void fallthrough_callback(MidiDevice * device,
1071 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
1075 switch (byte0 & 0xF0) {
1077 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1080 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1084 if (byte0 == MIDI_STOP) {
1091 rgblight_config_t rgblight_config;
1094 void cc_callback(MidiDevice * device,
1095 uint8_t chan, uint8_t num, uint8_t val) {
1096 //sending it back on the next channel
1097 // midi_send_cc(device, (chan + 1) % 16, num, val);
1099 rgblight_config.raw = eeconfig_read_rgblight();
1102 rgblight_config.hue = val * 360 / 127;
1105 rgblight_config.sat = val << 1;
1108 rgblight_config.val = val << 1;
1111 rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
1115 void send_dword(uint32_t number) {
1116 uint16_t word = (number >> 16);
1118 send_word(number & 0xFFFFUL);
1121 void send_word(uint16_t number) {
1122 uint8_t byte = number >> 8;
1124 send_byte(number & 0xFF);
1127 void send_byte(uint8_t number) {
1128 uint8_t nibble = number >> 4;
1129 send_nibble(nibble);
1130 send_nibble(number & 0xF);
1133 void send_nibble(uint8_t number) {
1136 register_code(KC_0);
1137 unregister_code(KC_0);
1140 register_code(KC_1 + (number - 1));
1141 unregister_code(KC_1 + (number - 1));
1144 register_code(KC_A + (number - 0xA));
1145 unregister_code(KC_A + (number - 0xA));
1150 uint8_t midi_buffer[16] = {0};
1152 void sysex_callback(MidiDevice * device,
1153 uint16_t start, uint8_t length, uint8_t * data) {
1154 // for (int i = 0; i < length; i++)
1155 // midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));
1156 // if (start == 0x27) {
1157 // SEND_STRING("\n");
1158 // send_word(start);
1159 // SEND_STRING(": ");
1160 for (uint8_t place = 0; place < length; place++) {
1161 // send_byte(*data);
1162 midi_buffer[start + place] = *data;
1164 sysex_buffer_callback(device, start + place, &midi_buffer);
1165 // SEND_STRING(" ");
1172 uint32_t decode_4byte_chunk(uint8_t * data) {
1173 uint32_t part1 = *data++;
1174 uint32_t part2 = *data++;
1175 uint32_t part3 = *data++;
1176 uint32_t part4 = *data++;
1177 uint32_t part5 = *data++;
1178 return ((part1 & 0x1FUL) << 28) | (part2 << 21) | (part3 << 14) | (part4 << 7) | part5;
1181 void encode_4byte_chunk(uint32_t data, uint8_t * pointer) {
1182 *pointer++ = (data >> 28) & 0x7F;
1183 *pointer++ = (data >> 21) & 0x7F;
1184 *pointer++ = (data >> 14) & 0x7F;
1185 *pointer++ = (data >> 7) & 0x7F;
1186 *pointer++ = (data) & 0x7F;
1189 void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) {
1190 uint8_t * pointer_copy = data;
1192 if (*data++ != 0xF0)
1200 case 0x13: ; // Get info from keyboard
1202 case 0x00: ; // Get layer state
1203 // send_dword(layer_state);
1205 encode_4byte_chunk(layer_state | default_layer_state, &chunk);
1207 uint8_t array[] = {0xF0, 0x00, 0x00, 0x00, 0x00, chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], 0xF7};
1208 midi_send_array(&midi_device, 11, &array);
1209 // midi_send_data(device, 3, 0x00, layer_state >> 24 & 0x7f, layer_state >> 16 & 0x7f);
1210 // midi_send_data(device, 6, layer_state >> 8 & 0x7f, layer_state & 0x7f, 0xF7);
1213 #ifdef RGBLIGHT_ENABLE
1214 case 0x27: ; // RGB LED functions
1216 case 0x00: ; // Update HSV
1217 uint32_t chunk = decode_4byte_chunk(data);
1218 rgblight_sethsv(((chunk >> 16) & 0xFFFF) % 360, (chunk >> 8) & 0xFF, chunk & 0xFF);
1220 case 0x01: ; // Update RGB
1227 // SEND_STRING("\nDATA:\n");
1228 // while (*pointer_copy != 0xF7) {
1229 // send_byte(*pointer_copy++);
1230 // SEND_STRING(" ");
1235 void send_unicode_midi(uint32_t unicode) {
1237 encode_4byte_chunk(unicode, &chunk);
1239 uint8_t array[] = {0xF0, 0x00, 0x00, 0x00, 0x05, chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], 0xF7};
1240 midi_send_array(&midi_device, 11, &array);