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