Merge ChibiOS and LUFA descriptor support (#2362)
* Move lufa descriptor to protocol/usb_descriptor * Try to compile usb_descriptor on ChibiOS * Add lufa_utils for ChibiOS Lufa USB descriptors for ChibiOS * More lufa_util compatibility fixes * First compiling version of shared USB descriptor * Send the usb descriptors * Fix the CONSOLE output on ChibiOS * Add errors for unsupported interfaces * Enable support for vitual serial port USB descriptors * Implement virtual serial port for ChibiOS * Cleanup the lufa_utils Use the default lufa header files * Add raw hid support for ChibiOS This is completely untested * Enable midi compilation on ChibiOS * Move midi functionality out of lufa.c * Don't register sysex callback when not needed * ChibiOS compilation fixes * Update ChibiOS submodule * Fix the Midi USB descriptor It didn't work properly when both Midi and Virtual serial port was enabled. * Add MIDI support for ChibiOS * Fix USB descriptor strings on ChibiOS * Use serial usb driver for raw hid * Generalize the ChibiOS stream like drivers This makes the initialization much more simple and eliminates a lot of the code duplication. * Convert console output to chibios stream driver * Fixes for ChibiOS update * Update the ChibiOS contrib submodule To include the usb data toggle synchronization fixes * Fix duplicate reset enumeration on ChibiOS * Add missing include * Add number of endpoints check for ChibiOS * Enable serial USB driver on all keyboards * Add missing includes when API is enabled withot midi * Add another missing inlcude
This commit is contained in:
		| @@ -4,7 +4,16 @@ CHIBIOS_DIR = $(PROTOCOL_DIR)/chibios | ||||
|  | ||||
| SRC += $(CHIBIOS_DIR)/usb_main.c | ||||
| SRC += $(CHIBIOS_DIR)/main.c | ||||
| SRC += usb_descriptor.c | ||||
|  | ||||
| VPATH += $(TMK_PATH)/$(PROTOCOL_DIR) | ||||
| VPATH += $(TMK_PATH)/$(CHIBIOS_DIR) | ||||
| VPATH += $(TMK_PATH)/$(CHIBIOS_DIR)/lufa_utils | ||||
|  | ||||
| OPT_DEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=64 | ||||
| OPT_DEFS += -DFIXED_NUM_CONFIGURATIONS=1 | ||||
|  | ||||
| ifeq ($(strip $(MIDI_ENABLE)), yes) | ||||
|   include $(TMK_PATH)/protocol/midi.mk | ||||
| endif | ||||
|  | ||||
|   | ||||
							
								
								
									
										42
									
								
								tmk_core/protocol/chibios/lufa_utils/LUFA/Drivers/USB/USB.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								tmk_core/protocol/chibios/lufa_utils/LUFA/Drivers/USB/USB.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| #include "progmem.h" | ||||
| #include "stddef.h" | ||||
| #include "inttypes.h" | ||||
|  | ||||
| #define ATTR_PACKED                      __attribute__ ((packed)) | ||||
| /** Concatenates the given input into a single token, via the C Preprocessor. | ||||
|  * | ||||
|  *  \param[in] x  First item to concatenate. | ||||
|  *  \param[in] y  Second item to concatenate. | ||||
|  * | ||||
|  *  \return Concatenated version of the input. | ||||
|  */ | ||||
| #define CONCAT(x, y)            x ## y | ||||
|  | ||||
| /** CConcatenates the given input into a single token after macro expansion, via the C Preprocessor. | ||||
|  * | ||||
|  *  \param[in] x  First item to concatenate. | ||||
|  *  \param[in] y  Second item to concatenate. | ||||
|  * | ||||
|  *  \return Concatenated version of the expanded input. | ||||
|  */ | ||||
| #define CONCAT_EXPANDED(x, y)   CONCAT(x, y) | ||||
| #define CPU_TO_LE16(x)           (x) | ||||
|  | ||||
| // We don't need anything from the following files, or we have defined it already | ||||
| #define __LUFA_COMMON_H__ | ||||
| #define __USBMODE_H__ | ||||
| #define __USBEVENTS_H__ | ||||
| #define __HIDPARSER_H__ | ||||
| #define __USBCONTROLLER_AVR8_H__ | ||||
|  | ||||
| #define __INCLUDE_FROM_USB_DRIVER | ||||
| #define __INCLUDE_FROM_HID_DRIVER | ||||
| #define __INCLUDE_FROM_CDC_DRIVER | ||||
| #define __INCLUDE_FROM_AUDIO_DRIVER | ||||
| #define __INCLUDE_FROM_MIDI_DRIVER | ||||
| #include "lib/lufa/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h" | ||||
| #include "lib/lufa/LUFA/Drivers/USB/Class/Common/HIDReportData.h" | ||||
| #include "lib/lufa/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h" | ||||
| #include "lib/lufa/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h" | ||||
| #include "lib/lufa/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h" | ||||
| #include "lib/lufa/LUFA/Drivers/USB/Core/USBController.h" | ||||
| @@ -41,6 +41,9 @@ | ||||
| #ifdef VISUALIZER_ENABLE | ||||
| #include "visualizer/visualizer.h" | ||||
| #endif | ||||
| #ifdef MIDI_ENABLE | ||||
| #include "qmk_midi.h" | ||||
| #endif | ||||
| #include "suspend.h" | ||||
| #include "wait.h" | ||||
|  | ||||
| @@ -65,6 +68,17 @@ host_driver_t chibios_driver = { | ||||
|   send_consumer | ||||
| }; | ||||
|  | ||||
| #ifdef VIRTSER_ENABLE | ||||
| void virtser_task(void); | ||||
| #endif | ||||
|  | ||||
| #ifdef RAW_HID_ENABLE | ||||
| void raw_hid_task(void); | ||||
| #endif | ||||
|  | ||||
| #ifdef CONSOLE_ENABLE | ||||
| void console_task(void); | ||||
| #endif | ||||
|  | ||||
| /* TESTING | ||||
|  * Amber LED blinker thread, times are in milliseconds. | ||||
| @@ -104,6 +118,10 @@ int main(void) { | ||||
|   /* init printf */ | ||||
|   init_printf(NULL,sendchar_pf); | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
|   setup_midi(); | ||||
| #endif | ||||
|  | ||||
| #ifdef SERIAL_LINK_ENABLE | ||||
|   init_serial_link(); | ||||
| #endif | ||||
| @@ -182,5 +200,14 @@ int main(void) { | ||||
|     } | ||||
|  | ||||
|     keyboard_task(); | ||||
| #ifdef CONSOLE_ENABLE | ||||
|     console_task(); | ||||
| #endif | ||||
| #ifdef VIRTSER_ENABLE | ||||
|     virtser_task(); | ||||
| #endif | ||||
| #ifdef RAW_HID_ENABLE | ||||
|     raw_hid_task(); | ||||
| #endif | ||||
|   } | ||||
| } | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -41,20 +41,6 @@ void init_usb_driver(USBDriver *usbp); | ||||
|  * --------------- | ||||
|  */ | ||||
|  | ||||
| /* main keyboard (6kro) */ | ||||
| #define KBD_INTERFACE   0 | ||||
| #define KBD_ENDPOINT    1 | ||||
| #define KBD_EPSIZE      8 | ||||
| #define KBD_REPORT_KEYS (KBD_EPSIZE - 2) | ||||
|  | ||||
| /* secondary keyboard */ | ||||
| #ifdef NKRO_ENABLE | ||||
| #define NKRO_INTERFACE    4 | ||||
| #define NKRO_ENDPOINT     5 | ||||
| #define NKRO_EPSIZE       16 | ||||
| #define NKRO_REPORT_KEYS  (NKRO_EPSIZE - 1) | ||||
| #endif | ||||
|  | ||||
| /* extern report_keyboard_t keyboard_report_sent; */ | ||||
|  | ||||
| /* keyboard IN request callback handler */ | ||||
| @@ -75,10 +61,6 @@ void nkro_in_cb(USBDriver *usbp, usbep_t ep); | ||||
|  | ||||
| #ifdef MOUSE_ENABLE | ||||
|  | ||||
| #define MOUSE_INTERFACE         1 | ||||
| #define MOUSE_ENDPOINT          2 | ||||
| #define MOUSE_EPSIZE            8 | ||||
|  | ||||
| /* mouse IN request callback handler */ | ||||
| void mouse_in_cb(USBDriver *usbp, usbep_t ep); | ||||
| #endif /* MOUSE_ENABLE */ | ||||
| @@ -90,10 +72,6 @@ void mouse_in_cb(USBDriver *usbp, usbep_t ep); | ||||
|  | ||||
| #ifdef EXTRAKEY_ENABLE | ||||
|  | ||||
| #define EXTRA_INTERFACE         3 | ||||
| #define EXTRA_ENDPOINT          4 | ||||
| #define EXTRA_EPSIZE            8 | ||||
|  | ||||
| /* extrakey IN request callback handler */ | ||||
| void extra_in_cb(USBDriver *usbp, usbep_t ep); | ||||
|  | ||||
| @@ -111,24 +89,12 @@ typedef struct { | ||||
|  | ||||
| #ifdef CONSOLE_ENABLE | ||||
|  | ||||
| #define CONSOLE_INTERFACE      2 | ||||
| #define CONSOLE_ENDPOINT       3 | ||||
| #define CONSOLE_EPSIZE         16 | ||||
|  | ||||
| /* Number of IN reports that can be stored inside the output queue */ | ||||
| #define CONSOLE_QUEUE_CAPACITY 4 | ||||
|  | ||||
| /* Console flush time */ | ||||
| #define CONSOLE_FLUSH_MS 50 | ||||
|  | ||||
| /* Putchar over the USB console */ | ||||
| int8_t sendchar(uint8_t c); | ||||
|  | ||||
| /* Flush output (send everything immediately) */ | ||||
| void console_flush_output(void); | ||||
|  | ||||
| /* console IN request callback handler */ | ||||
| void console_in_cb(USBDriver *usbp, usbep_t ep); | ||||
| #endif /* CONSOLE_ENABLE */ | ||||
|  | ||||
| void sendchar_pf(void *p, char c); | ||||
|   | ||||
| @@ -15,7 +15,7 @@ else | ||||
| endif | ||||
|  | ||||
| LUFA_SRC = lufa.c \ | ||||
| 	   descriptor.c \ | ||||
| 	   usb_descriptor.c \ | ||||
| 	   outputselect.c \ | ||||
| 	   $(LUFA_SRC_USB) | ||||
|  | ||||
| @@ -64,7 +64,7 @@ LUFA_OPTS  = -DUSB_DEVICE_ONLY | ||||
| LUFA_OPTS += -DUSE_FLASH_DESCRIPTORS | ||||
| LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" | ||||
| #LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT | ||||
| LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8  | ||||
| LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 | ||||
| LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 | ||||
| LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1 | ||||
|  | ||||
|   | ||||
| @@ -49,7 +49,7 @@ | ||||
| #endif | ||||
| #include "suspend.h" | ||||
|  | ||||
| #include "descriptor.h" | ||||
| #include "usb_descriptor.h" | ||||
| #include "lufa.h" | ||||
| #include "quantum.h" | ||||
| #include <util/atomic.h> | ||||
| @@ -83,7 +83,7 @@ | ||||
| #endif | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
|   #include "sysex_tools.h" | ||||
|   #include "qmk_midi.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef RAW_ENABLE | ||||
| @@ -97,12 +97,6 @@ static uint8_t keyboard_led_stats = 0; | ||||
|  | ||||
| static report_keyboard_t keyboard_report_sent; | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
| static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); | ||||
| static void usb_get_midi(MidiDevice * device); | ||||
| static void midi_usb_init(MidiDevice * device); | ||||
| #endif | ||||
|  | ||||
| /* Host driver */ | ||||
| static uint8_t keyboard_leds(void); | ||||
| static void send_keyboard(report_keyboard_t *report); | ||||
| @@ -115,48 +109,8 @@ host_driver_t lufa_driver = { | ||||
|     send_mouse, | ||||
|     send_system, | ||||
|     send_consumer, | ||||
| #ifdef MIDI_ENABLE | ||||
|     usb_send_func, | ||||
|     usb_get_midi, | ||||
|     midi_usb_init | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| /******************************************************************************* | ||||
|  * MIDI | ||||
|  ******************************************************************************/ | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
| USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface = | ||||
| { | ||||
|   .Config = | ||||
|   { | ||||
|     .StreamingInterfaceNumber = AS_INTERFACE, | ||||
|     .DataINEndpoint           = | ||||
|     { | ||||
|       .Address          = MIDI_STREAM_IN_EPADDR, | ||||
|       .Size             = MIDI_STREAM_EPSIZE, | ||||
|       .Banks            = 1, | ||||
|     }, | ||||
|     .DataOUTEndpoint          = | ||||
|     { | ||||
|       .Address          = MIDI_STREAM_OUT_EPADDR, | ||||
|       .Size             = MIDI_STREAM_EPSIZE, | ||||
|       .Banks            = 1, | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| #define SYSEX_START_OR_CONT 0x40 | ||||
| #define SYSEX_ENDS_IN_1 0x50 | ||||
| #define SYSEX_ENDS_IN_2 0x60 | ||||
| #define SYSEX_ENDS_IN_3 0x70 | ||||
|  | ||||
| #define SYS_COMMON_1 0x50 | ||||
| #define SYS_COMMON_2 0x20 | ||||
| #define SYS_COMMON_3 0x30 | ||||
| #endif | ||||
|  | ||||
| #ifdef VIRTSER_ENABLE | ||||
| USB_ClassInfo_CDC_Device_t cdc_device = | ||||
| { | ||||
| @@ -853,170 +807,32 @@ int8_t sendchar(uint8_t c) | ||||
|  ******************************************************************************/ | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
| static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { | ||||
|   MIDI_EventPacket_t event; | ||||
|   event.Data1 = byte0; | ||||
|   event.Data2 = byte1; | ||||
|   event.Data3 = byte2; | ||||
|  | ||||
|   uint8_t cable = 0; | ||||
|  | ||||
| // Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM); | ||||
|  | ||||
|   //if the length is undefined we assume it is a SYSEX message | ||||
|   if (midi_packet_length(byte0) == UNDEFINED) { | ||||
|     switch(cnt) { | ||||
|       case 3: | ||||
|         if (byte2 == SYSEX_END) | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3); | ||||
|         else | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT); | ||||
|         break; | ||||
|       case 2: | ||||
|         if (byte1 == SYSEX_END) | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2); | ||||
|         else | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT); | ||||
|         break; | ||||
|       case 1: | ||||
|         if (byte0 == SYSEX_END) | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1); | ||||
|         else | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT); | ||||
|         break; | ||||
|       default: | ||||
|         return; //invalid cnt | ||||
|     } | ||||
|   } else { | ||||
|     //deal with 'system common' messages | ||||
|     //TODO are there any more? | ||||
|     switch(byte0 & 0xF0){ | ||||
|       case MIDI_SONGPOSITION: | ||||
|         event.Event = MIDI_EVENT(cable, SYS_COMMON_3); | ||||
|         break; | ||||
|       case MIDI_SONGSELECT: | ||||
|       case MIDI_TC_QUARTERFRAME: | ||||
|         event.Event = MIDI_EVENT(cable, SYS_COMMON_2); | ||||
|         break; | ||||
|       default: | ||||
|         event.Event = MIDI_EVENT(cable, byte0); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| // Endpoint_Write_Stream_LE(&event, sizeof(event), NULL); | ||||
| // Endpoint_ClearIN(); | ||||
|  | ||||
|   MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event); | ||||
|   MIDI_Device_Flush(&USB_MIDI_Interface); | ||||
|   MIDI_Device_USBTask(&USB_MIDI_Interface); | ||||
|   USB_USBTask(); | ||||
| } | ||||
|  | ||||
| static void usb_get_midi(MidiDevice * device) { | ||||
|   MIDI_EventPacket_t event; | ||||
|   while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) { | ||||
|  | ||||
|     midi_packet_length_t length = midi_packet_length(event.Data1); | ||||
|     uint8_t input[3]; | ||||
|     input[0] = event.Data1; | ||||
|     input[1] = event.Data2; | ||||
|     input[2] = event.Data3; | ||||
|     if (length == UNDEFINED) { | ||||
|       //sysex | ||||
|       if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) { | ||||
|         length = 3; | ||||
|       } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) { | ||||
|         length = 2; | ||||
|       } else if(event.Event ==  MIDI_EVENT(0, SYSEX_ENDS_IN_1)) { | ||||
|         length = 1; | ||||
|       } else { | ||||
|         //XXX what to do? | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     //pass the data to the device input function | ||||
|     if (length != UNDEFINED) | ||||
|       midi_device_input(device, length, input); | ||||
|   } | ||||
|   MIDI_Device_USBTask(&USB_MIDI_Interface); | ||||
|   USB_USBTask(); | ||||
| } | ||||
|  | ||||
| static void midi_usb_init(MidiDevice * device){ | ||||
|   midi_device_init(device); | ||||
|   midi_device_set_send_func(device, usb_send_func); | ||||
|   midi_device_set_pre_input_process_func(device, usb_get_midi); | ||||
|  | ||||
|   // SetupHardware(); | ||||
|   sei(); | ||||
| } | ||||
|  | ||||
| void MIDI_Task(void) | ||||
| USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface = | ||||
| { | ||||
|  | ||||
|     /* Device must be connected and configured for the task to run */ | ||||
|     dprint("in MIDI_TASK\n"); | ||||
|     if (USB_DeviceState != DEVICE_STATE_Configured) | ||||
|       return; | ||||
|     dprint("continuing in MIDI_TASK\n"); | ||||
|  | ||||
|     Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR); | ||||
|  | ||||
|     if (Endpoint_IsINReady()) | ||||
|   .Config = | ||||
|   { | ||||
|     .StreamingInterfaceNumber = AS_INTERFACE, | ||||
|     .DataINEndpoint           = | ||||
|     { | ||||
|  | ||||
|         dprint("Endpoint is ready\n"); | ||||
|  | ||||
|         uint8_t MIDICommand = 0; | ||||
|         uint8_t MIDIPitch; | ||||
|  | ||||
|         /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */ | ||||
|         uint8_t Channel = MIDI_CHANNEL(1); | ||||
|  | ||||
|         MIDICommand = MIDI_COMMAND_NOTE_ON; | ||||
|         MIDIPitch   = 0x3E; | ||||
|  | ||||
|         /* Check if a MIDI command is to be sent */ | ||||
|         if (MIDICommand) | ||||
|         { | ||||
|             dprint("Command exists\n"); | ||||
|             MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) | ||||
|                 { | ||||
|                     .Event       = MIDI_EVENT(0, MIDICommand), | ||||
|  | ||||
|                     .Data1       = MIDICommand | Channel, | ||||
|                     .Data2       = MIDIPitch, | ||||
|                     .Data3       = MIDI_STANDARD_VELOCITY, | ||||
|                 }; | ||||
|  | ||||
|             /* Write the MIDI event packet to the endpoint */ | ||||
|             Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL); | ||||
|  | ||||
|             /* Send the data in the endpoint to the host */ | ||||
|             Endpoint_ClearIN(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /* Select the MIDI OUT stream */ | ||||
|     Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR); | ||||
|  | ||||
|     /* Check if a MIDI command has been received */ | ||||
|     if (Endpoint_IsOUTReceived()) | ||||
|       .Address          = MIDI_STREAM_IN_EPADDR, | ||||
|       .Size             = MIDI_STREAM_EPSIZE, | ||||
|       .Banks            = 1, | ||||
|     }, | ||||
|     .DataOUTEndpoint          = | ||||
|     { | ||||
|         MIDI_EventPacket_t MIDIEvent; | ||||
|       .Address          = MIDI_STREAM_OUT_EPADDR, | ||||
|       .Size             = MIDI_STREAM_EPSIZE, | ||||
|       .Banks            = 1, | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
|  | ||||
|         /* Read the MIDI event packet from the endpoint */ | ||||
|         Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL); | ||||
| void send_midi_packet(MIDI_EventPacket_t* event) { | ||||
|   MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event); | ||||
| } | ||||
|  | ||||
|         /* If the endpoint is now empty, clear the bank */ | ||||
|         if (!(Endpoint_BytesInEndpoint())) | ||||
|         { | ||||
|             /* Clear the endpoint ready for new packet */ | ||||
|             Endpoint_ClearOUT(); | ||||
|         } | ||||
|     } | ||||
| bool recv_midi_packet(MIDI_EventPacket_t* const event) { | ||||
|   return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -1105,26 +921,6 @@ static void setup_usb(void) | ||||
|     print_set_sendchar(sendchar); | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
| void fallthrough_callback(MidiDevice * device, | ||||
|     uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); | ||||
| void cc_callback(MidiDevice * device, | ||||
|     uint8_t chan, uint8_t num, uint8_t val); | ||||
| void sysex_callback(MidiDevice * device, | ||||
|     uint16_t start, uint8_t length, uint8_t * data); | ||||
|  | ||||
| void setup_midi(void) | ||||
| { | ||||
| #ifdef MIDI_ADVANCED | ||||
| 	midi_init(); | ||||
| #endif | ||||
| 	midi_device_init(&midi_device); | ||||
|     midi_device_set_send_func(&midi_device, usb_send_func); | ||||
|     midi_device_set_pre_input_process_func(&midi_device, usb_get_midi); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| int main(void)  __attribute__ ((weak)); | ||||
| int main(void) | ||||
| { | ||||
| @@ -1137,18 +933,6 @@ int main(void) | ||||
|     setup_usb(); | ||||
|     sei(); | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
|     midi_register_fallthrough_callback(&midi_device, fallthrough_callback); | ||||
|     midi_register_cc_callback(&midi_device, cc_callback); | ||||
|     midi_register_sysex_callback(&midi_device, sysex_callback); | ||||
|  | ||||
|     // init_notes(); | ||||
|     // midi_send_cc(&midi_device, 0, 1, 2); | ||||
|     // midi_send_cc(&midi_device, 15, 1, 0); | ||||
|     // midi_send_noteon(&midi_device, 0, 64, 127); | ||||
|     // midi_send_noteoff(&midi_device, 0, 64, 127); | ||||
| #endif | ||||
|  | ||||
| #if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42) | ||||
|     serial_init(); | ||||
| #endif | ||||
| @@ -1193,10 +977,7 @@ int main(void) | ||||
|         keyboard_task(); | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
|         midi_device_process(&midi_device); | ||||
| #ifdef MIDI_ADVANCED | ||||
|         midi_task(); | ||||
| #endif | ||||
|         MIDI_Device_USBTask(&USB_MIDI_Interface); | ||||
| #endif | ||||
|  | ||||
| #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE) | ||||
| @@ -1223,71 +1004,10 @@ int main(void) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
| void fallthrough_callback(MidiDevice * device, | ||||
|     uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){ | ||||
|  | ||||
| #ifdef AUDIO_ENABLE | ||||
|   if (cnt == 3) { | ||||
|     switch (byte0 & 0xF0) { | ||||
|         case MIDI_NOTEON: | ||||
|             play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8); | ||||
|             break; | ||||
|         case MIDI_NOTEOFF: | ||||
|             stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0)); | ||||
|             break; | ||||
|     } | ||||
|   } | ||||
|   if (byte0 == MIDI_STOP) { | ||||
|     stop_all_notes(); | ||||
|   } | ||||
| #endif | ||||
| uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | ||||
|                                     const uint16_t wIndex, | ||||
|                                     const void** const DescriptorAddress) | ||||
| { | ||||
|   return get_usb_descriptor(wValue, wIndex, DescriptorAddress); | ||||
| } | ||||
|  | ||||
|  | ||||
| void cc_callback(MidiDevice * device, | ||||
|     uint8_t chan, uint8_t num, uint8_t val) { | ||||
|   //sending it back on the next channel | ||||
|   // midi_send_cc(device, (chan + 1) % 16, num, val); | ||||
| } | ||||
|  | ||||
| #ifdef API_SYSEX_ENABLE | ||||
| uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0}; | ||||
| #endif | ||||
|  | ||||
| void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) { | ||||
|     #ifdef API_SYSEX_ENABLE | ||||
|         // SEND_STRING("\n"); | ||||
|         // send_word(start); | ||||
|         // SEND_STRING(": "); | ||||
|         // Don't store the header | ||||
|         int16_t pos = start - 4; | ||||
|         for (uint8_t place = 0; place < length; place++) { | ||||
|             // send_byte(*data); | ||||
|             if (pos >= 0) { | ||||
|                 if (*data == 0xF7) { | ||||
|                     // SEND_STRING("\nRD: "); | ||||
|                     // for (uint8_t i = 0; i < start + place + 1; i++){ | ||||
|                     //     send_byte(midi_buffer[i]); | ||||
|                     // SEND_STRING(" "); | ||||
|                     // } | ||||
|                     const unsigned decoded_length = sysex_decoded_length(pos); | ||||
|                     uint8_t decoded[API_SYSEX_MAX_SIZE]; | ||||
|                     sysex_decode(decoded, midi_buffer, pos); | ||||
|                     process_api(decoded_length, decoded); | ||||
|                     return; | ||||
|                 } | ||||
|                 else if (pos >= MIDI_SYSEX_BUFFER) { | ||||
|                     return; | ||||
|                 } | ||||
|                 midi_buffer[pos] = *data; | ||||
|             } | ||||
|             // SEND_STRING(" "); | ||||
|             data++; | ||||
|             pos++; | ||||
|         } | ||||
|     #endif | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /*  | ||||
| /* | ||||
|  * Copyright 2012 Jun Wako <wakojun@gmail.com> | ||||
|  * This file is based on: | ||||
|  *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse | ||||
| @@ -48,9 +48,6 @@ | ||||
| #include <LUFA/Version.h> | ||||
| #include <LUFA/Drivers/USB/USB.h> | ||||
| #include "host.h" | ||||
| #ifdef MIDI_ENABLE | ||||
|   #include "process_midi.h" | ||||
| #endif | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| @@ -67,11 +64,6 @@ typedef struct { | ||||
|     uint16_t usage; | ||||
| } __attribute__ ((packed)) report_extra_t; | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
|   void MIDI_Task(void); | ||||
|   MidiDevice midi_device; | ||||
| #endif | ||||
|  | ||||
| #ifdef API_ENABLE | ||||
|   #include "api.h" | ||||
| #endif | ||||
|   | ||||
| @@ -5,6 +5,7 @@ SRC += midi.c \ | ||||
| 	   bytequeue/bytequeue.c \ | ||||
| 	   bytequeue/interrupt_setting.c \ | ||||
| 	   sysex_tools.c \ | ||||
|      qmk_midi.c \ | ||||
| 	   $(LUFA_SRC_USBCLASS) | ||||
|  | ||||
| VPATH += $(TMK_PATH)/$(MIDI_DIR) | ||||
| VPATH += $(TMK_PATH)/$(MIDI_DIR) | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| //Copyright 20010 Alex Norman | ||||
| //writen by Alex Norman  | ||||
| //writen by Alex Norman | ||||
| // | ||||
| //This file is part of avr-bytequeue. | ||||
| // | ||||
| @@ -22,6 +22,7 @@ | ||||
| //implementations of the typedef and these functions | ||||
|  | ||||
| #include "interrupt_setting.h" | ||||
| #if defined(__AVR__) | ||||
| #include <avr/interrupt.h> | ||||
|  | ||||
| interrupt_setting_t store_and_clear_interrupt(void) { | ||||
| @@ -33,4 +34,16 @@ interrupt_setting_t store_and_clear_interrupt(void) { | ||||
| void restore_interrupt_setting(interrupt_setting_t setting) { | ||||
|    SREG = setting; | ||||
| } | ||||
| #elif defined(__arm__) | ||||
| #include "ch.h" | ||||
|  | ||||
| interrupt_setting_t store_and_clear_interrupt(void) { | ||||
|   chSysLock(); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| void restore_interrupt_setting(interrupt_setting_t setting) { | ||||
|    chSysUnlock(); | ||||
| } | ||||
| #endif | ||||
|  | ||||
|   | ||||
							
								
								
									
										184
									
								
								tmk_core/protocol/midi/qmk_midi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								tmk_core/protocol/midi/qmk_midi.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| #include <LUFA/Drivers/USB/USB.h> | ||||
| #include "qmk_midi.h" | ||||
| #include "sysex_tools.h" | ||||
| #include "midi.h" | ||||
| #include "usb_descriptor.h" | ||||
| #include "process_midi.h" | ||||
| #if API_SYSEX_ENABLE | ||||
| #include "api.h" | ||||
| #endif | ||||
|  | ||||
| /******************************************************************************* | ||||
|  * MIDI | ||||
|  ******************************************************************************/ | ||||
|  | ||||
| MidiDevice midi_device; | ||||
|  | ||||
| #define SYSEX_START_OR_CONT 0x40 | ||||
| #define SYSEX_ENDS_IN_1 0x50 | ||||
| #define SYSEX_ENDS_IN_2 0x60 | ||||
| #define SYSEX_ENDS_IN_3 0x70 | ||||
|  | ||||
| #define SYS_COMMON_1 0x50 | ||||
| #define SYS_COMMON_2 0x20 | ||||
| #define SYS_COMMON_3 0x30 | ||||
|  | ||||
| static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { | ||||
|   MIDI_EventPacket_t event; | ||||
|   event.Data1 = byte0; | ||||
|   event.Data2 = byte1; | ||||
|   event.Data3 = byte2; | ||||
|  | ||||
|   uint8_t cable = 0; | ||||
|  | ||||
|   //if the length is undefined we assume it is a SYSEX message | ||||
|   if (midi_packet_length(byte0) == UNDEFINED) { | ||||
|     switch(cnt) { | ||||
|       case 3: | ||||
|         if (byte2 == SYSEX_END) | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3); | ||||
|         else | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT); | ||||
|         break; | ||||
|       case 2: | ||||
|         if (byte1 == SYSEX_END) | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2); | ||||
|         else | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT); | ||||
|         break; | ||||
|       case 1: | ||||
|         if (byte0 == SYSEX_END) | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1); | ||||
|         else | ||||
|           event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT); | ||||
|         break; | ||||
|       default: | ||||
|         return; //invalid cnt | ||||
|     } | ||||
|   } else { | ||||
|     //deal with 'system common' messages | ||||
|     //TODO are there any more? | ||||
|     switch(byte0 & 0xF0){ | ||||
|       case MIDI_SONGPOSITION: | ||||
|         event.Event = MIDI_EVENT(cable, SYS_COMMON_3); | ||||
|         break; | ||||
|       case MIDI_SONGSELECT: | ||||
|       case MIDI_TC_QUARTERFRAME: | ||||
|         event.Event = MIDI_EVENT(cable, SYS_COMMON_2); | ||||
|         break; | ||||
|       default: | ||||
|         event.Event = MIDI_EVENT(cable, byte0); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   send_midi_packet(&event); | ||||
| } | ||||
|  | ||||
| static void usb_get_midi(MidiDevice * device) { | ||||
|   MIDI_EventPacket_t event; | ||||
|   while (recv_midi_packet(&event)) { | ||||
|  | ||||
|     midi_packet_length_t length = midi_packet_length(event.Data1); | ||||
|     uint8_t input[3]; | ||||
|     input[0] = event.Data1; | ||||
|     input[1] = event.Data2; | ||||
|     input[2] = event.Data3; | ||||
|     if (length == UNDEFINED) { | ||||
|       //sysex | ||||
|       if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) { | ||||
|         length = 3; | ||||
|       } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) { | ||||
|         length = 2; | ||||
|       } else if(event.Event ==  MIDI_EVENT(0, SYSEX_ENDS_IN_1)) { | ||||
|         length = 1; | ||||
|       } else { | ||||
|         //XXX what to do? | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     //pass the data to the device input function | ||||
|     if (length != UNDEFINED) | ||||
|       midi_device_input(device, length, input); | ||||
|   } | ||||
| } | ||||
|  | ||||
| static void fallthrough_callback(MidiDevice * device, | ||||
|     uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){ | ||||
|  | ||||
| #ifdef AUDIO_ENABLE | ||||
|   if (cnt == 3) { | ||||
|     switch (byte0 & 0xF0) { | ||||
|         case MIDI_NOTEON: | ||||
|             play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8); | ||||
|             break; | ||||
|         case MIDI_NOTEOFF: | ||||
|             stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0)); | ||||
|             break; | ||||
|     } | ||||
|   } | ||||
|   if (byte0 == MIDI_STOP) { | ||||
|     stop_all_notes(); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
| static void cc_callback(MidiDevice * device, | ||||
|     uint8_t chan, uint8_t num, uint8_t val) { | ||||
|   //sending it back on the next channel | ||||
|   // midi_send_cc(device, (chan + 1) % 16, num, val); | ||||
| } | ||||
|  | ||||
| #ifdef API_SYSEX_ENABLE | ||||
| uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0}; | ||||
|  | ||||
| static void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) { | ||||
|   // SEND_STRING("\n"); | ||||
|   // send_word(start); | ||||
|   // SEND_STRING(": "); | ||||
|   // Don't store the header | ||||
|   int16_t pos = start - 4; | ||||
|   for (uint8_t place = 0; place < length; place++) { | ||||
|       // send_byte(*data); | ||||
|       if (pos >= 0) { | ||||
|           if (*data == 0xF7) { | ||||
|               // SEND_STRING("\nRD: "); | ||||
|               // for (uint8_t i = 0; i < start + place + 1; i++){ | ||||
|               //     send_byte(midi_buffer[i]); | ||||
|               // SEND_STRING(" "); | ||||
|               // } | ||||
|               const unsigned decoded_length = sysex_decoded_length(pos); | ||||
|               uint8_t decoded[API_SYSEX_MAX_SIZE]; | ||||
|               sysex_decode(decoded, midi_buffer, pos); | ||||
|               process_api(decoded_length, decoded); | ||||
|               return; | ||||
|           } | ||||
|           else if (pos >= MIDI_SYSEX_BUFFER) { | ||||
|               return; | ||||
|           } | ||||
|           midi_buffer[pos] = *data; | ||||
|       } | ||||
|       // SEND_STRING(" "); | ||||
|       data++; | ||||
|       pos++; | ||||
|   } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void midi_init(void); | ||||
|  | ||||
| void setup_midi(void) | ||||
| { | ||||
| #ifdef MIDI_ADVANCED | ||||
| 	midi_init(); | ||||
| #endif | ||||
| 	midi_device_init(&midi_device); | ||||
|   midi_device_set_send_func(&midi_device, usb_send_func); | ||||
|   midi_device_set_pre_input_process_func(&midi_device, usb_get_midi); | ||||
|   midi_register_fallthrough_callback(&midi_device, fallthrough_callback); | ||||
|   midi_register_cc_callback(&midi_device, cc_callback); | ||||
| #ifdef API_SYSEX_ENABLE | ||||
|   midi_register_sysex_callback(&midi_device, sysex_callback); | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										9
									
								
								tmk_core/protocol/midi/qmk_midi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tmk_core/protocol/midi/qmk_midi.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef MIDI_ENABLE | ||||
|   #include "midi.h" | ||||
|   extern MidiDevice midi_device; | ||||
|   void setup_midi(void); | ||||
|   void send_midi_packet(MIDI_EventPacket_t* event); | ||||
|   bool recv_midi_packet(MIDI_EventPacket_t* const event); | ||||
| #endif | ||||
| @@ -38,7 +38,7 @@ | ||||
| 
 | ||||
| #include "util.h" | ||||
| #include "report.h" | ||||
| #include "descriptor.h" | ||||
| #include "usb_descriptor.h" | ||||
| 
 | ||||
| #ifndef USB_MAX_POWER_CONSUMPTION | ||||
| #define USB_MAX_POWER_CONSUMPTION 500 | ||||
| @@ -571,6 +571,19 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = | ||||
| #endif | ||||
| 
 | ||||
| #ifdef MIDI_ENABLE | ||||
|     .Audio_Interface_Association = | ||||
|         { | ||||
|             .Header                   = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation}, | ||||
| 
 | ||||
|             .FirstInterfaceIndex      = AC_INTERFACE, | ||||
|             .TotalInterfaces          = 2, | ||||
| 
 | ||||
|             .Class                    = AUDIO_CSCP_AudioClass, | ||||
|             .SubClass                 = AUDIO_CSCP_ControlSubclass, | ||||
|             .Protocol                 = AUDIO_CSCP_ControlProtocol, | ||||
| 
 | ||||
|             .IADStrIndex              = NO_DESCRIPTOR, | ||||
|         }, | ||||
|     .Audio_ControlInterface = | ||||
|         { | ||||
|             .Header                   = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, | ||||
| @@ -622,8 +635,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = | ||||
| 
 | ||||
|             .AudioSpecification       = VERSION_BCD(1,0,0), | ||||
| 
 | ||||
|             .TotalLength              = (sizeof(USB_Descriptor_Configuration_t) - | ||||
|                                          offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)) | ||||
|             .TotalLength              = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC) | ||||
|                                         + sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t) | ||||
|                                         - offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC) | ||||
|         }, | ||||
| 
 | ||||
