]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/lufa/lufa.c
rgb light through midi
[qmk_firmware.git] / tmk_core / protocol / lufa / lufa.c
1 /*
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
6  */
7
8 /*
9              LUFA Library
10      Copyright (C) Dean Camera, 2012.
11
12   dean [at] fourwalledcubicle [dot] com
13            www.lufa-lib.org
14 */
15
16 /*
17   Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)
18   Copyright 2010  Denver Gingerich (denver [at] ossguy [dot] com)
19
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.
28
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
36   this software.
37 */
38
39 #include "report.h"
40 #include "host.h"
41 #include "host_driver.h"
42 #include "keyboard.h"
43 #include "action.h"
44 #include "led.h"
45 #include "sendchar.h"
46 #include "debug.h"
47 #ifdef SLEEP_LED_ENABLE
48 #include "sleep_led.h"
49 #endif
50 #include "suspend.h"
51
52 #include "descriptor.h"
53 #include "lufa.h"
54 #include "quantum.h"
55
56 #ifdef NKRO_ENABLE
57   #include "keycode_config.h"
58
59   extern keymap_config_t keymap_config;
60 #endif
61
62
63 #ifdef AUDIO_ENABLE
64     #include <audio.h>
65 #endif
66
67 #ifdef BLUETOOTH_ENABLE
68     #include "bluetooth.h"
69 #endif
70
71 #ifdef VIRTSER_ENABLE
72     #include "virtser.h"
73 #endif
74
75 #ifdef RGB_MIDI
76     #include "rgblight.h"        
77 #endif
78
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;
83
84 static report_keyboard_t keyboard_report_sent;
85
86 #ifdef MIDI_ENABLE
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);
90 #endif
91
92 /* Host driver */
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 = {
99     keyboard_leds,
100     send_keyboard,
101     send_mouse,
102     send_system,
103     send_consumer,
104 #ifdef MIDI_ENABLE
105     usb_send_func,
106     usb_get_midi,
107     midi_usb_init
108 #endif
109 };
110
111 /*******************************************************************************
112  * MIDI
113  ******************************************************************************/
114
115 #ifdef MIDI_ENABLE
116 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
117 {
118   .Config =
119   {
120     .StreamingInterfaceNumber = AS_INTERFACE,
121     .DataINEndpoint           =
122     {
123       .Address          = MIDI_STREAM_IN_EPADDR,
124       .Size             = MIDI_STREAM_EPSIZE,
125       .Banks            = 1,
126     },
127     .DataOUTEndpoint          =
128     {
129       .Address          = MIDI_STREAM_OUT_EPADDR,
130       .Size             = MIDI_STREAM_EPSIZE,
131       .Banks            = 1,
132     },
133   },
134 };
135
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
140
141 #define SYS_COMMON_1 0x50
142 #define SYS_COMMON_2 0x20
143 #define SYS_COMMON_3 0x30
144 #endif
145
146 #ifdef VIRTSER_ENABLE
147 USB_ClassInfo_CDC_Device_t cdc_device =
148 {
149   .Config =
150   {
151     .ControlInterfaceNumber = CCI_INTERFACE,
152     .DataINEndpoint         =
153     {
154       .Address          = CDC_IN_EPADDR,
155       .Size             = CDC_EPSIZE,
156       .Banks            = 1,
157     },
158     .DataOUTEndpoint        =
159     {
160       .Address          = CDC_OUT_EPADDR,
161       .Size             = CDC_EPSIZE,
162       .Banks            = 1,
163     },
164     .NotificationEndpoint   =
165     {
166       .Address          = CDC_NOTIFICATION_EPADDR,
167       .Size             = CDC_NOTIFICATION_EPSIZE,
168       .Banks            = 1,
169     },
170   },
171 };
172 #endif
173
174
175 /*******************************************************************************
176  * Console
177  ******************************************************************************/
178 #ifdef CONSOLE_ENABLE
179 static void Console_Task(void)
180 {
181     /* Device must be connected and configured for the task to run */
182     if (USB_DeviceState != DEVICE_STATE_Configured)
183         return;
184
185     uint8_t ep = Endpoint_GetCurrentEndpoint();
186
187 #if 0
188     // TODO: impl receivechar()/recvchar()
189     Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
190
191     /* Check to see if a packet has been sent from the host */
192     if (Endpoint_IsOUTReceived())
193     {
194         /* Check to see if the packet contains data */
195         if (Endpoint_IsReadWriteAllowed())
196         {
197             /* Create a temporary buffer to hold the read in report from the host */
198             uint8_t ConsoleData[CONSOLE_EPSIZE];
199
200             /* Read Console Report Data */
201             Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
202
203             /* Process Console Report Data */
204             //ProcessConsoleHIDReport(ConsoleData);
205         }
206
207         /* Finalize the stream transfer to send the last packet */
208         Endpoint_ClearOUT();
209     }
210 #endif
211
212     /* IN packet */
213     Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
214     if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
215         Endpoint_SelectEndpoint(ep);
216         return;
217     }
218
219     // fill empty bank
220     while (Endpoint_IsReadWriteAllowed())
221         Endpoint_Write_8(0);
222
223     // flash senchar packet
224     if (Endpoint_IsINReady()) {
225         Endpoint_ClearIN();
226     }
227
228     Endpoint_SelectEndpoint(ep);
229 }
230 #endif
231
232
233 /*******************************************************************************
234  * USB Events
235  ******************************************************************************/
236 /*
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
242 */
243 void EVENT_USB_Device_Connect(void)
244 {
245     print("[C]");
246     /* For battery powered device */
247     if (!USB_IsInitialized) {
248         USB_Disable();
249         USB_Init();
250         USB_Device_EnableSOFEvents();
251     }
252 }
253
254 void EVENT_USB_Device_Disconnect(void)
255 {
256     print("[D]");
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);
264     }
265 */
266 }
267
268 void EVENT_USB_Device_Reset(void)
269 {
270     print("[R]");
271 }
272
273 void EVENT_USB_Device_Suspend()
274 {
275     print("[S]");
276 #ifdef SLEEP_LED_ENABLE
277     sleep_led_enable();
278 #endif
279 }
280
281 void EVENT_USB_Device_WakeUp()
282 {
283     print("[W]");
284     suspend_wakeup_init();
285
286 #ifdef SLEEP_LED_ENABLE
287     sleep_led_disable();
288     // NOTE: converters may not accept this
289     led_set(host_keyboard_leds());
290 #endif
291 }
292
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; \
297 } while (0)
298
299 // called every 1ms
300 void EVENT_USB_Device_StartOfFrame(void)
301 {
302     static uint8_t count;
303     if (++count % 50) return;
304     count = 0;
305
306     if (!console_flush) return;
307     Console_Task();
308     console_flush = false;
309 }
310 #endif
311
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.
314  *
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.
317  */
318 void EVENT_USB_Device_ConfigurationChanged(void)
319 {
320     bool ConfigSuccess = true;
321
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);
325
326 #ifdef MOUSE_ENABLE
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);
330 #endif
331
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);
336 #endif
337
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);
342 #if 0
343     ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
344                                      CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
345 #endif
346 #endif
347
348 #ifdef NKRO_ENABLE
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);
352 #endif
353
354 #ifdef MIDI_ENABLE
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);
357 #endif
358
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);
363 #endif
364 }
365
366 /*
367 Appendix G: HID Request Support Requirements
368
369 The following table enumerates the requests that need to be supported by various types of HID class devices.
370
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
378 */
379 /** Event handler for the USB_ControlRequest event.
380  *  This is fired before passing along unhandled control requests to the library for processing internally.
381  */
382 void EVENT_USB_Device_ControlRequest(void)
383 {
384     uint8_t* ReportData = NULL;
385     uint8_t  ReportSize = 0;
386
387     /* Handle HID Class specific requests */
388     switch (USB_ControlRequest.bRequest)
389     {
390         case HID_REQ_GetReport:
391             if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
392             {
393                 Endpoint_ClearSETUP();
394
395                 // Interface
396                 switch (USB_ControlRequest.wIndex) {
397                 case KEYBOARD_INTERFACE:
398                     // TODO: test/check
399                     ReportData = (uint8_t*)&keyboard_report_sent;
400                     ReportSize = sizeof(keyboard_report_sent);
401                     break;
402                 }
403
404                 /* Write the report data to the control endpoint */
405                 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
406                 Endpoint_ClearOUT();
407             }
408
409             break;
410         case HID_REQ_SetReport:
411             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
412             {
413
414                 // Interface
415                 switch (USB_ControlRequest.wIndex) {
416                 case KEYBOARD_INTERFACE:
417 #ifdef NKRO_ENABLE
418                 case NKRO_INTERFACE:
419 #endif
420                     Endpoint_ClearSETUP();
421
422                     while (!(Endpoint_IsOUTReceived())) {
423                         if (USB_DeviceState == DEVICE_STATE_Unattached)
424                           return;
425                     }
426                     keyboard_led_stats = Endpoint_Read_8();
427
428                     Endpoint_ClearOUT();
429                     Endpoint_ClearStatusStage();
430                     break;
431                 }
432
433             }
434
435             break;
436
437         case HID_REQ_GetProtocol:
438             if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
439             {
440                 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
441                     Endpoint_ClearSETUP();
442                     while (!(Endpoint_IsINReady()));
443                     Endpoint_Write_8(keyboard_protocol);
444                     Endpoint_ClearIN();
445                     Endpoint_ClearStatusStage();
446                 }
447             }
448
449             break;
450         case HID_REQ_SetProtocol:
451             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
452             {
453                 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
454                     Endpoint_ClearSETUP();
455                     Endpoint_ClearStatusStage();
456
457                     keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
458                     clear_keyboard();
459                 }
460             }
461
462             break;
463         case HID_REQ_SetIdle:
464             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
465             {
466                 Endpoint_ClearSETUP();
467                 Endpoint_ClearStatusStage();
468
469                 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
470             }
471
472             break;
473         case HID_REQ_GetIdle:
474             if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
475             {
476                 Endpoint_ClearSETUP();
477                 while (!(Endpoint_IsINReady()));
478                 Endpoint_Write_8(keyboard_idle);
479                 Endpoint_ClearIN();
480                 Endpoint_ClearStatusStage();
481             }
482
483             break;
484     }
485
486 #ifdef VIRTSER_ENABLE
487     CDC_Device_ProcessControlRequest(&cdc_device);
488 #endif
489 }
490
491 /*******************************************************************************
492  * Host driver
493 p
494  ******************************************************************************/
495 static uint8_t keyboard_leds(void)
496 {
497     return keyboard_led_stats;
498 }
499
500 static void send_keyboard(report_keyboard_t *report)
501 {
502
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]);
507     }
508 #endif
509
510     uint8_t timeout = 255;
511
512     if (USB_DeviceState != DEVICE_STATE_Configured)
513         return;
514
515     /* Select the Keyboard Report Endpoint */
516 #ifdef NKRO_ENABLE
517     if (keyboard_protocol && keymap_config.nkro) {
518         /* Report protocol - NKRO */
519         Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
520
521         /* Check if write ready for a polling interval around 1ms */
522         while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
523         if (!Endpoint_IsReadWriteAllowed()) return;
524
525         /* Write Keyboard Report Data */
526         Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
527     }
528     else
529 #endif
530     {
531         /* Boot protocol */
532         Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
533
534         /* Check if write ready for a polling interval around 10ms */
535         while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
536         if (!Endpoint_IsReadWriteAllowed()) return;
537
538         /* Write Keyboard Report Data */
539         Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
540     }
541
542     /* Finalize the stream transfer to send the last packet */
543     Endpoint_ClearIN();
544
545     keyboard_report_sent = *report;
546 }
547
548 static void send_mouse(report_mouse_t *report)
549 {
550 #ifdef MOUSE_ENABLE
551
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);
562 #endif
563
564     uint8_t timeout = 255;
565
566     if (USB_DeviceState != DEVICE_STATE_Configured)
567         return;
568
569     /* Select the Mouse Report Endpoint */
570     Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
571
572     /* Check if write ready for a polling interval around 10ms */
573     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
574     if (!Endpoint_IsReadWriteAllowed()) return;
575
576     /* Write Mouse Report Data */
577     Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
578
579     /* Finalize the stream transfer to send the last packet */
580     Endpoint_ClearIN();
581 #endif
582 }
583
584 static void send_system(uint16_t data)
585 {
586     uint8_t timeout = 255;
587
588     if (USB_DeviceState != DEVICE_STATE_Configured)
589         return;
590
591     report_extra_t r = {
592         .report_id = REPORT_ID_SYSTEM,
593         .usage = data
594     };
595     Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
596
597     /* Check if write ready for a polling interval around 10ms */
598     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
599     if (!Endpoint_IsReadWriteAllowed()) return;
600
601     Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
602     Endpoint_ClearIN();
603 }
604
605 static void send_consumer(uint16_t data)
606 {
607
608 #ifdef BLUETOOTH_ENABLE
609     static uint16_t last_data = 0;
610     if (data == last_data) return;
611     last_data = data;
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);
622 #endif
623
624     uint8_t timeout = 255;
625
626     if (USB_DeviceState != DEVICE_STATE_Configured)
627         return;
628
629     report_extra_t r = {
630         .report_id = REPORT_ID_CONSUMER,
631         .usage = data
632     };
633     Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
634
635     /* Check if write ready for a polling interval around 10ms */
636     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
637     if (!Endpoint_IsReadWriteAllowed()) return;
638
639     Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
640     Endpoint_ClearIN();
641 }
642
643
644 /*******************************************************************************
645  * sendchar
646  ******************************************************************************/
647 #ifdef CONSOLE_ENABLE
648 #define SEND_TIMEOUT 5
649 int8_t sendchar(uint8_t c)
650 {
651     // Not wait once timeouted.
652     // Because sendchar() is called so many times, waiting each call causes big lag.
653     static bool timeouted = false;
654
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);
658
659     if (USB_DeviceState != DEVICE_STATE_Configured)
660         return -1;
661
662     uint8_t ep = Endpoint_GetCurrentEndpoint();
663     Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
664     if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
665         goto ERROR_EXIT;
666     }
667
668     if (timeouted && !Endpoint_IsReadWriteAllowed()) {
669         goto ERROR_EXIT;
670     }
671
672     timeouted = false;
673
674     uint8_t timeout = SEND_TIMEOUT;
675     while (!Endpoint_IsReadWriteAllowed()) {
676         if (USB_DeviceState != DEVICE_STATE_Configured) {
677             goto ERROR_EXIT;
678         }
679         if (Endpoint_IsStalled()) {
680             goto ERROR_EXIT;
681         }
682         if (!(timeout--)) {
683             timeouted = true;
684             goto ERROR_EXIT;
685         }
686         _delay_ms(1);
687     }
688
689     Endpoint_Write_8(c);
690
691     // send when bank is full
692     if (!Endpoint_IsReadWriteAllowed()) {
693         while (!(Endpoint_IsINReady()));
694         Endpoint_ClearIN();
695     } else {
696         CONSOLE_FLUSH_SET(true);
697     }
698
699     Endpoint_SelectEndpoint(ep);
700     return 0;
701 ERROR_EXIT:
702     Endpoint_SelectEndpoint(ep);
703     return -1;
704 }
705 #else
706 int8_t sendchar(uint8_t c)
707 {
708     return 0;
709 }
710 #endif
711
712 /*******************************************************************************
713  * MIDI
714  ******************************************************************************/
715
716 #ifdef MIDI_ENABLE
717 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
718   MIDI_EventPacket_t event;
719   event.Data1 = byte0;
720   event.Data2 = byte1;
721   event.Data3 = byte2;
722
723   uint8_t cable = 0;
724
725 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
726
727   //if the length is undefined we assume it is a SYSEX message
728   if (midi_packet_length(byte0) == UNDEFINED) {
729     switch(cnt) {
730       case 3:
731         if (byte2 == SYSEX_END)
732           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
733         else
734           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
735         break;
736       case 2:
737         if (byte1 == SYSEX_END)
738           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
739         else
740           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
741         break;
742       case 1:
743         if (byte0 == SYSEX_END)
744           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
745         else
746           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
747         break;
748       default:
749         return; //invalid cnt
750     }
751   } else {
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);
757         break;
758       case MIDI_SONGSELECT:
759       case MIDI_TC_QUARTERFRAME:
760         event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
761         break;
762       default:
763         event.Event = MIDI_EVENT(cable, byte0);
764         break;
765     }
766   }
767
768 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
769 // Endpoint_ClearIN();
770
771   MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
772   MIDI_Device_Flush(&USB_MIDI_Interface);
773   MIDI_Device_USBTask(&USB_MIDI_Interface);
774   USB_USBTask();
775 }
776
777 void usb_get_midi(MidiDevice * device) {
778   MIDI_EventPacket_t event;
779   while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
780
781     midi_packet_length_t length = midi_packet_length(event.Data1);
782     uint8_t input[3];
783     input[0] = event.Data1;
784     input[1] = event.Data2;
785     input[2] = event.Data3;
786     if (length == UNDEFINED) {
787       //sysex
788       if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
789         length = 3;
790       } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
791         length = 2;
792       } else if(event.Event ==  MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
793         length = 1;
794       } else {
795         //XXX what to do?
796       }
797     }
798
799     //pass the data to the device input function
800     if (length != UNDEFINED)
801       midi_device_input(device, length, input);
802   }
803   MIDI_Device_USBTask(&USB_MIDI_Interface);
804   USB_USBTask();
805 }
806
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);
811
812   SetupHardware();
813   sei();
814 }
815
816 void MIDI_Task(void)
817 {
818
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)
822       return;
823     dprint("continuing in MIDI_TASK\n");
824
825     Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
826
827     if (Endpoint_IsINReady())
828     {
829
830         dprint("Endpoint is ready\n");
831
832         uint8_t MIDICommand = 0;
833         uint8_t MIDIPitch;
834
835         /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
836         uint8_t Channel = MIDI_CHANNEL(1);
837
838         MIDICommand = MIDI_COMMAND_NOTE_ON;
839         MIDIPitch   = 0x3E;
840
841         /* Check if a MIDI command is to be sent */
842         if (MIDICommand)
843         {
844             dprint("Command exists\n");
845             MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
846                 {
847                     .Event       = MIDI_EVENT(0, MIDICommand),
848
849                     .Data1       = MIDICommand | Channel,
850                     .Data2       = MIDIPitch,
851                     .Data3       = MIDI_STANDARD_VELOCITY,
852                 };
853
854             /* Write the MIDI event packet to the endpoint */
855             Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
856
857             /* Send the data in the endpoint to the host */
858             Endpoint_ClearIN();
859         }
860     }
861
862
863     /* Select the MIDI OUT stream */
864     Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
865
866     /* Check if a MIDI command has been received */
867     if (Endpoint_IsOUTReceived())
868     {
869         MIDI_EventPacket_t MIDIEvent;
870
871         /* Read the MIDI event packet from the endpoint */
872         Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
873
874         /* If the endpoint is now empty, clear the bank */
875         if (!(Endpoint_BytesInEndpoint()))
876         {
877             /* Clear the endpoint ready for new packet */
878             Endpoint_ClearOUT();
879         }
880     }
881 }
882
883 #endif
884
885 /*******************************************************************************
886  * VIRTUAL SERIAL
887  ******************************************************************************/
888
889 #ifdef VIRTSER_ENABLE
890 void virtser_init(void)
891 {
892   cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
893   CDC_Device_SendControlLineStateChange(&cdc_device);
894 }
895
896 void virtser_recv(uint8_t c) __attribute__ ((weak));
897 void virtser_recv(uint8_t c)
898 {
899   // Ignore by default
900 }
901
902 void virtser_task(void)
903 {
904   uint16_t count = CDC_Device_BytesReceived(&cdc_device);
905   uint8_t ch;
906   if (count)
907   {
908     ch = CDC_Device_ReceiveByte(&cdc_device);
909     virtser_recv(ch);
910   }
911 }
912 void virtser_send(const uint8_t byte)
913 {
914   uint8_t timeout = 255;
915   uint8_t ep = Endpoint_GetCurrentEndpoint();
916
917   if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
918   {
919     /* IN packet */
920     Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
921
922     if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
923         Endpoint_SelectEndpoint(ep);
924         return;
925     }
926
927     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
928
929     Endpoint_Write_8(byte);
930     CDC_Device_Flush(&cdc_device);
931
932     if (Endpoint_IsINReady()) {
933       Endpoint_ClearIN();
934     }
935
936     Endpoint_SelectEndpoint(ep);
937   }
938 }
939 #endif
940
941 /*******************************************************************************
942  * main
943  ******************************************************************************/
944 static void setup_mcu(void)
945 {
946     /* Disable watchdog if enabled by bootloader/fuses */
947     MCUSR &= ~(1 << WDRF);
948     wdt_disable();
949
950     /* Disable clock division */
951     // clock_prescale_set(clock_div_1);
952
953     CLKPR = (1 << CLKPCE);
954     CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
955 }
956
957 static void setup_usb(void)
958 {
959     // Leonardo needs. Without this USB device is not recognized.
960     USB_Disable();
961
962     USB_Init();
963
964     // for Console_Task
965     USB_Device_EnableSOFEvents();
966     print_set_sendchar(sendchar);
967 }
968
969
970 #ifdef MIDI_ENABLE
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);
977 #endif
978
979 int main(void)  __attribute__ ((weak));
980 int main(void)
981 {
982
983 #ifdef MIDI_ENABLE
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);
987 #endif
988
989     setup_mcu();
990     keyboard_setup();
991     setup_usb();
992     sei();
993
994 #ifdef MIDI_ENABLE
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);
998
999     // init_notes();
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);
1004 #endif
1005
1006 #ifdef BLUETOOTH_ENABLE
1007     serial_init();
1008 #endif
1009
1010     /* wait for USB startup & debug output */
1011
1012 #ifdef WAIT_FOR_USB
1013     while (USB_DeviceState != DEVICE_STATE_Configured) {
1014     #if defined(INTERRUPT_CONTROL_ENDPOINT)
1015             ;
1016     #else
1017             USB_USBTask();
1018     #endif
1019     }
1020     print("USB configured.\n");
1021 #else
1022     USB_USBTask();
1023 #endif
1024     /* init modules */
1025     keyboard_init();
1026     host_set_driver(&lufa_driver);
1027 #ifdef SLEEP_LED_ENABLE
1028     sleep_led_init();
1029 #endif
1030
1031 #ifdef VIRTSER_ENABLE
1032     virtser_init();
1033 #endif
1034
1035     print("Keyboard start.\n");
1036     while (1) {
1037         #ifndef BLUETOOTH_ENABLE
1038         while (USB_DeviceState == DEVICE_STATE_Suspended) {
1039             print("[s]");
1040             suspend_power_down();
1041             if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1042                     USB_Device_SendRemoteWakeup();
1043             }
1044         }
1045         #endif
1046
1047         keyboard_task();
1048
1049 #ifdef MIDI_ENABLE
1050         midi_device_process(&midi_device);
1051         // MIDI_Task();
1052 #endif
1053         
1054 #ifdef RGBLIGHT_ENABLE
1055         rgblight_task();
1056 #endif
1057
1058 #ifdef VIRTSER_ENABLE
1059         virtser_task();
1060         CDC_Device_USBTask(&cdc_device);
1061 #endif
1062
1063 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1064         USB_USBTask();
1065 #endif
1066     }
1067 }
1068
1069 #ifdef MIDI_ENABLE
1070 void fallthrough_callback(MidiDevice * device,
1071     uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
1072
1073 #ifdef AUDIO_ENABLE
1074   if (cnt == 3) {
1075     switch (byte0 & 0xF0) {
1076         case MIDI_NOTEON:
1077             play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1078             break;
1079         case MIDI_NOTEOFF:
1080             stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1081             break;
1082     }
1083   }
1084   if (byte0 == MIDI_STOP) {
1085     stop_all_notes();
1086   }
1087 #endif
1088 }
1089
1090 #ifdef RGB_MIDI
1091     rgblight_config_t rgblight_config;
1092 #endif
1093
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);
1098     #ifdef RGB_MIDI
1099         rgblight_config.raw = eeconfig_read_rgblight();
1100         switch (num) {
1101             case 14:
1102                 rgblight_config.hue = val * 360 / 127;
1103             break;
1104             case 15:
1105                 rgblight_config.sat = val << 1;
1106             break;
1107             case 16:
1108                 rgblight_config.val = val << 1;
1109             break;
1110         }
1111         rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
1112     #endif
1113 }
1114
1115 void send_dword(uint32_t number) {
1116     uint16_t word = (number >> 16);
1117     send_word(word);
1118     send_word(number & 0xFFFFUL);
1119 }
1120
1121 void send_word(uint16_t number) {
1122     uint8_t byte = number >> 8;
1123     send_byte(byte);
1124     send_byte(number & 0xFF);
1125 }
1126
1127 void send_byte(uint8_t number) {
1128     uint8_t nibble = number >> 4;
1129     send_nibble(nibble);
1130     send_nibble(number & 0xF);
1131 }
1132
1133 void send_nibble(uint8_t number) {
1134     switch (number) {
1135         case 0:
1136             register_code(KC_0);
1137             unregister_code(KC_0);
1138             break;
1139         case 1 ... 9:
1140             register_code(KC_1 + (number - 1));
1141             unregister_code(KC_1 + (number - 1));
1142             break;
1143         case 0xA ... 0xF:
1144             register_code(KC_A + (number - 0xA));
1145             unregister_code(KC_A + (number - 0xA));
1146             break;
1147     }
1148 }
1149
1150 uint8_t midi_buffer[16] = {0};
1151
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;
1163             if (*data == 0xF7)
1164                 sysex_buffer_callback(start + place, &midi_buffer);
1165             // SEND_STRING(" ");
1166             data++;
1167         }
1168     // }
1169
1170 }
1171
1172 void sysex_buffer_callback(uint8_t length, uint8_t * data) {
1173     uint8_t * pointer_copy = data;
1174
1175     if (*data++ != 0xF0)
1176         return
1177     data++;
1178     data++;
1179     data++;
1180     data++;
1181
1182     switch (*data++) {
1183         case 0x27: ; // RGB LED functions
1184             switch (*data++)
1185                 case 0x00: ; // Update HSV
1186                     uint32_t part1 = *data++;
1187                     uint32_t part2 = *data++;
1188                     uint32_t part3 = *data++;
1189                     uint32_t part4 = *data++;
1190                     uint32_t part5 = *data++;
1191                     uint32_t chunk = ((part1 & 0x1FUL) << 28) | (part2 << 21) | (part3 << 14) | (part4 << 7) | part5;
1192                     // SEND_STRING("\nCHUNK: ");
1193                     // send_dword(chunk);
1194                     rgblight_sethsv(((chunk >> 16) & 0xFFFF) % 360, (chunk >> 8) & 0xFF, chunk & 0xFF);
1195                     // SEND_STRING("\nHUE: ");
1196                     // send_word(((chunk >> 16) & 0xFFFF) % 360);
1197                     // SEND_STRING("\nSAT: ");
1198                     // send_word((chunk >> 8) & 0xFF);
1199                     // SEND_STRING("\nVAL: ");
1200                     // send_word(chunk & 0xFF);
1201                     break;
1202                 case 0x01: ; // Update RGB
1203                     break;
1204             break;
1205     }
1206
1207     // SEND_STRING("\nDATA:\n");
1208     // while (*pointer_copy != 0xF7) {
1209     //     send_byte(*pointer_copy++);
1210     //     SEND_STRING(" ");
1211     // }
1212
1213 }
1214
1215 #endif