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.c226
1 files changed, 224 insertions, 2 deletions
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index cdfc7bc6a..03b13f404 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,60 @@ 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);
69
70#ifdef MIDI_ENABLE
71void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
72void usb_get_midi(MidiDevice * device);
73void midi_usb_init(MidiDevice * device);
74#endif
75
68host_driver_t lufa_driver = { 76host_driver_t lufa_driver = {
69 keyboard_leds, 77 keyboard_leds,
70 send_keyboard, 78 send_keyboard,
71 send_mouse, 79 send_mouse,
72 send_system, 80 send_system,
73 send_consumer 81 send_consumer,
82#ifdef MIDI_ENABLE
83 usb_send_func,
84 usb_get_midi,
85 midi_usb_init,
86#endif
87
88};
89
90void SetupHardware(void);
91
92
93USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
94{
95 .Config =
96 {
97 .StreamingInterfaceNumber = MIDI2_INTERFACE,
98 .DataINEndpoint =
99 {
100 .Address = (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM),
101 .Size = MIDI_STREAM_EPSIZE,
102 .Banks = 1,
103 },
104 .DataOUTEndpoint =
105 {
106 .Address = (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM),
107 .Size = MIDI_STREAM_EPSIZE,
108 .Banks = 1,
109 },
110 },
74}; 111};
75 112
113#define SYSEX_START_OR_CONT 0x40
114#define SYSEX_ENDS_IN_1 0x50
115#define SYSEX_ENDS_IN_2 0x60
116#define SYSEX_ENDS_IN_3 0x70
117
118#define SYS_COMMON_1 0x50
119#define SYS_COMMON_2 0x20
120#define SYS_COMMON_3 0x30
121
122
76 123
77/******************************************************************************* 124/*******************************************************************************
78 * Console 125 * Console
@@ -240,8 +287,20 @@ void EVENT_USB_Device_ConfigurationChanged(void)
240 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, 287 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
241 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE); 288 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
242#endif 289#endif
290
291#ifdef MIDI_ENABLE
292 ConfigSuccess &= MIDI_Device_ConfigureEndpoints(&USB_MIDI_Interface);
293
294 // ConfigSuccess &= ENDPOINT_CONFIG(MIDI_STREAM_IN_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_IN,
295 // MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
296 // ConfigSuccess &= ENDPOINT_CONFIG(MIDI_STREAM_OUT_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT,
297 // MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
298#endif
299
243} 300}
244 301
302
303
245/* 304/*
246Appendix G: HID Request Support Requirements 305Appendix G: HID Request Support Requirements
247 306
@@ -263,6 +322,8 @@ void EVENT_USB_Device_ControlRequest(void)
263 uint8_t* ReportData = NULL; 322 uint8_t* ReportData = NULL;
264 uint8_t ReportSize = 0; 323 uint8_t ReportSize = 0;
265 324
325 MIDI_Device_ProcessControlRequest(&USB_MIDI_Interface);
326
266 /* Handle HID Class specific requests */ 327 /* Handle HID Class specific requests */
267 switch (USB_ControlRequest.bRequest) 328 switch (USB_ControlRequest.bRequest)
268 { 329 {
@@ -541,10 +602,117 @@ int8_t sendchar(uint8_t c)
541#endif 602#endif
542 603
543 604
605
606
607
608#ifdef MIDI_ENABLE
609void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
610 MIDI_EventPacket_t event;
611 event.Data1 = byte0;
612 event.Data2 = byte1;
613 event.Data3 = byte2;
614
615 uint8_t cable = 0;
616
617// Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
618
619 //if the length is undefined we assume it is a SYSEX message
620 if (midi_packet_length(byte0) == UNDEFINED) {
621 switch(cnt) {
622 case 3:
623 if (byte2 == SYSEX_END)
624 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
625 else
626 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
627 break;
628 case 2:
629 if (byte1 == SYSEX_END)
630 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
631 else
632 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
633 break;
634 case 1:
635 if (byte0 == SYSEX_END)
636 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
637 else
638 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
639 break;
640 default:
641 return; //invalid cnt
642 }
643 } else {
644 //deal with 'system common' messages
645 //TODO are there any more?
646 switch(byte0 & 0xF0){
647 case MIDI_SONGPOSITION:
648 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
649 break;
650 case MIDI_SONGSELECT:
651 case MIDI_TC_QUARTERFRAME:
652 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
653 break;
654 default:
655 event.Event = MIDI_EVENT(cable, byte0);
656 break;
657 }
658 }
659
660// Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
661// Endpoint_ClearIN();
662
663 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
664 MIDI_Device_Flush(&USB_MIDI_Interface);
665 MIDI_Device_USBTask(&USB_MIDI_Interface);
666 USB_USBTask();
667}
668
669void usb_get_midi(MidiDevice * device) {
670 MIDI_EventPacket_t event;
671 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
672
673 midi_packet_length_t length = midi_packet_length(event.Data1);
674 uint8_t input[3];
675 input[0] = event.Data1;
676 input[1] = event.Data2;
677 input[2] = event.Data3;
678 if (length == UNDEFINED) {
679 //sysex
680 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
681 length = 3;
682 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
683 length = 2;
684 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
685 length = 1;
686 } else {
687 //XXX what to do?
688 }
689 }
690
691 //pass the data to the device input function
692 if (length != UNDEFINED)
693 midi_device_input(device, length, input);
694 }
695 MIDI_Device_USBTask(&USB_MIDI_Interface);
696 USB_USBTask();
697}
698
699void midi_usb_init(MidiDevice * device){
700 midi_device_init(device);
701 midi_device_set_send_func(device, usb_send_func);
702 midi_device_set_pre_input_process_func(device, usb_get_midi);
703
704 SetupHardware();
705 sei();
706}
707#endif
708
709
710
711
544/******************************************************************************* 712/*******************************************************************************
545 * main 713 * main
546 ******************************************************************************/ 714 ******************************************************************************/
547static void SetupHardware(void) 715void SetupHardware(void)
548{ 716{
549 /* Disable watchdog if enabled by bootloader/fuses */ 717 /* Disable watchdog if enabled by bootloader/fuses */
550 MCUSR &= ~(1 << WDRF); 718 MCUSR &= ~(1 << WDRF);
@@ -563,12 +731,41 @@ static void SetupHardware(void)
563 print_set_sendchar(sendchar); 731 print_set_sendchar(sendchar);
564} 732}
565 733
734#ifdef MIDI_ENABLE
735void fallthrough_callback(MidiDevice * device,
736 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
737void cc_callback(MidiDevice * device,
738 uint8_t chan, uint8_t num, uint8_t val);
739void sysex_callback(MidiDevice * device,
740 uint16_t start, uint8_t length, uint8_t * data);
741#endif
742
566int main(void) __attribute__ ((weak)); 743int main(void) __attribute__ ((weak));
567int main(void) 744int main(void)
568{ 745{
746 //setup the device
747
748#ifdef MIDI_ENABLE
749 midi_device_init(&midi_device);
750 midi_device_set_send_func(&midi_device, usb_send_func);
751 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
752#endif
753
569 SetupHardware(); 754 SetupHardware();
570 sei(); 755 sei();
571 756
757#ifdef MIDI_ENABLE
758 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
759 midi_register_cc_callback(&midi_device, cc_callback);
760 midi_register_sysex_callback(&midi_device, sysex_callback);
761
762 midi_send_cc(&midi_device, 0, 1, 2);
763 midi_send_cc(&midi_device, 15, 1, 0);
764 midi_send_noteon(&midi_device, 0, 64, 127);
765 midi_send_noteoff(&midi_device, 0, 64, 127);
766#endif
767
768
572 /* wait for USB startup & debug output */ 769 /* wait for USB startup & debug output */
573 while (USB_DeviceState != DEVICE_STATE_Configured) { 770 while (USB_DeviceState != DEVICE_STATE_Configured) {
574#if defined(INTERRUPT_CONTROL_ENDPOINT) 771#if defined(INTERRUPT_CONTROL_ENDPOINT)
@@ -598,8 +795,33 @@ int main(void)
598 795
599 keyboard_task(); 796 keyboard_task();
600 797
798#ifdef MIDI_ENABLE
799 midi_device_process(&midi_device);
800#endif
801
601#if !defined(INTERRUPT_CONTROL_ENDPOINT) 802#if !defined(INTERRUPT_CONTROL_ENDPOINT)
602 USB_USBTask(); 803 USB_USBTask();
603#endif 804#endif
604 } 805 }
605} 806}
807
808#ifdef MIDI_ENABLE
809//echo data back
810void fallthrough_callback(MidiDevice * device,
811 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
812 //pass the data back to the device, using the general purpose send data
813 //function, any bytes after cnt are ignored
814}
815
816void cc_callback(MidiDevice * device,
817 uint8_t chan, uint8_t num, uint8_t val) {
818 //sending it back on the next channel
819 midi_send_cc(device, (chan + 1) % 16, num, val);
820}
821
822void sysex_callback(MidiDevice * device,
823 uint16_t start, uint8_t length, uint8_t * data) {
824 for (int i = 0; i < length; i++)
825 midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));
826}
827#endif