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