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