aboutsummaryrefslogtreecommitdiff
path: root/protocol/lufa/lufa.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocol/lufa/lufa.c')
-rw-r--r--protocol/lufa/lufa.c191
1 files changed, 189 insertions, 2 deletions
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index cdfc7bc6a..d4c8eb169 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -52,6 +52,7 @@
52#include "descriptor.h" 52#include "descriptor.h"
53#include "lufa.h" 53#include "lufa.h"
54 54
55
55uint8_t keyboard_idle = 0; 56uint8_t keyboard_idle = 0;
56uint8_t keyboard_protocol = 1; 57uint8_t keyboard_protocol = 1;
57static uint8_t keyboard_led_stats = 0; 58static uint8_t keyboard_led_stats = 0;
@@ -65,14 +66,51 @@ static void send_keyboard(report_keyboard_t *report);
65static void send_mouse(report_mouse_t *report); 66static void send_mouse(report_mouse_t *report);
66static void send_system(uint16_t data); 67static void send_system(uint16_t data);
67static void send_consumer(uint16_t data); 68static void send_consumer(uint16_t data);
69void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
70void usb_get_midi(MidiDevice * device);
71void midi_usb_init(MidiDevice * device);
68host_driver_t lufa_driver = { 72host_driver_t lufa_driver = {
69 keyboard_leds, 73 keyboard_leds,
70 send_keyboard, 74 send_keyboard,
71 send_mouse, 75 send_mouse,
72 send_system, 76 send_system,
73 send_consumer 77 send_consumer,
78 usb_send_func,
79 usb_get_midi,
80 midi_usb_init
81};
82
83void SetupHardware(void);
84
85USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
86{
87 .Config =
88 {
89 .StreamingInterfaceNumber = 1,
90 .DataINEndpoint =
91 {
92 .Address = (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM),
93 .Size = MIDI_STREAM_EPSIZE,
94 .Banks = 1,
95 },
96 .DataOUTEndpoint =
97 {
98 .Address = (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM),
99 .Size = MIDI_STREAM_EPSIZE,
100 .Banks = 1,
101 },
102 },
74}; 103};
75 104
105#define SYSEX_START_OR_CONT 0x40
106#define SYSEX_ENDS_IN_1 0x50
107#define SYSEX_ENDS_IN_2 0x60
108#define SYSEX_ENDS_IN_3 0x70
109
110#define SYS_COMMON_1 0x50
111#define SYS_COMMON_2 0x20
112#define SYS_COMMON_3 0x30
113
76 114
77/******************************************************************************* 115/*******************************************************************************
78 * Console 116 * Console
@@ -240,8 +278,13 @@ void EVENT_USB_Device_ConfigurationChanged(void)
240 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, 278 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
241 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE); 279 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
242#endif 280#endif
281
282
283 ConfigSuccess &= MIDI_Device_ConfigureEndpoints(&USB_MIDI_Interface);
243} 284}
244 285
286
287
245/* 288/*
246Appendix G: HID Request Support Requirements 289Appendix G: HID Request Support Requirements
247 290
@@ -263,6 +306,8 @@ void EVENT_USB_Device_ControlRequest(void)
263 uint8_t* ReportData = NULL; 306 uint8_t* ReportData = NULL;
264 uint8_t ReportSize = 0; 307 uint8_t ReportSize = 0;
265 308
309 MIDI_Device_ProcessControlRequest(&USB_MIDI_Interface);
310
266 /* Handle HID Class specific requests */ 311 /* Handle HID Class specific requests */
267 switch (USB_ControlRequest.bRequest) 312 switch (USB_ControlRequest.bRequest)
268 { 313 {
@@ -541,10 +586,109 @@ int8_t sendchar(uint8_t c)
541#endif 586#endif
542 587
543 588
589
590
591
592void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
593 MIDI_EventPacket_t event;
594 event.Data1 = byte0;
595 event.Data2 = byte1;
596 event.Data3 = byte2;
597
598 //if the length is undefined we assume it is a SYSEX message
599 if (midi_packet_length(byte0) == UNDEFINED) {
600 switch(cnt) {
601 case 3:
602 if (byte2 == SYSEX_END)
603 event.Event = MIDI_EVENT(0, SYSEX_ENDS_IN_3);
604 else
605 event.Event = MIDI_EVENT(0, SYSEX_START_OR_CONT);
606 break;
607 case 2:
608 if (byte1 == SYSEX_END)
609 event.Event = MIDI_EVENT(0, SYSEX_ENDS_IN_2);
610 else
611 event.Event = MIDI_EVENT(0, SYSEX_START_OR_CONT);
612 break;
613 case 1:
614 if (byte0 == SYSEX_END)
615 event.Event = MIDI_EVENT(0, SYSEX_ENDS_IN_1);
616 else
617 event.Event = MIDI_EVENT(0, SYSEX_START_OR_CONT);
618 break;
619 default:
620 return; //invalid cnt
621 }
622 } else {
623 //deal with 'system common' messages
624 //TODO are there any more?
625 switch(byte0 & 0xF0){
626 case MIDI_SONGPOSITION:
627 event.Event = MIDI_EVENT(0, SYS_COMMON_3);
628 break;
629 case MIDI_SONGSELECT:
630 case MIDI_TC_QUARTERFRAME:
631 event.Event = MIDI_EVENT(0, SYS_COMMON_2);
632 break;
633 default:
634 event.Event = MIDI_EVENT(0, byte0);
635 break;
636 }
637 }
638
639 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
640 MIDI_Device_Flush(&USB_MIDI_Interface);
641 MIDI_Device_USBTask(&USB_MIDI_Interface);
642 USB_USBTask();
643}
644
645void usb_get_midi(MidiDevice * device) {
646 MIDI_EventPacket_t event;
647 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
648
649 midi_packet_length_t length = midi_packet_length(event.Data1);
650 uint8_t input[3];
651 input[0] = event.Data1;
652 input[1] = event.Data2;
653 input[2] = event.Data3;
654 if (length == UNDEFINED) {
655 //sysex
656 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
657 length = 3;
658 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
659 length = 2;
660 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
661 length = 1;
662 } else {
663 //XXX what to do?
664 }
665 }
666
667 //pass the data to the device input function
668 if (length != UNDEFINED)
669 midi_device_input(device, length, input);
670 }
671 MIDI_Device_USBTask(&USB_MIDI_Interface);
672 USB_USBTask();
673}
674
675void midi_usb_init(MidiDevice * device){
676 midi_device_init(device);
677 midi_device_set_send_func(device, usb_send_func);
678 midi_device_set_pre_input_process_func(device, usb_get_midi);
679
680 SetupHardware();
681 sei();
682}
683
684
685
686
687
544/******************************************************************************* 688/*******************************************************************************
545 * main 689 * main
546 ******************************************************************************/ 690 ******************************************************************************/
547static void SetupHardware(void) 691void SetupHardware(void)
548{ 692{
549 /* Disable watchdog if enabled by bootloader/fuses */ 693 /* Disable watchdog if enabled by bootloader/fuses */
550 MCUSR &= ~(1 << WDRF); 694 MCUSR &= ~(1 << WDRF);
@@ -563,12 +707,34 @@ static void SetupHardware(void)
563 print_set_sendchar(sendchar); 707 print_set_sendchar(sendchar);
564} 708}
565 709
710void fallthrough_callback(MidiDevice * device,
711 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
712void cc_callback(MidiDevice * device,
713 uint8_t chan, uint8_t num, uint8_t val);
714void sysex_callback(MidiDevice * device,
715 uint16_t start, uint8_t length, uint8_t * data);
716
566int main(void) __attribute__ ((weak)); 717int main(void) __attribute__ ((weak));
567int main(void) 718int main(void)
568{ 719{
720 //setup the device
721
722 midi_device_init(&midi_device);
723 midi_device_set_send_func(&midi_device, usb_send_func);
724 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
725
569 SetupHardware(); 726 SetupHardware();
570 sei(); 727 sei();
571 728
729 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
730 midi_register_cc_callback(&midi_device, cc_callback);
731 midi_register_sysex_callback(&midi_device, sysex_callback);
732
733 midi_send_cc(&midi_device, 0, 1, 2);
734 midi_send_cc(&midi_device, 15, 1, 0);
735 midi_send_noteon(&midi_device, 0, 64, 127);
736 midi_send_noteoff(&midi_device, 0, 64, 127);
737
572 /* wait for USB startup & debug output */ 738 /* wait for USB startup & debug output */
573 while (USB_DeviceState != DEVICE_STATE_Configured) { 739 while (USB_DeviceState != DEVICE_STATE_Configured) {
574#if defined(INTERRUPT_CONTROL_ENDPOINT) 740#if defined(INTERRUPT_CONTROL_ENDPOINT)
@@ -598,8 +764,29 @@ int main(void)
598 764
599 keyboard_task(); 765 keyboard_task();
600 766
767 midi_device_process(&midi_device);
768
601#if !defined(INTERRUPT_CONTROL_ENDPOINT) 769#if !defined(INTERRUPT_CONTROL_ENDPOINT)
602 USB_USBTask(); 770 USB_USBTask();
603#endif 771#endif
604 } 772 }
605} 773}
774
775//echo data back
776void fallthrough_callback(MidiDevice * device,
777 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
778 //pass the data back to the device, using the general purpose send data
779 //function, any bytes after cnt are ignored
780}
781
782void cc_callback(MidiDevice * device,
783 uint8_t chan, uint8_t num, uint8_t val) {
784 //sending it back on the next channel
785 midi_send_cc(device, (chan + 1) % 16, num, val);
786}
787
788void sysex_callback(MidiDevice * device,
789 uint16_t start, uint8_t length, uint8_t * data) {
790 for (int i = 0; i < length; i++)
791 midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));
792}