]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/lufa/lufa.c
updates midi in play_note to better octave
[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 #endif
187
188
189 /*******************************************************************************
190  * USB Events
191  ******************************************************************************/
192 /*
193  * Event Order of Plug in:
194  * 0) EVENT_USB_Device_Connect
195  * 1) EVENT_USB_Device_Suspend
196  * 2) EVENT_USB_Device_Reset
197  * 3) EVENT_USB_Device_Wake
198 */
199 void EVENT_USB_Device_Connect(void)
200 {
201     print("[C]");
202     /* For battery powered device */
203     if (!USB_IsInitialized) {
204         USB_Disable();
205         USB_Init();
206         USB_Device_EnableSOFEvents();
207     }
208 }
209
210 void EVENT_USB_Device_Disconnect(void)
211 {
212     print("[D]");
213     /* For battery powered device */
214     USB_IsInitialized = false;
215 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
216     if (USB_IsInitialized) {
217         USB_Disable();  // Disable all interrupts
218         USB_Controller_Enable();
219         USB_INT_Enable(USB_INT_VBUSTI);
220     }
221 */
222 }
223
224 void EVENT_USB_Device_Reset(void)
225 {
226     print("[R]");
227 }
228
229 void EVENT_USB_Device_Suspend()
230 {
231     print("[S]");
232 #ifdef SLEEP_LED_ENABLE
233     sleep_led_enable();
234 #endif
235 }
236
237 void EVENT_USB_Device_WakeUp()
238 {
239     print("[W]");
240     suspend_wakeup_init();
241
242 #ifdef SLEEP_LED_ENABLE
243     sleep_led_disable();
244     // NOTE: converters may not accept this
245     led_set(host_keyboard_leds());
246 #endif
247 }
248
249 #ifdef CONSOLE_ENABLE
250 static bool console_flush = false;
251 #define CONSOLE_FLUSH_SET(b)   do { \
252     uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
253 } while (0)
254
255 // called every 1ms
256 void EVENT_USB_Device_StartOfFrame(void)
257 {
258     static uint8_t count;
259     if (++count % 50) return;
260     count = 0;
261
262     if (!console_flush) return;
263     Console_Task();
264     console_flush = false;
265 }
266 #endif
267
268 /** Event handler for the USB_ConfigurationChanged event.
269  * This is fired when the host sets the current configuration of the USB device after enumeration.
270  *
271  * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
272  * it is safe to use singl bank for all endpoints.
273  */
274 void EVENT_USB_Device_ConfigurationChanged(void)
275 {
276     bool ConfigSuccess = true;
277
278     /* Setup Keyboard HID Report Endpoints */
279     ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
280                                      KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
281
282 #ifdef MOUSE_ENABLE
283     /* Setup Mouse HID Report Endpoint */
284     ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
285                                      MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
286 #endif
287
288 #ifdef EXTRAKEY_ENABLE
289     /* Setup Extra HID Report Endpoint */
290     ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
291                                      EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
292 #endif
293
294 #ifdef CONSOLE_ENABLE
295     /* Setup Console HID Report Endpoints */
296     ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
297                                      CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
298 #if 0
299     ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
300                                      CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
301 #endif
302 #endif
303
304 #ifdef NKRO_ENABLE
305     /* Setup NKRO HID Report Endpoints */
306     ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
307                                      NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
308 #endif
309
310 #ifdef MIDI_ENABLE
311     ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
312     ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
313 #endif
314 }
315
316 /*
317 Appendix G: HID Request Support Requirements
318
319 The following table enumerates the requests that need to be supported by various types of HID class devices.
320
321 Device type     GetReport   SetReport   GetIdle     SetIdle     GetProtocol SetProtocol
322 ------------------------------------------------------------------------------------------
323 Boot Mouse      Required    Optional    Optional    Optional    Required    Required
324 Non-Boot Mouse  Required    Optional    Optional    Optional    Optional    Optional
325 Boot Keyboard   Required    Optional    Required    Required    Required    Required
326 Non-Boot Keybrd Required    Optional    Required    Required    Optional    Optional
327 Other Device    Required    Optional    Optional    Optional    Optional    Optional
328 */
329 /** Event handler for the USB_ControlRequest event.
330  *  This is fired before passing along unhandled control requests to the library for processing internally.
331  */
332 void EVENT_USB_Device_ControlRequest(void)
333 {
334     uint8_t* ReportData = NULL;
335     uint8_t  ReportSize = 0;
336
337     /* Handle HID Class specific requests */
338     switch (USB_ControlRequest.bRequest)
339     {
340         case HID_REQ_GetReport:
341             if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
342             {
343                 Endpoint_ClearSETUP();
344
345                 // Interface
346                 switch (USB_ControlRequest.wIndex) {
347                 case KEYBOARD_INTERFACE:
348                     // TODO: test/check
349                     ReportData = (uint8_t*)&keyboard_report_sent;
350                     ReportSize = sizeof(keyboard_report_sent);
351                     break;
352                 }
353
354                 /* Write the report data to the control endpoint */
355                 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
356                 Endpoint_ClearOUT();
357             }
358
359             break;
360         case HID_REQ_SetReport:
361             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
362             {
363
364                 // Interface
365                 switch (USB_ControlRequest.wIndex) {
366                 case KEYBOARD_INTERFACE:
367 #ifdef NKRO_ENABLE
368                 case NKRO_INTERFACE:
369 #endif
370                     Endpoint_ClearSETUP();
371
372                     while (!(Endpoint_IsOUTReceived())) {
373                         if (USB_DeviceState == DEVICE_STATE_Unattached)
374                           return;
375                     }
376                     keyboard_led_stats = Endpoint_Read_8();
377
378                     Endpoint_ClearOUT();
379                     Endpoint_ClearStatusStage();
380                     break;
381                 }
382
383             }
384
385             break;
386
387         case HID_REQ_GetProtocol:
388             if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
389             {
390                 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
391                     Endpoint_ClearSETUP();
392                     while (!(Endpoint_IsINReady()));
393                     Endpoint_Write_8(keyboard_protocol);
394                     Endpoint_ClearIN();
395                     Endpoint_ClearStatusStage();
396                 }
397             }
398
399             break;
400         case HID_REQ_SetProtocol:
401             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
402             {
403                 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
404                     Endpoint_ClearSETUP();
405                     Endpoint_ClearStatusStage();
406
407                     keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
408                     clear_keyboard();
409                 }
410             }
411
412             break;
413         case HID_REQ_SetIdle:
414             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
415             {
416                 Endpoint_ClearSETUP();
417                 Endpoint_ClearStatusStage();
418
419                 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
420             }
421
422             break;
423         case HID_REQ_GetIdle:
424             if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
425             {
426                 Endpoint_ClearSETUP();
427                 while (!(Endpoint_IsINReady()));
428                 Endpoint_Write_8(keyboard_idle);
429                 Endpoint_ClearIN();
430                 Endpoint_ClearStatusStage();
431             }
432
433             break;
434     }
435 }
436
437 /*******************************************************************************
438  * Host driver
439  ******************************************************************************/
440 static uint8_t keyboard_leds(void)
441 {
442     return keyboard_led_stats;
443 }
444
445 static void send_keyboard(report_keyboard_t *report)
446 {
447
448 #ifdef BLUETOOTH_ENABLE
449     bluefruit_serial_send(0xFD);
450     for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
451         bluefruit_serial_send(report->raw[i]);
452     }
453 #endif
454
455     uint8_t timeout = 255;
456
457     if (USB_DeviceState != DEVICE_STATE_Configured)
458         return;
459
460     /* Select the Keyboard Report Endpoint */
461 #ifdef NKRO_ENABLE
462     if (keyboard_protocol && keyboard_nkro) {
463         /* Report protocol - NKRO */
464         Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
465
466         /* Check if write ready for a polling interval around 1ms */
467         while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
468         if (!Endpoint_IsReadWriteAllowed()) return;
469
470         /* Write Keyboard Report Data */
471         Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
472     }
473     else
474 #endif
475     {
476         /* Boot protocol */
477         Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
478
479         /* Check if write ready for a polling interval around 10ms */
480         while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
481         if (!Endpoint_IsReadWriteAllowed()) return;
482
483         /* Write Keyboard Report Data */
484         Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
485     }
486
487     /* Finalize the stream transfer to send the last packet */
488     Endpoint_ClearIN();
489
490     keyboard_report_sent = *report;
491 }
492
493 static void send_mouse(report_mouse_t *report)
494 {
495 #ifdef MOUSE_ENABLE
496
497 #ifdef BLUETOOTH_ENABLE
498     bluefruit_serial_send(0xFD);
499     bluefruit_serial_send(0x00);
500     bluefruit_serial_send(0x03);
501     bluefruit_serial_send(report->buttons);
502     bluefruit_serial_send(report->x);
503     bluefruit_serial_send(report->y);
504     bluefruit_serial_send(report->v); // should try sending the wheel v here
505     bluefruit_serial_send(report->h); // should try sending the wheel h here
506     bluefruit_serial_send(0x00);
507 #endif
508
509     uint8_t timeout = 255;
510
511     if (USB_DeviceState != DEVICE_STATE_Configured)
512         return;
513
514     /* Select the Mouse Report Endpoint */
515     Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
516
517     /* Check if write ready for a polling interval around 10ms */
518     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
519     if (!Endpoint_IsReadWriteAllowed()) return;
520
521     /* Write Mouse Report Data */
522     Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
523
524     /* Finalize the stream transfer to send the last packet */
525     Endpoint_ClearIN();
526 #endif
527 }
528
529 static void send_system(uint16_t data)
530 {
531     uint8_t timeout = 255;
532
533     if (USB_DeviceState != DEVICE_STATE_Configured)
534         return;
535
536     report_extra_t r = {
537         .report_id = REPORT_ID_SYSTEM,
538         .usage = data
539     };
540     Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
541
542     /* Check if write ready for a polling interval around 10ms */
543     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
544     if (!Endpoint_IsReadWriteAllowed()) return;
545
546     Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
547     Endpoint_ClearIN();
548 }
549
550 static void send_consumer(uint16_t data)
551 {
552
553 #ifdef BLUETOOTH_ENABLE
554     static uint16_t last_data = 0;
555     if (data == last_data) return;
556     last_data = data;
557     uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
558     bluefruit_serial_send(0xFD);
559     bluefruit_serial_send(0x00);
560     bluefruit_serial_send(0x02);
561     bluefruit_serial_send((bitmap>>8)&0xFF);
562     bluefruit_serial_send(bitmap&0xFF);
563     bluefruit_serial_send(0x00);
564     bluefruit_serial_send(0x00);
565     bluefruit_serial_send(0x00);
566     bluefruit_serial_send(0x00);
567 #endif
568
569     uint8_t timeout = 255;
570
571     if (USB_DeviceState != DEVICE_STATE_Configured)
572         return;
573
574     report_extra_t r = {
575         .report_id = REPORT_ID_CONSUMER,
576         .usage = data
577     };
578     Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
579
580     /* Check if write ready for a polling interval around 10ms */
581     while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
582     if (!Endpoint_IsReadWriteAllowed()) return;
583
584     Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
585     Endpoint_ClearIN();
586 }
587
588
589 /*******************************************************************************
590  * sendchar
591  ******************************************************************************/
592 #ifdef CONSOLE_ENABLE
593 #define SEND_TIMEOUT 5
594 int8_t sendchar(uint8_t c)
595 {
596     // Not wait once timeouted.
597     // Because sendchar() is called so many times, waiting each call causes big lag.
598     static bool timeouted = false;
599
600     // prevents Console_Task() from running during sendchar() runs.
601     // or char will be lost. These two function is mutually exclusive.
602     CONSOLE_FLUSH_SET(false);
603
604     if (USB_DeviceState != DEVICE_STATE_Configured)
605         return -1;
606
607     uint8_t ep = Endpoint_GetCurrentEndpoint();
608     Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
609     if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
610         goto ERROR_EXIT;
611     }
612
613     if (timeouted && !Endpoint_IsReadWriteAllowed()) {
614         goto ERROR_EXIT;
615     }
616
617     timeouted = false;
618
619     uint8_t timeout = SEND_TIMEOUT;
620     while (!Endpoint_IsReadWriteAllowed()) {
621         if (USB_DeviceState != DEVICE_STATE_Configured) {
622             goto ERROR_EXIT;
623         }
624         if (Endpoint_IsStalled()) {
625             goto ERROR_EXIT;
626         }
627         if (!(timeout--)) {
628             timeouted = true;
629             goto ERROR_EXIT;
630         }
631         _delay_ms(1);
632     }
633
634     Endpoint_Write_8(c);
635
636     // send when bank is full
637     if (!Endpoint_IsReadWriteAllowed()) {
638         while (!(Endpoint_IsINReady()));
639         Endpoint_ClearIN();
640     } else {
641         CONSOLE_FLUSH_SET(true);
642     }
643
644     Endpoint_SelectEndpoint(ep);
645     return 0;
646 ERROR_EXIT:
647     Endpoint_SelectEndpoint(ep);
648     return -1;
649 }
650 #else
651 int8_t sendchar(uint8_t c)
652 {
653     return 0;
654 }
655 #endif
656
657 /*******************************************************************************
658  * MIDI
659  ******************************************************************************/
660
661 #ifdef MIDI_ENABLE
662 void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
663   MIDI_EventPacket_t event;
664   event.Data1 = byte0;
665   event.Data2 = byte1;
666   event.Data3 = byte2;
667
668   uint8_t cable = 0;
669
670 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
671
672   //if the length is undefined we assume it is a SYSEX message
673   if (midi_packet_length(byte0) == UNDEFINED) {
674     switch(cnt) {
675       case 3:
676         if (byte2 == SYSEX_END)
677           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
678         else
679           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
680         break;
681       case 2:
682         if (byte1 == SYSEX_END)
683           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
684         else
685           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
686         break;
687       case 1:
688         if (byte0 == SYSEX_END)
689           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
690         else
691           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
692         break;
693       default:
694         return; //invalid cnt
695     }
696   } else {
697     //deal with 'system common' messages
698     //TODO are there any more?
699     switch(byte0 & 0xF0){
700       case MIDI_SONGPOSITION:
701         event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
702         break;
703       case MIDI_SONGSELECT:
704       case MIDI_TC_QUARTERFRAME:
705         event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
706         break;
707       default:
708         event.Event = MIDI_EVENT(cable, byte0);
709         break;
710     }
711   }
712
713 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
714 // Endpoint_ClearIN();
715
716   MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
717   MIDI_Device_Flush(&USB_MIDI_Interface);
718   MIDI_Device_USBTask(&USB_MIDI_Interface);
719   USB_USBTask();
720 }
721
722 void usb_get_midi(MidiDevice * device) {
723   MIDI_EventPacket_t event;
724   while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
725
726     midi_packet_length_t length = midi_packet_length(event.Data1);
727     uint8_t input[3];
728     input[0] = event.Data1;
729     input[1] = event.Data2;
730     input[2] = event.Data3;
731     if (length == UNDEFINED) {
732       //sysex
733       if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
734         length = 3;
735       } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
736         length = 2;
737       } else if(event.Event ==  MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
738         length = 1;
739       } else {
740         //XXX what to do?
741       }
742     }
743
744     //pass the data to the device input function
745     if (length != UNDEFINED)
746       midi_device_input(device, length, input);
747   }
748   MIDI_Device_USBTask(&USB_MIDI_Interface);
749   USB_USBTask();
750 }
751
752 void midi_usb_init(MidiDevice * device){
753   midi_device_init(device);
754   midi_device_set_send_func(device, usb_send_func);
755   midi_device_set_pre_input_process_func(device, usb_get_midi);
756
757   SetupHardware();
758   sei();
759 }
760
761 void MIDI_Task(void)
762 {
763
764     /* Device must be connected and configured for the task to run */
765     dprint("in MIDI_TASK\n");
766     if (USB_DeviceState != DEVICE_STATE_Configured)
767       return;
768     dprint("continuing in MIDI_TASK\n");
769
770     Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
771
772     if (Endpoint_IsINReady())
773     {
774
775         dprint("Endpoint is ready\n");
776
777         uint8_t MIDICommand = 0;
778         uint8_t MIDIPitch;
779
780         /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
781         uint8_t Channel = MIDI_CHANNEL(1);
782
783         MIDICommand = MIDI_COMMAND_NOTE_ON;
784         MIDIPitch   = 0x3E;
785
786         /* Check if a MIDI command is to be sent */
787         if (MIDICommand)
788         {
789             dprint("Command exists\n");
790             MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
791                 {
792                     .Event       = MIDI_EVENT(0, MIDICommand),
793
794                     .Data1       = MIDICommand | Channel,
795                     .Data2       = MIDIPitch,
796                     .Data3       = MIDI_STANDARD_VELOCITY,
797                 };
798
799             /* Write the MIDI event packet to the endpoint */
800             Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
801
802             /* Send the data in the endpoint to the host */
803             Endpoint_ClearIN();
804         }
805     }
806
807
808     /* Select the MIDI OUT stream */
809     Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
810
811     /* Check if a MIDI command has been received */
812     if (Endpoint_IsOUTReceived())
813     {
814         MIDI_EventPacket_t MIDIEvent;
815
816         /* Read the MIDI event packet from the endpoint */
817         Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
818
819         /* If the endpoint is now empty, clear the bank */
820         if (!(Endpoint_BytesInEndpoint()))
821         {
822             /* Clear the endpoint ready for new packet */
823             Endpoint_ClearOUT();
824         }
825     }
826 }
827
828 #endif
829
830
831 /*******************************************************************************
832  * main
833  ******************************************************************************/
834 static void setup_mcu(void)
835 {
836     /* Disable watchdog if enabled by bootloader/fuses */
837     MCUSR &= ~(1 << WDRF);
838     wdt_disable();
839
840     /* Disable clock division */
841     clock_prescale_set(clock_div_1);
842 }
843
844 static void setup_usb(void)
845 {
846     // Leonardo needs. Without this USB device is not recognized.
847     USB_Disable();
848
849     USB_Init();
850
851     // for Console_Task
852     USB_Device_EnableSOFEvents();
853     print_set_sendchar(sendchar);
854 }
855
856
857 #ifdef MIDI_ENABLE
858 void fallthrough_callback(MidiDevice * device,
859     uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
860 void cc_callback(MidiDevice * device,
861     uint8_t chan, uint8_t num, uint8_t val);
862 void sysex_callback(MidiDevice * device,
863     uint16_t start, uint8_t length, uint8_t * data);
864 #endif
865
866 int main(void)  __attribute__ ((weak));
867 int main(void)
868 {
869
870 #ifdef MIDI_ENABLE
871     midi_device_init(&midi_device);
872     midi_device_set_send_func(&midi_device, usb_send_func);
873     midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
874 #endif
875
876     setup_mcu();
877     keyboard_setup();
878     setup_usb();
879     sei();
880
881 #ifdef MIDI_ENABLE
882     midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
883     midi_register_cc_callback(&midi_device, cc_callback);
884     midi_register_sysex_callback(&midi_device, sysex_callback);
885
886     // init_notes();
887     // midi_send_cc(&midi_device, 0, 1, 2);
888     // midi_send_cc(&midi_device, 15, 1, 0);
889     // midi_send_noteon(&midi_device, 0, 64, 127);
890     // midi_send_noteoff(&midi_device, 0, 64, 127);
891 #endif
892
893 #ifdef BLUETOOTH_ENABLE
894     serial_init();
895 #endif
896
897     /* wait for USB startup & debug output */
898
899 #ifdef WAIT_FOR_USB
900     while (USB_DeviceState != DEVICE_STATE_Configured) {
901     #if defined(INTERRUPT_CONTROL_ENDPOINT)
902             ;
903     #else
904             USB_USBTask();
905     #endif
906     }
907     print("USB configured.\n");
908 #else
909     USB_USBTask();
910 #endif
911     /* init modules */
912     keyboard_init();
913     host_set_driver(&lufa_driver);
914 #ifdef SLEEP_LED_ENABLE
915     sleep_led_init();
916 #endif
917
918     print("Keyboard start.\n");
919     while (1) {
920         #ifndef BLUETOOTH_ENABLE
921         while (USB_DeviceState == DEVICE_STATE_Suspended) {
922             print("[s]");
923             suspend_power_down();
924             if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
925                     USB_Device_SendRemoteWakeup();
926             }
927         }
928         #endif
929
930 #ifdef MIDI_ENABLE
931         midi_device_process(&midi_device);
932         // MIDI_Task();
933 #endif
934         keyboard_task();
935
936 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
937         USB_USBTask();
938 #endif
939     }
940 }
941
942 #ifdef MIDI_ENABLE
943 void fallthrough_callback(MidiDevice * device,
944     uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
945
946 #ifdef AUDIO_ENABLE
947   if (cnt == 3) {
948     switch (byte0 & 0xF0) {
949         case MIDI_NOTEON:
950             play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
951             break;
952         case MIDI_NOTEOFF:
953             stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
954             break;
955     }
956   }
957   if (byte0 == MIDI_STOP) {
958     stop_all_notes();
959   }
960 #endif
961 }
962
963 void cc_callback(MidiDevice * device,
964     uint8_t chan, uint8_t num, uint8_t val) {
965   //sending it back on the next channel
966   midi_send_cc(device, (chan + 1) % 16, num, val);
967 }
968
969 void sysex_callback(MidiDevice * device,
970     uint16_t start, uint8_t length, uint8_t * data) {
971   for (int i = 0; i < length; i++)
972     midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));
973 }
974 #endif