|     .MIDI_In_Jack_Emb = | ||||
| @@ -879,9 +893,9 @@ const USB_Descriptor_String_t PROGMEM SerialNumberString = | ||||
|  *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the | ||||
|  *  USB host. | ||||
|  */ | ||||
| uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | ||||
|                                     const uint16_t wIndex, | ||||
|                                     const void** const DescriptorAddress) | ||||
| uint16_t get_usb_descriptor(const uint16_t wValue, | ||||
|                             const uint16_t wIndex, | ||||
|                             const void** const DescriptorAddress) | ||||
| { | ||||
|     const uint8_t  DescriptorType   = (wValue >> 8); | ||||
|     const uint8_t  DescriptorIndex  = (wValue & 0xFF); | ||||
| @@ -45,8 +45,9 @@ | ||||
| #define _DESCRIPTORS_H_ | ||||
| 
 | ||||
| #include <LUFA/Drivers/USB/USB.h> | ||||
| #include <avr/pgmspace.h> | ||||
| 
 | ||||
| #ifdef PROTOCOL_CHIBIOS | ||||
| #include "hal.h" | ||||
| #endif | ||||
| 
 | ||||
| typedef struct | ||||
| { | ||||
| @@ -95,25 +96,26 @@ typedef struct | ||||
| #endif | ||||
| 
 | ||||
| #ifdef MIDI_ENABLE | ||||
|       // MIDI Audio Control Interface
 | ||||
|       USB_Descriptor_Interface_t                Audio_ControlInterface; | ||||
|       USB_Audio_Descriptor_Interface_AC_t       Audio_ControlInterface_SPC; | ||||
|     USB_Descriptor_Interface_Association_t    Audio_Interface_Association; | ||||
|     // MIDI Audio Control Interface
 | ||||
|     USB_Descriptor_Interface_t                Audio_ControlInterface; | ||||
|     USB_Audio_Descriptor_Interface_AC_t       Audio_ControlInterface_SPC; | ||||
| 
 | ||||
|       // MIDI Audio Streaming Interface
 | ||||
|       USB_Descriptor_Interface_t                Audio_StreamInterface; | ||||
|       USB_MIDI_Descriptor_AudioInterface_AS_t   Audio_StreamInterface_SPC; | ||||
|       USB_MIDI_Descriptor_InputJack_t           MIDI_In_Jack_Emb; | ||||
|       USB_MIDI_Descriptor_InputJack_t           MIDI_In_Jack_Ext; | ||||
|       USB_MIDI_Descriptor_OutputJack_t          MIDI_Out_Jack_Emb; | ||||
|       USB_MIDI_Descriptor_OutputJack_t          MIDI_Out_Jack_Ext; | ||||
|       USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint; | ||||
|       USB_MIDI_Descriptor_Jack_Endpoint_t       MIDI_In_Jack_Endpoint_SPC; | ||||
|       USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint; | ||||
|       USB_MIDI_Descriptor_Jack_Endpoint_t       MIDI_Out_Jack_Endpoint_SPC; | ||||
|     // MIDI Audio Streaming Interface
 | ||||
|     USB_Descriptor_Interface_t                Audio_StreamInterface; | ||||
|     USB_MIDI_Descriptor_AudioInterface_AS_t   Audio_StreamInterface_SPC; | ||||
|     USB_MIDI_Descriptor_InputJack_t           MIDI_In_Jack_Emb; | ||||
|     USB_MIDI_Descriptor_InputJack_t           MIDI_In_Jack_Ext; | ||||
|     USB_MIDI_Descriptor_OutputJack_t          MIDI_Out_Jack_Emb; | ||||
|     USB_MIDI_Descriptor_OutputJack_t          MIDI_Out_Jack_Ext; | ||||
|     USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint; | ||||
|     USB_MIDI_Descriptor_Jack_Endpoint_t       MIDI_In_Jack_Endpoint_SPC; | ||||
|     USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint; | ||||
|     USB_MIDI_Descriptor_Jack_Endpoint_t       MIDI_Out_Jack_Endpoint_SPC; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef VIRTSER_ENABLE | ||||
|         USB_Descriptor_Interface_Association_t   CDC_Interface_Association; | ||||
|   USB_Descriptor_Interface_Association_t   CDC_Interface_Association; | ||||
| 
 | ||||
| 	// CDC Control Interface
 | ||||
| 	USB_Descriptor_Interface_t               CDC_CCI_Interface; | ||||
| @@ -208,8 +210,14 @@ typedef struct | ||||
| 
 | ||||
| #ifdef CONSOLE_ENABLE | ||||
| #   define CONSOLE_IN_EPNUM         (RAW_OUT_EPNUM + 1) | ||||
| //#   define CONSOLE_OUT_EPNUM        (RAW_OUT_EPNUM + 2)
 | ||||
| #ifdef PROTOCOL_CHIBIOS | ||||
| // ChibiOS has enough memory and descriptor to actually enable the endpoint
 | ||||
| // It could use the same endpoint numbers, as that's supported by ChibiOS
 | ||||
| // But the QMK code currently assumes that the endpoint numbers are different
 | ||||
| #   define CONSOLE_OUT_EPNUM        (RAW_OUT_EPNUM + 2) | ||||
| #else | ||||
| #   define CONSOLE_OUT_EPNUM        (RAW_OUT_EPNUM + 1) | ||||
| #endif | ||||
| #else | ||||
| #   define CONSOLE_OUT_EPNUM        RAW_OUT_EPNUM | ||||
| #endif | ||||
| @@ -241,27 +249,24 @@ typedef struct | ||||
| #   define CDC_OUT_EPNUM	MIDI_STREAM_OUT_EPNUM | ||||
| #endif | ||||
| 
 | ||||
| #if (defined(__AVR_ATmega32U2__) && CDC_OUT_EPNUM > 4) || \ | ||||
|     (defined(__AVR_ATmega32U4__) && CDC_OUT_EPNUM > 6) | ||||
| # error "Endpoints are not available enough to support all functions. Remove some in Makefile.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL)" | ||||
| #if (defined(PROTOCOL_LUFA) && CDC_OUT_EPNUM > (ENDPOINT_TOTAL_ENDPOINTS - 1)) || \ | ||||
|   (defined(PROTOCOL_CHIBIOS) && CDC_OUT_EPNUM > USB_MAX_ENDPOINTS) | ||||
| # error "There are not enough available endpoints to support all functions. Remove some in the rules.mk file.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL, STENO)" | ||||
| #endif | ||||
| 
 | ||||
| #define KEYBOARD_EPSIZE             8 | ||||
| #define MOUSE_EPSIZE                8 | ||||
| #define EXTRAKEY_EPSIZE             8 | ||||
| #define RAW_EPSIZE              	32 | ||||
| #define RAW_EPSIZE              	  32 | ||||
| #define CONSOLE_EPSIZE              32 | ||||
| #define NKRO_EPSIZE                 32 | ||||
| #define MIDI_STREAM_EPSIZE          64 | ||||
| #define CDC_NOTIFICATION_EPSIZE     8 | ||||
| #define CDC_NOTIFICATION_EPSIZE     32 | ||||
| #define CDC_EPSIZE                  16 | ||||
| 
 | ||||
| 
 | ||||
| uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | ||||
|                                     const uint16_t wIndex, | ||||
|                                     const void** const DescriptorAddress) | ||||
|                                     ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); | ||||
| 
 | ||||
| uint16_t get_usb_descriptor(const uint16_t wValue, | ||||
|                             const uint16_t wIndex, | ||||
|                             const void** const DescriptorAddress); | ||||
| 
 | ||||
| /* new API */ | ||||
| #if LUFA_VERSION_INTEGER < 0x140302 | ||||
		Reference in New Issue
	
	Block a user