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