Merge remote-tracking branch 'remotes/jackhumbert/master' into personal_atomic_planck
[jackhill/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, -1.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, -1.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