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