]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/lufa/lufa.c
Merge pull request #157 from DidierLoiseau/typematrix
[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
55 #ifdef AUDIO_ENABLE
56     #include <audio.h>
57 #endif
58
59 #ifdef BLUETOOTH_ENABLE
60     #include "bluetooth.h"
61 #endif
62
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;
67
68 static report_keyboard_t keyboard_report_sent;
69
70 #ifdef MIDI_ENABLE
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);
74 #endif
75
76 /* Host driver */
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 = {
83     keyboard_leds,
84     send_keyboard,
85     send_mouse,
86     send_system,
87     send_consumer,
88 #ifdef MIDI_ENABLE
89     usb_send_func,
90     usb_get_midi,
91     midi_usb_init
92 #endif
93 };
94
95 /*******************************************************************************
96  * MIDI
97  ******************************************************************************/
98
99 #ifdef MIDI_ENABLE
100 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
101 {
102   .Config =
103   {
104     .StreamingInterfaceNumber = AS_INTERFACE,
105     .DataINEndpoint           =
106     {
107       .Address          = MIDI_STREAM_IN_EPADDR,
108       .Size             = MIDI_STREAM_EPSIZE,
109       .Banks            = 1,
110     },
111     .DataOUTEndpoint          =
112     {
113       .Address          = MIDI_STREAM_OUT_EPADDR,
114       .Size             = MIDI_STREAM_EPSIZE,
115       .Banks            = 1,
116     },
117   },
118 };
119
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
124
125 #define SYS_COMMON_1 0x50
126 #define SYS_COMMON_2 0x20
127 #define SYS_COMMON_3 0x30
128 #endif
129
130
131 /*******************************************************************************
132  * Console
133  ******************************************************************************/
134 #ifdef CONSOLE_ENABLE
135 static void Console_Task(void)
136 {
137     /* Device must be connected and configured for the task to run */
138     if (USB_DeviceState != DEVICE_STATE_Configured)
139         return;
140
141     uint8_t ep = Endpoint_GetCurrentEndpoint();
142
143 #if 0
144     // TODO: impl receivechar()/recvchar()
145     Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
146
147     /* Check to see if a packet has been sent from the host */
148     if (Endpoint_IsOUTReceived())
149     {
150         /* Check to see if the packet contains data */
151         if (Endpoint_IsReadWriteAllowed())
152         {
153             /* Create a temporary buffer to hold the read in report from the host */
154             uint8_t ConsoleData[CONSOLE_EPSIZE];
155  
156             /* Read Console Report Data */
157             Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
158  
159             /* Process Console Report Data */
160             //ProcessConsoleHIDReport(ConsoleData);
161         }
162
163         /* Finalize the stream transfer to send the last packet */
164         Endpoint_ClearOUT();
165     }
166 #endif
167
168     /* IN packet */
169     Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
170     if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
171         Endpoint_SelectEndpoint(ep);
172         return;
173     }
174
175     // fill empty bank
176     while (Endpoint_IsReadWriteAllowed())
177         Endpoint_Write_8(0);
178
179     // flash senchar packet
180     if (Endpoint_IsINReady()) {
181         Endpoint_ClearIN();
182     }
183
184     Endpoint_SelectEndpoint(ep);
185 }
186 #else
187 static void Console_Task(void)
188 {
189 }
190 #endif
191
192
193 /*******************************************************************************
194  * USB Events
195  ******************************************************************************/
196 /*
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
202 */
203 void EVENT_USB_Device_Connect(void)
204 {
205     print("[C]");
206     /* For battery powered device */
207     if (!USB_IsInitialized) {
208         USB_Disable();
209         USB_Init();
210         USB_Device_EnableSOFEvents();
211     }
212 }
213
214 void EVENT_USB_Device_Disconnect(void)
215 {
216     print("[D]");
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);
224     }
225 */
226 }
227
228 void EVENT_USB_Device_Reset(void)
229 {
230     print("[R]");
231 }
232
233 void EVENT_USB_Device_Suspend()
234 {
235     print("[S]");
236 #ifdef SLEEP_LED_ENABLE
237     sleep_led_enable();
238 #endif
239 }
240
241 void EVENT_USB_Device_WakeUp()
242 {
243     print("[W]");
244     suspend_wakeup_init();
245
246 #ifdef SLEEP_LED_ENABLE
247     sleep_led_disable();
248     // NOTE: converters may not accept this
249     led_set(host_keyboard_leds());
250 #endif
251 }
252
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; \
257 } while (0)
258
259 // called every 1ms
260 void EVENT_USB_Device_StartOfFrame(void)
261 {
262     static uint8_t count;
263     if (++count % 50) return;
264     count = 0;
265
266     if (!console_flush) return;
267     Console_Task();
268     console_flush = false;
269 }
270 #endif
271
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.
274  *
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.
277  */
278 void EVENT_USB_Device_ConfigurationChanged(void)
279 {
280     bool ConfigSuccess = true;
281
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);
285
286 #ifdef MOUSE_ENABLE
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);
290 #endif
291
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);
296 #endif
297
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);
302 #if 0
303     ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
304                                      CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
305 #endif
306 #endif
307
308 #ifdef NKRO_ENABLE
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);
312 #endif
313
314 #ifdef MIDI_ENABLE
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);    
317 #endif
318 }
319
320 /*
321 Appendix G: HID Request Support Requirements
322
323 The following table enumerates the requests that need to be supported by various types of HID class devices.
324
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
332 */
333 /** Event handler for the USB_ControlRequest event.
334  *  This is fired before passing along unhandled control requests to the library for processing internally.
335  */
336 void EVENT_USB_Device_ControlRequest(void)
337 {
338     uint8_t* ReportData = NULL;
339     uint8_t  ReportSize = 0;
340
341     /* Handle HID Class specific requests */
342     switch (USB_ControlRequest.bRequest)
343     {
344         case HID_REQ_GetReport:
345             if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
346             {
347                 Endpoint_ClearSETUP();
348
349                 // Interface
350                 switch (USB_ControlRequest.wIndex) {
351                 case KEYBOARD_INTERFACE:
352                     // TODO: test/check
353                     ReportData = (uint8_t*)&keyboard_report_sent;
354                     ReportSize = sizeof(keyboard_report_sent);
355                     break;
356                 }
357
358                 /* Write the report data to the control endpoint */
359                 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
360                 Endpoint_ClearOUT();
361             }
362
363             break;
364         case HID_REQ_SetReport:
365             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
366             {
367
368                 // Interface
369                 switch (USB_ControlRequest.wIndex) {
370                 case KEYBOARD_INTERFACE:
371 #ifdef NKRO_ENABLE
372                 case NKRO_INTERFACE:
373 #endif
374                     Endpoint_ClearSETUP();
375
376                     while (!(Endpoint_IsOUTReceived())) {
377                         if (USB_DeviceState == DEVICE_STATE_Unattached)
378                           return;
379                     }
380                     keyboard_led_stats = Endpoint_Read_8();
381
382                     Endpoint_ClearOUT();
383                     Endpoint_ClearStatusStage();
384                     break;
385                 }
386
387             }
388
389             break;
390
391         case HID_REQ_GetProtocol:
392             if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
393             {
394                 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
395                     Endpoint_ClearSETUP();
396                     while (!(Endpoint_IsINReady()));
397                     Endpoint_Write_8(keyboard_protocol);
398                     Endpoint_ClearIN();
399                     Endpoint_ClearStatusStage();
400                 }
401             }
402
403             break;
404         case HID_REQ_SetProtocol:
405             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
406             {
407                 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
408                     Endpoint_ClearSETUP();
409                     Endpoint_ClearStatusStage();
410
411                     keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
412                     clear_keyboard();
413                 }
414             }
415
416             break;
417         case HID_REQ_SetIdle:
418             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
419             {
420                 Endpoint_ClearSETUP();
421                 Endpoint_ClearStatusStage();
422
423                 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
424             }
425
426             break;
427         case HID_REQ_GetIdle:
428             if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
429             {
430                 Endpoint_ClearSETUP();
431                 while (!(Endpoint_IsINReady()));
432                 Endpoint_Write_8(keyboard_idle);
433                 Endpoint_ClearIN();
434                 Endpoint_ClearStatusStage();
435             }
436
437             break;
438     }
439 }
440
441 /*******************************************************************************
442  * Host driver 
443  ******************************************************************************/
444 static uint8_t keyboard_leds(void)
445 {
446     return keyboard_led_stats;
447 }
448
449 static void send_keyboard(report_keyboard_t *report)
450 {
451
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]);
456     }
457 #endif
458
459     uint8_t timeout = 255;
460
461     if (USB_DeviceState != DEVICE_STATE_Configured)
462         return;
463
464     /* Select the Keyboard Report Endpoint */
465 #ifdef NKRO_ENABLE
466     if (keyboard_protocol && keyboard_nkro) {
467         /* Report protocol - NKRO */
468         Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
469
470         /* Check if write ready for a polling interval around 1ms */
471         while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
472         if (!Endpoint_IsReadWriteAllowed()) return;
473
474         /* Write Keyboard Report Data */
475         Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
476     }
477     else
478 #endif
479     {
480         /* Boot protocol */
481         Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
482
483         /* Check if write ready for a polling interval around 10ms */
484         while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
485         if (!Endpoint_IsReadWriteAllowed()) return;
486
487         /* Write Keyboard Report Data */
488         Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
489     }
490
491     /* Finalize the stream transfer to send the last packet */
492     Endpoint_ClearIN();
493
494     keyboard_report_sent = *report;
495 }
496
497 static void send_mouse(report_mouse_t *report)
498 {
499 #ifdef MOUSE_ENABLE
500
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);
511 #endif
512
513     uint8_t timeout = 255;
514
515     if (USB_DeviceState != DEVICE_STATE_Configured)
516         return;
517
518     /* Select the Mouse Report Endpoint */
519     Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
520
521     /* Check if write ready for a polling interval around 10ms */
522     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
523     if (!Endpoint_IsReadWriteAllowed()) return;
524
525     /* Write Mouse Report Data */
526     Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
527
528     /* Finalize the stream transfer to send the last packet */
529     Endpoint_ClearIN();
530 #endif
531 }
532
533 static void send_system(uint16_t data)
534 {
535     uint8_t timeout = 255;
536
537     if (USB_DeviceState != DEVICE_STATE_Configured)
538         return;
539
540     report_extra_t r = {
541         .report_id = REPORT_ID_SYSTEM,
542         .usage = data
543     };
544     Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
545
546     /* Check if write ready for a polling interval around 10ms */
547     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
548     if (!Endpoint_IsReadWriteAllowed()) return;
549
550     Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
551     Endpoint_ClearIN();
552 }
553
554 static void send_consumer(uint16_t data)
555 {
556
557 #ifdef BLUETOOTH_ENABLE
558     static uint16_t last_data = 0;
559     if (data == last_data) return;
560     last_data = data;
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);
571 #endif
572
573     uint8_t timeout = 255;
574
575     if (USB_DeviceState != DEVICE_STATE_Configured)
576         return;
577
578     report_extra_t r = {
579         .report_id = REPORT_ID_CONSUMER,
580         .usage = data
581     };
582     Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
583
584     /* Check if write ready for a polling interval around 10ms */
585     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
586     if (!Endpoint_IsReadWriteAllowed()) return;
587
588     Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
589     Endpoint_ClearIN();
590 }
591
592
593 /*******************************************************************************
594  * sendchar
595  ******************************************************************************/
596 #ifdef CONSOLE_ENABLE
597 #define SEND_TIMEOUT 5
598 int8_t sendchar(uint8_t c)
599 {
600     // Not wait once timeouted.
601     // Because sendchar() is called so many times, waiting each call causes big lag.
602     static bool timeouted = false;
603
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);
607
608     if (USB_DeviceState != DEVICE_STATE_Configured)
609         return -1;
610
611     uint8_t ep = Endpoint_GetCurrentEndpoint();
612     Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
613     if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
614         goto ERROR_EXIT;
615     }
616
617     if (timeouted && !Endpoint_IsReadWriteAllowed()) {
618         goto ERROR_EXIT;
619     }
620
621     timeouted = false;
622
623     uint8_t timeout = SEND_TIMEOUT;
624     while (!Endpoint_IsReadWriteAllowed()) {
625         if (USB_DeviceState != DEVICE_STATE_Configured) {
626             goto ERROR_EXIT;
627         }
628         if (Endpoint_IsStalled()) {
629             goto ERROR_EXIT;
630         }
631         if (!(timeout--)) {
632             timeouted = true;
633             goto ERROR_EXIT;
634         }
635         _delay_ms(1);
636     }
637
638     Endpoint_Write_8(c);
639
640     // send when bank is full
641     if (!Endpoint_IsReadWriteAllowed()) {
642         while (!(Endpoint_IsINReady()));
643         Endpoint_ClearIN();
644     } else {
645         CONSOLE_FLUSH_SET(true);
646     }
647
648     Endpoint_SelectEndpoint(ep);
649     return 0;
650 ERROR_EXIT:
651     Endpoint_SelectEndpoint(ep);
652     return -1;
653 }
654 #else
655 int8_t sendchar(uint8_t c)
656 {
657     return 0;
658 }
659 #endif
660
661 /*******************************************************************************
662  * MIDI
663  ******************************************************************************/
664
665 #ifdef MIDI_ENABLE
666 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
667   MIDI_EventPacket_t event;
668   event.Data1 = byte0;
669   event.Data2 = byte1;
670   event.Data3 = byte2;
671
672   uint8_t cable = 0;
673
674 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
675
676   //if the length is undefined we assume it is a SYSEX message
677   if (midi_packet_length(byte0) == UNDEFINED) {
678     switch(cnt) {
679       case 3:
680         if (byte2 == SYSEX_END)
681           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
682         else
683           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
684         break;
685       case 2:
686         if (byte1 == SYSEX_END)
687           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
688         else
689           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
690         break;
691       case 1:
692         if (byte0 == SYSEX_END)
693           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
694         else
695           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
696         break;
697       default:
698         return; //invalid cnt
699     }
700   } else {
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);
706         break;
707       case MIDI_SONGSELECT:
708       case MIDI_TC_QUARTERFRAME:
709         event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
710         break;
711       default:
712         event.Event = MIDI_EVENT(cable, byte0);
713         break;
714     }
715   }
716
717 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
718 // Endpoint_ClearIN();
719
720   MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
721   MIDI_Device_Flush(&USB_MIDI_Interface);
722   MIDI_Device_USBTask(&USB_MIDI_Interface);
723   USB_USBTask();
724 }
725
726 void usb_get_midi(MidiDevice * device) {
727   MIDI_EventPacket_t event;
728   while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
729
730     midi_packet_length_t length = midi_packet_length(event.Data1);
731     uint8_t input[3];
732     input[0] = event.Data1;
733     input[1] = event.Data2;
734     input[2] = event.Data3;
735     if (length == UNDEFINED) {
736       //sysex
737       if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
738         length = 3;
739       } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
740         length = 2;
741       } else if(event.Event ==  MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
742         length = 1;
743       } else {
744         //XXX what to do?
745       }
746     }
747
748     //pass the data to the device input function
749     if (length != UNDEFINED)
750       midi_device_input(device, length, input);
751   }
752   MIDI_Device_USBTask(&USB_MIDI_Interface);
753   USB_USBTask();
754 }
755
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);
760
761   SetupHardware();
762   sei();
763 }
764
765 void MIDI_Task(void)
766 {
767
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)
771       return;
772     dprint("continuing in MIDI_TASK\n");
773
774     Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
775
776     if (Endpoint_IsINReady())
777     {
778
779         dprint("Endpoint is ready\n");
780
781         uint8_t MIDICommand = 0;
782         uint8_t MIDIPitch;
783
784         /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
785         uint8_t Channel = MIDI_CHANNEL(1);
786
787         MIDICommand = MIDI_COMMAND_NOTE_ON;
788         MIDIPitch   = 0x3E;
789
790         /* Check if a MIDI command is to be sent */
791         if (MIDICommand)
792         {
793             dprint("Command exists\n");
794             MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
795                 {
796                     .Event       = MIDI_EVENT(0, MIDICommand),
797
798                     .Data1       = MIDICommand | Channel,
799                     .Data2       = MIDIPitch,
800                     .Data3       = MIDI_STANDARD_VELOCITY,
801                 };
802
803             /* Write the MIDI event packet to the endpoint */
804             Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
805
806             /* Send the data in the endpoint to the host */
807             Endpoint_ClearIN();
808         }
809     }
810
811
812     /* Select the MIDI OUT stream */
813     Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
814
815     /* Check if a MIDI command has been received */
816     if (Endpoint_IsOUTReceived())
817     {
818         MIDI_EventPacket_t MIDIEvent;
819
820         /* Read the MIDI event packet from the endpoint */
821         Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
822
823         /* If the endpoint is now empty, clear the bank */
824         if (!(Endpoint_BytesInEndpoint()))
825         {
826             /* Clear the endpoint ready for new packet */
827             Endpoint_ClearOUT();
828         }
829     }
830 }
831
832 #endif
833
834
835 /*******************************************************************************
836  * main
837  ******************************************************************************/
838 static void setup_mcu(void)
839 {
840     /* Disable watchdog if enabled by bootloader/fuses */
841     MCUSR &= ~(1 << WDRF);
842     wdt_disable();
843
844     /* Disable clock division */
845     clock_prescale_set(clock_div_1);
846 }
847
848 static void setup_usb(void)
849 {
850     // Leonardo needs. Without this USB device is not recognized.
851     USB_Disable();
852
853     USB_Init();
854
855     // for Console_Task
856     USB_Device_EnableSOFEvents();
857     print_set_sendchar(sendchar);
858 }
859
860
861 #ifdef MIDI_ENABLE
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);
868 #endif
869
870 int main(void)  __attribute__ ((weak));
871 int main(void)
872 {
873
874 #ifdef MIDI_ENABLE
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);
878 #endif
879
880     setup_mcu();
881     keyboard_setup();
882     setup_usb();
883     sei();
884
885 #ifdef MIDI_ENABLE
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);
889
890     init_notes();
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);
895 #endif
896
897 #ifdef BLUETOOTH_ENABLE
898     serial_init();
899 #endif
900
901     /* wait for USB startup & debug output */
902
903 #ifdef WAIT_FOR_USB
904     while (USB_DeviceState != DEVICE_STATE_Configured) {
905     #if defined(INTERRUPT_CONTROL_ENDPOINT)
906             ;
907     #else
908             USB_USBTask();
909     #endif
910     }
911     print("USB configured.\n");
912 #else
913     USB_USBTask();
914 #endif
915     /* init modules */
916     keyboard_init();
917     host_set_driver(&lufa_driver);
918 #ifdef SLEEP_LED_ENABLE
919     sleep_led_init();
920 #endif
921
922     print("Keyboard start.\n");
923     while (1) {
924         #ifndef BLUETOOTH_ENABLE
925         while (USB_DeviceState == DEVICE_STATE_Suspended) {
926             print("[s]");
927             suspend_power_down();
928             if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
929                     USB_Device_SendRemoteWakeup();
930             }
931         }
932         #endif
933
934 #ifdef MIDI_ENABLE
935         midi_device_process(&midi_device);
936         // MIDI_Task();
937 #endif
938         keyboard_task();
939
940 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
941         USB_USBTask();
942 #endif
943     }
944 }
945
946 #ifdef MIDI_ENABLE
947 void fallthrough_callback(MidiDevice * device,
948     uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
949
950 #ifdef AUDIO_ENABLE
951   if (cnt == 3) {
952     switch (byte0 & 0xF0) {
953         case MIDI_NOTEON:
954             play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
955             break;
956         case MIDI_NOTEOFF:
957             stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(byte1 & 0x7F)/12.0));
958             break;
959     }
960   }
961   if (byte0 == MIDI_STOP) {
962     stop_all_notes();
963   }
964 #endif
965 }
966
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);
971 }
972
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));
977 }
978 #endif