Merge branch 'master' of github.com:jackhumbert/qmk_firmware into wu5y7
[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 #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 #if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE)
76 #include "rgblight.h"
77 #endif
78
79 #ifdef MIDI_ENABLE
80 #include "sysex_tools.h"
81 #endif
82
83 uint8_t keyboard_idle = 0;
84 /* 0: Boot Protocol, 1: Report Protocol(default) */
85 uint8_t keyboard_protocol = 1;
86 static uint8_t keyboard_led_stats = 0;
87
88 static report_keyboard_t keyboard_report_sent;
89
90 #ifdef MIDI_ENABLE
91 static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
92 static void usb_get_midi(MidiDevice * device);
93 static void midi_usb_init(MidiDevice * device);
94 #endif
95
96 /* Host driver */
97 static uint8_t keyboard_leds(void);
98 static void send_keyboard(report_keyboard_t *report);
99 static void send_mouse(report_mouse_t *report);
100 static void send_system(uint16_t data);
101 static void send_consumer(uint16_t data);
102 host_driver_t lufa_driver = {
103 keyboard_leds,
104 send_keyboard,
105 send_mouse,
106 send_system,
107 send_consumer,
108 #ifdef MIDI_ENABLE
109 usb_send_func,
110 usb_get_midi,
111 midi_usb_init
112 #endif
113 };
114
115 /*******************************************************************************
116 * MIDI
117 ******************************************************************************/
118
119 #ifdef MIDI_ENABLE
120 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
121 {
122 .Config =
123 {
124 .StreamingInterfaceNumber = AS_INTERFACE,
125 .DataINEndpoint =
126 {
127 .Address = MIDI_STREAM_IN_EPADDR,
128 .Size = MIDI_STREAM_EPSIZE,
129 .Banks = 1,
130 },
131 .DataOUTEndpoint =
132 {
133 .Address = MIDI_STREAM_OUT_EPADDR,
134 .Size = MIDI_STREAM_EPSIZE,
135 .Banks = 1,
136 },
137 },
138 };
139
140 #define SYSEX_START_OR_CONT 0x40
141 #define SYSEX_ENDS_IN_1 0x50
142 #define SYSEX_ENDS_IN_2 0x60
143 #define SYSEX_ENDS_IN_3 0x70
144
145 #define SYS_COMMON_1 0x50
146 #define SYS_COMMON_2 0x20
147 #define SYS_COMMON_3 0x30
148 #endif
149
150 #ifdef VIRTSER_ENABLE
151 USB_ClassInfo_CDC_Device_t cdc_device =
152 {
153 .Config =
154 {
155 .ControlInterfaceNumber = CCI_INTERFACE,
156 .DataINEndpoint =
157 {
158 .Address = CDC_IN_EPADDR,
159 .Size = CDC_EPSIZE,
160 .Banks = 1,
161 },
162 .DataOUTEndpoint =
163 {
164 .Address = CDC_OUT_EPADDR,
165 .Size = CDC_EPSIZE,
166 .Banks = 1,
167 },
168 .NotificationEndpoint =
169 {
170 .Address = CDC_NOTIFICATION_EPADDR,
171 .Size = CDC_NOTIFICATION_EPSIZE,
172 .Banks = 1,
173 },
174 },
175 };
176 #endif
177
178
179 /*******************************************************************************
180 * Console
181 ******************************************************************************/
182 #ifdef CONSOLE_ENABLE
183 static void Console_Task(void)
184 {
185 /* Device must be connected and configured for the task to run */
186 if (USB_DeviceState != DEVICE_STATE_Configured)
187 return;
188
189 uint8_t ep = Endpoint_GetCurrentEndpoint();
190
191 #if 0
192 // TODO: impl receivechar()/recvchar()
193 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
194
195 /* Check to see if a packet has been sent from the host */
196 if (Endpoint_IsOUTReceived())
197 {
198 /* Check to see if the packet contains data */
199 if (Endpoint_IsReadWriteAllowed())
200 {
201 /* Create a temporary buffer to hold the read in report from the host */
202 uint8_t ConsoleData[CONSOLE_EPSIZE];
203
204 /* Read Console Report Data */
205 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
206
207 /* Process Console Report Data */
208 //ProcessConsoleHIDReport(ConsoleData);
209 }
210
211 /* Finalize the stream transfer to send the last packet */
212 Endpoint_ClearOUT();
213 }
214 #endif
215
216 /* IN packet */
217 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
218 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
219 Endpoint_SelectEndpoint(ep);
220 return;
221 }
222
223 // fill empty bank
224 while (Endpoint_IsReadWriteAllowed())
225 Endpoint_Write_8(0);
226
227 // flash senchar packet
228 if (Endpoint_IsINReady()) {
229 Endpoint_ClearIN();
230 }
231
232 Endpoint_SelectEndpoint(ep);
233 }
234 #endif
235
236
237 /*******************************************************************************
238 * USB Events
239 ******************************************************************************/
240 /*
241 * Event Order of Plug in:
242 * 0) EVENT_USB_Device_Connect
243 * 1) EVENT_USB_Device_Suspend
244 * 2) EVENT_USB_Device_Reset
245 * 3) EVENT_USB_Device_Wake
246 */
247 void EVENT_USB_Device_Connect(void)
248 {
249 print("[C]");
250 /* For battery powered device */
251 if (!USB_IsInitialized) {
252 USB_Disable();
253 USB_Init();
254 USB_Device_EnableSOFEvents();
255 }
256 }
257
258 void EVENT_USB_Device_Disconnect(void)
259 {
260 print("[D]");
261 /* For battery powered device */
262 USB_IsInitialized = false;
263 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
264 if (USB_IsInitialized) {
265 USB_Disable(); // Disable all interrupts
266 USB_Controller_Enable();
267 USB_INT_Enable(USB_INT_VBUSTI);
268 }
269 */
270 }
271
272 void EVENT_USB_Device_Reset(void)
273 {
274 print("[R]");
275 }
276
277 void EVENT_USB_Device_Suspend()
278 {
279 print("[S]");
280 #ifdef SLEEP_LED_ENABLE
281 sleep_led_enable();
282 #endif
283 }
284
285 void EVENT_USB_Device_WakeUp()
286 {
287 print("[W]");
288 suspend_wakeup_init();
289
290 #ifdef SLEEP_LED_ENABLE
291 sleep_led_disable();
292 // NOTE: converters may not accept this
293 led_set(host_keyboard_leds());
294 #endif
295 }
296
297 #ifdef CONSOLE_ENABLE
298 static bool console_flush = false;
299 #define CONSOLE_FLUSH_SET(b) do { \
300 uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
301 } while (0)
302
303 // called every 1ms
304 void EVENT_USB_Device_StartOfFrame(void)
305 {
306 static uint8_t count;
307 if (++count % 50) return;
308 count = 0;
309
310 if (!console_flush) return;
311 Console_Task();
312 console_flush = false;
313 }
314 #endif
315
316 /** Event handler for the USB_ConfigurationChanged event.
317 * This is fired when the host sets the current configuration of the USB device after enumeration.
318 *
319 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
320 * it is safe to use singl bank for all endpoints.
321 */
322 void EVENT_USB_Device_ConfigurationChanged(void)
323 {
324 bool ConfigSuccess = true;
325
326 /* Setup Keyboard HID Report Endpoints */
327 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
328 KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
329
330 #ifdef MOUSE_ENABLE
331 /* Setup Mouse HID Report Endpoint */
332 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
333 MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
334 #endif
335
336 #ifdef EXTRAKEY_ENABLE
337 /* Setup Extra HID Report Endpoint */
338 ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
339 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
340 #endif
341
342 #ifdef CONSOLE_ENABLE
343 /* Setup Console HID Report Endpoints */
344 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
345 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
346 #if 0
347 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
348 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
349 #endif
350 #endif
351
352 #ifdef NKRO_ENABLE
353 /* Setup NKRO HID Report Endpoints */
354 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
355 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
356 #endif
357
358 #ifdef MIDI_ENABLE
359 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
360 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
361 #endif
362
363 #ifdef VIRTSER_ENABLE
364 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
365 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
366 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
367 #endif
368 }
369
370 /*
371 Appendix G: HID Request Support Requirements
372
373 The following table enumerates the requests that need to be supported by various types of HID class devices.
374
375 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
376 ------------------------------------------------------------------------------------------
377 Boot Mouse Required Optional Optional Optional Required Required
378 Non-Boot Mouse Required Optional Optional Optional Optional Optional
379 Boot Keyboard Required Optional Required Required Required Required
380 Non-Boot Keybrd Required Optional Required Required Optional Optional
381 Other Device Required Optional Optional Optional Optional Optional
382 */
383 /** Event handler for the USB_ControlRequest event.
384 * This is fired before passing along unhandled control requests to the library for processing internally.
385 */
386 void EVENT_USB_Device_ControlRequest(void)
387 {
388 uint8_t* ReportData = NULL;
389 uint8_t ReportSize = 0;
390
391 /* Handle HID Class specific requests */
392 switch (USB_ControlRequest.bRequest)
393 {
394 case HID_REQ_GetReport:
395 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
396 {
397 Endpoint_ClearSETUP();
398
399 // Interface
400 switch (USB_ControlRequest.wIndex) {
401 case KEYBOARD_INTERFACE:
402 // TODO: test/check
403 ReportData = (uint8_t*)&keyboard_report_sent;
404 ReportSize = sizeof(keyboard_report_sent);
405 break;
406 }
407
408 /* Write the report data to the control endpoint */
409 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
410 Endpoint_ClearOUT();
411 }
412
413 break;
414 case HID_REQ_SetReport:
415 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
416 {
417
418 // Interface
419 switch (USB_ControlRequest.wIndex) {
420 case KEYBOARD_INTERFACE:
421 #ifdef NKRO_ENABLE
422 case NKRO_INTERFACE:
423 #endif
424 Endpoint_ClearSETUP();
425
426 while (!(Endpoint_IsOUTReceived())) {
427 if (USB_DeviceState == DEVICE_STATE_Unattached)
428 return;
429 }
430 keyboard_led_stats = Endpoint_Read_8();
431
432 Endpoint_ClearOUT();
433 Endpoint_ClearStatusStage();
434 break;
435 }
436
437 }
438
439 break;
440
441 case HID_REQ_GetProtocol:
442 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
443 {
444 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
445 Endpoint_ClearSETUP();
446 while (!(Endpoint_IsINReady()));
447 Endpoint_Write_8(keyboard_protocol);
448 Endpoint_ClearIN();
449 Endpoint_ClearStatusStage();
450 }
451 }
452
453 break;
454 case HID_REQ_SetProtocol:
455 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
456 {
457 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
458 Endpoint_ClearSETUP();
459 Endpoint_ClearStatusStage();
460
461 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
462 clear_keyboard();
463 }
464 }
465
466 break;
467 case HID_REQ_SetIdle:
468 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
469 {
470 Endpoint_ClearSETUP();
471 Endpoint_ClearStatusStage();
472
473 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
474 }
475
476 break;
477 case HID_REQ_GetIdle:
478 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
479 {
480 Endpoint_ClearSETUP();
481 while (!(Endpoint_IsINReady()));
482 Endpoint_Write_8(keyboard_idle);
483 Endpoint_ClearIN();
484 Endpoint_ClearStatusStage();
485 }
486
487 break;
488 }
489
490 #ifdef VIRTSER_ENABLE
491 CDC_Device_ProcessControlRequest(&cdc_device);
492 #endif
493 }
494
495 /*******************************************************************************
496 * Host driver
497 p
498 ******************************************************************************/
499 static uint8_t keyboard_leds(void)
500 {
501 return keyboard_led_stats;
502 }
503
504 static void send_keyboard(report_keyboard_t *report)
505 {
506
507 #ifdef BLUETOOTH_ENABLE
508 bluefruit_serial_send(0xFD);
509 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
510 bluefruit_serial_send(report->raw[i]);
511 }
512 #endif
513
514 uint8_t timeout = 255;
515
516 if (USB_DeviceState != DEVICE_STATE_Configured)
517 return;
518
519 /* Select the Keyboard Report Endpoint */
520 #ifdef NKRO_ENABLE
521 if (keyboard_protocol && keymap_config.nkro) {
522 /* Report protocol - NKRO */
523 Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
524
525 /* Check if write ready for a polling interval around 1ms */
526 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
527 if (!Endpoint_IsReadWriteAllowed()) return;
528
529 /* Write Keyboard Report Data */
530 Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
531 }
532 else
533 #endif
534 {
535 /* Boot protocol */
536 Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
537
538 /* Check if write ready for a polling interval around 10ms */
539 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
540 if (!Endpoint_IsReadWriteAllowed()) return;
541
542 /* Write Keyboard Report Data */
543 Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
544 }
545
546 /* Finalize the stream transfer to send the last packet */
547 Endpoint_ClearIN();
548
549 keyboard_report_sent = *report;
550 }
551
552 static void send_mouse(report_mouse_t *report)
553 {
554 #ifdef MOUSE_ENABLE
555
556 #ifdef BLUETOOTH_ENABLE
557 bluefruit_serial_send(0xFD);
558 bluefruit_serial_send(0x00);
559 bluefruit_serial_send(0x03);
560 bluefruit_serial_send(report->buttons);
561 bluefruit_serial_send(report->x);
562 bluefruit_serial_send(report->y);
563 bluefruit_serial_send(report->v); // should try sending the wheel v here
564 bluefruit_serial_send(report->h); // should try sending the wheel h here
565 bluefruit_serial_send(0x00);
566 #endif
567
568 uint8_t timeout = 255;
569
570 if (USB_DeviceState != DEVICE_STATE_Configured)
571 return;
572
573 /* Select the Mouse Report Endpoint */
574 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
575
576 /* Check if write ready for a polling interval around 10ms */
577 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
578 if (!Endpoint_IsReadWriteAllowed()) return;
579
580 /* Write Mouse Report Data */
581 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
582
583 /* Finalize the stream transfer to send the last packet */
584 Endpoint_ClearIN();
585 #endif
586 }
587
588 static void send_system(uint16_t data)
589 {
590 uint8_t timeout = 255;
591
592 if (USB_DeviceState != DEVICE_STATE_Configured)
593 return;
594
595 report_extra_t r = {
596 .report_id = REPORT_ID_SYSTEM,
597 .usage = data
598 };
599 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
600
601 /* Check if write ready for a polling interval around 10ms */
602 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
603 if (!Endpoint_IsReadWriteAllowed()) return;
604
605 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
606 Endpoint_ClearIN();
607 }
608
609 static void send_consumer(uint16_t data)
610 {
611
612 #ifdef BLUETOOTH_ENABLE
613 static uint16_t last_data = 0;
614 if (data == last_data) return;
615 last_data = data;
616 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
617 bluefruit_serial_send(0xFD);
618 bluefruit_serial_send(0x00);
619 bluefruit_serial_send(0x02);
620 bluefruit_serial_send((bitmap>>8)&0xFF);
621 bluefruit_serial_send(bitmap&0xFF);
622 bluefruit_serial_send(0x00);
623 bluefruit_serial_send(0x00);
624 bluefruit_serial_send(0x00);
625 bluefruit_serial_send(0x00);
626 #endif
627
628 uint8_t timeout = 255;
629
630 if (USB_DeviceState != DEVICE_STATE_Configured)
631 return;
632
633 report_extra_t r = {
634 .report_id = REPORT_ID_CONSUMER,
635 .usage = data
636 };
637 Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
638
639 /* Check if write ready for a polling interval around 10ms */
640 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
641 if (!Endpoint_IsReadWriteAllowed()) return;
642
643 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
644 Endpoint_ClearIN();
645 }
646
647
648 /*******************************************************************************
649 * sendchar
650 ******************************************************************************/
651 #ifdef CONSOLE_ENABLE
652 #define SEND_TIMEOUT 5
653 int8_t sendchar(uint8_t c)
654 {
655 // Not wait once timeouted.
656 // Because sendchar() is called so many times, waiting each call causes big lag.
657 static bool timeouted = false;
658
659 // prevents Console_Task() from running during sendchar() runs.
660 // or char will be lost. These two function is mutually exclusive.
661 CONSOLE_FLUSH_SET(false);
662
663 if (USB_DeviceState != DEVICE_STATE_Configured)
664 return -1;
665
666 uint8_t ep = Endpoint_GetCurrentEndpoint();
667 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
668 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
669 goto ERROR_EXIT;
670 }
671
672 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
673 goto ERROR_EXIT;
674 }
675
676 timeouted = false;
677
678 uint8_t timeout = SEND_TIMEOUT;
679 while (!Endpoint_IsReadWriteAllowed()) {
680 if (USB_DeviceState != DEVICE_STATE_Configured) {
681 goto ERROR_EXIT;
682 }
683 if (Endpoint_IsStalled()) {
684 goto ERROR_EXIT;
685 }
686 if (!(timeout--)) {
687 timeouted = true;
688 goto ERROR_EXIT;
689 }
690 _delay_ms(1);
691 }
692
693 Endpoint_Write_8(c);
694
695 // send when bank is full
696 if (!Endpoint_IsReadWriteAllowed()) {
697 while (!(Endpoint_IsINReady()));
698 Endpoint_ClearIN();
699 } else {
700 CONSOLE_FLUSH_SET(true);
701 }
702
703 Endpoint_SelectEndpoint(ep);
704 return 0;
705 ERROR_EXIT:
706 Endpoint_SelectEndpoint(ep);
707 return -1;
708 }
709 #else
710 int8_t sendchar(uint8_t c)
711 {
712 return 0;
713 }
714 #endif
715
716 /*******************************************************************************
717 * MIDI
718 ******************************************************************************/
719
720 #ifdef MIDI_ENABLE
721 static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
722 MIDI_EventPacket_t event;
723 event.Data1 = byte0;
724 event.Data2 = byte1;
725 event.Data3 = byte2;
726
727 uint8_t cable = 0;
728
729 // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
730
731 //if the length is undefined we assume it is a SYSEX message
732 if (midi_packet_length(byte0) == UNDEFINED) {
733 switch(cnt) {
734 case 3:
735 if (byte2 == SYSEX_END)
736 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
737 else
738 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
739 break;
740 case 2:
741 if (byte1 == SYSEX_END)
742 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
743 else
744 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
745 break;
746 case 1:
747 if (byte0 == SYSEX_END)
748 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
749 else
750 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
751 break;
752 default:
753 return; //invalid cnt
754 }
755 } else {
756 //deal with 'system common' messages
757 //TODO are there any more?
758 switch(byte0 & 0xF0){
759 case MIDI_SONGPOSITION:
760 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
761 break;
762 case MIDI_SONGSELECT:
763 case MIDI_TC_QUARTERFRAME:
764 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
765 break;
766 default:
767 event.Event = MIDI_EVENT(cable, byte0);
768 break;
769 }
770 }
771
772 // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
773 // Endpoint_ClearIN();
774
775 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
776 MIDI_Device_Flush(&USB_MIDI_Interface);
777 MIDI_Device_USBTask(&USB_MIDI_Interface);
778 USB_USBTask();
779 }
780
781 static void usb_get_midi(MidiDevice * device) {
782 MIDI_EventPacket_t event;
783 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
784
785 midi_packet_length_t length = midi_packet_length(event.Data1);
786 uint8_t input[3];
787 input[0] = event.Data1;
788 input[1] = event.Data2;
789 input[2] = event.Data3;
790 if (length == UNDEFINED) {
791 //sysex
792 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
793 length = 3;
794 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
795 length = 2;
796 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
797 length = 1;
798 } else {
799 //XXX what to do?
800 }
801 }
802
803 //pass the data to the device input function
804 if (length != UNDEFINED)
805 midi_device_input(device, length, input);
806 }
807 MIDI_Device_USBTask(&USB_MIDI_Interface);
808 USB_USBTask();
809 }
810
811 static void midi_usb_init(MidiDevice * device){
812 midi_device_init(device);
813 midi_device_set_send_func(device, usb_send_func);
814 midi_device_set_pre_input_process_func(device, usb_get_midi);
815
816 // SetupHardware();
817 sei();
818 }
819
820 void MIDI_Task(void)
821 {
822
823 /* Device must be connected and configured for the task to run */
824 dprint("in MIDI_TASK\n");
825 if (USB_DeviceState != DEVICE_STATE_Configured)
826 return;
827 dprint("continuing in MIDI_TASK\n");
828
829 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
830
831 if (Endpoint_IsINReady())
832 {
833
834 dprint("Endpoint is ready\n");
835
836 uint8_t MIDICommand = 0;
837 uint8_t MIDIPitch;
838
839 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
840 uint8_t Channel = MIDI_CHANNEL(1);
841
842 MIDICommand = MIDI_COMMAND_NOTE_ON;
843 MIDIPitch = 0x3E;
844
845 /* Check if a MIDI command is to be sent */
846 if (MIDICommand)
847 {
848 dprint("Command exists\n");
849 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
850 {
851 .Event = MIDI_EVENT(0, MIDICommand),
852
853 .Data1 = MIDICommand | Channel,
854 .Data2 = MIDIPitch,
855 .Data3 = MIDI_STANDARD_VELOCITY,
856 };
857
858 /* Write the MIDI event packet to the endpoint */
859 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
860
861 /* Send the data in the endpoint to the host */
862 Endpoint_ClearIN();
863 }
864 }
865
866
867 /* Select the MIDI OUT stream */
868 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
869
870 /* Check if a MIDI command has been received */
871 if (Endpoint_IsOUTReceived())
872 {
873 MIDI_EventPacket_t MIDIEvent;
874
875 /* Read the MIDI event packet from the endpoint */
876 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
877
878 /* If the endpoint is now empty, clear the bank */
879 if (!(Endpoint_BytesInEndpoint()))
880 {
881 /* Clear the endpoint ready for new packet */
882 Endpoint_ClearOUT();
883 }
884 }
885 }
886
887 #endif
888
889 /*******************************************************************************
890 * VIRTUAL SERIAL
891 ******************************************************************************/
892
893 #ifdef VIRTSER_ENABLE
894 void virtser_init(void)
895 {
896 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ;
897 CDC_Device_SendControlLineStateChange(&cdc_device);
898 }
899
900 void virtser_recv(uint8_t c) __attribute__ ((weak));
901 void virtser_recv(uint8_t c)
902 {
903 // Ignore by default
904 }
905
906 void virtser_task(void)
907 {
908 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
909 uint8_t ch;
910 if (count)
911 {
912 ch = CDC_Device_ReceiveByte(&cdc_device);
913 virtser_recv(ch);
914 }
915 }
916 void virtser_send(const uint8_t byte)
917 {
918 uint8_t timeout = 255;
919 uint8_t ep = Endpoint_GetCurrentEndpoint();
920
921 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
922 {
923 /* IN packet */
924 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
925
926 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
927 Endpoint_SelectEndpoint(ep);
928 return;
929 }
930
931 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
932
933 Endpoint_Write_8(byte);
934 CDC_Device_Flush(&cdc_device);
935
936 if (Endpoint_IsINReady()) {
937 Endpoint_ClearIN();
938 }
939
940 Endpoint_SelectEndpoint(ep);
941 }
942 }
943 #endif
944
945 /*******************************************************************************
946 * main
947 ******************************************************************************/
948 static void setup_mcu(void)
949 {
950 /* Disable watchdog if enabled by bootloader/fuses */
951 MCUSR &= ~(1 << WDRF);
952 wdt_disable();
953
954 /* Disable clock division */
955 // clock_prescale_set(clock_div_1);
956
957 CLKPR = (1 << CLKPCE);
958 CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
959 }
960
961 static void setup_usb(void)
962 {
963 // Leonardo needs. Without this USB device is not recognized.
964 USB_Disable();
965
966 USB_Init();
967
968 // for Console_Task
969 USB_Device_EnableSOFEvents();
970 print_set_sendchar(sendchar);
971 }
972
973
974 #ifdef MIDI_ENABLE
975 void fallthrough_callback(MidiDevice * device,
976 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
977 void cc_callback(MidiDevice * device,
978 uint8_t chan, uint8_t num, uint8_t val);
979 void sysex_callback(MidiDevice * device,
980 uint16_t start, uint8_t length, uint8_t * data);
981 #endif
982
983 int main(void) __attribute__ ((weak));
984 int main(void)
985 {
986
987 #ifdef MIDI_ENABLE
988 midi_device_init(&midi_device);
989 midi_device_set_send_func(&midi_device, usb_send_func);
990 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
991 #endif
992
993 setup_mcu();
994 keyboard_setup();
995 setup_usb();
996 sei();
997
998 #ifdef MIDI_ENABLE
999 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
1000 midi_register_cc_callback(&midi_device, cc_callback);
1001 midi_register_sysex_callback(&midi_device, sysex_callback);
1002
1003 // init_notes();
1004 // midi_send_cc(&midi_device, 0, 1, 2);
1005 // midi_send_cc(&midi_device, 15, 1, 0);
1006 // midi_send_noteon(&midi_device, 0, 64, 127);
1007 // midi_send_noteoff(&midi_device, 0, 64, 127);
1008 #endif
1009
1010 #ifdef BLUETOOTH_ENABLE
1011 serial_init();
1012 #endif
1013
1014 /* wait for USB startup & debug output */
1015
1016 #ifdef WAIT_FOR_USB
1017 while (USB_DeviceState != DEVICE_STATE_Configured) {
1018 #if defined(INTERRUPT_CONTROL_ENDPOINT)
1019 ;
1020 #else
1021 USB_USBTask();
1022 #endif
1023 }
1024 print("USB configured.\n");
1025 #else
1026 USB_USBTask();
1027 #endif
1028 /* init modules */
1029 keyboard_init();
1030 host_set_driver(&lufa_driver);
1031 #ifdef SLEEP_LED_ENABLE
1032 sleep_led_init();
1033 #endif
1034
1035 #ifdef VIRTSER_ENABLE
1036 virtser_init();
1037 #endif
1038
1039 print("Keyboard start.\n");
1040 while (1) {
1041 #ifndef BLUETOOTH_ENABLE
1042 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1043 print("[s]");
1044 suspend_power_down();
1045 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1046 USB_Device_SendRemoteWakeup();
1047 }
1048 }
1049 #endif
1050
1051 keyboard_task();
1052
1053 #ifdef MIDI_ENABLE
1054 midi_device_process(&midi_device);
1055 // MIDI_Task();
1056 #endif
1057
1058 #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
1059 rgblight_task();
1060 #endif
1061
1062 #ifdef VIRTSER_ENABLE
1063 virtser_task();
1064 CDC_Device_USBTask(&cdc_device);
1065 #endif
1066
1067 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1068 USB_USBTask();
1069 #endif
1070 }
1071 }
1072
1073 #ifdef MIDI_ENABLE
1074 void fallthrough_callback(MidiDevice * device,
1075 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
1076
1077 #ifdef AUDIO_ENABLE
1078 if (cnt == 3) {
1079 switch (byte0 & 0xF0) {
1080 case MIDI_NOTEON:
1081 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1082 break;
1083 case MIDI_NOTEOFF:
1084 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1085 break;
1086 }
1087 }
1088 if (byte0 == MIDI_STOP) {
1089 stop_all_notes();
1090 }
1091 #endif
1092 }
1093
1094
1095 void cc_callback(MidiDevice * device,
1096 uint8_t chan, uint8_t num, uint8_t val) {
1097 //sending it back on the next channel
1098 // midi_send_cc(device, (chan + 1) % 16, num, val);
1099 }
1100
1101 uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
1102
1103 void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
1104 #ifdef API_SYSEX_ENABLE
1105 // SEND_STRING("\n");
1106 // send_word(start);
1107 // SEND_STRING(": ");
1108 for (uint8_t place = 0; place < length; place++) {
1109 // send_byte(*data);
1110 midi_buffer[start + place] = *data;
1111 if (*data == 0xF7) {
1112 // SEND_STRING("\nRD: ");
1113 // for (uint8_t i = 0; i < start + place + 1; i++){
1114 // send_byte(midi_buffer[i]);
1115 // SEND_STRING(" ");
1116 // }
1117 uint8_t * decoded = malloc(sizeof(uint8_t) * (sysex_decoded_length(start + place - 4)));
1118 uint16_t decode_length = sysex_decode(decoded, midi_buffer + 4, start + place - 4);
1119 process_api(decode_length, decoded);
1120 }
1121 // SEND_STRING(" ");
1122 data++;
1123 }
1124 #endif
1125 }
1126
1127
1128 #endif