]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Merge ChibiOS and LUFA descriptor support (#2362)
authorfredizzimo <fsundvik@gmail.com>
Thu, 8 Feb 2018 20:07:46 +0000 (22:07 +0200)
committerJack Humbert <jack.humb@gmail.com>
Thu, 8 Feb 2018 20:07:46 +0000 (15:07 -0500)
* 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

40 files changed:
build_keyboard.mk
keyboards/chibios_test/config.h
keyboards/chibios_test/stm32_f072_onekey/halconf.h
keyboards/chibios_test/stm32_f103_onekey/halconf.h
keyboards/chibios_test/teensy_lc_onekey/halconf.h
keyboards/clueboard/60/config.h
keyboards/ergodox_infinity/config.h
keyboards/infinity60/config.h
keyboards/infinity60/halconf.h
keyboards/jm60/config.h
keyboards/jm60/halconf.h
keyboards/whitefox/config.h
lib/chibios
lib/chibios-contrib
quantum/api/api_sysex.c
quantum/keymap.h
quantum/process_keycode/process_midi.c
quantum/process_keycode/process_midi.h
quantum/quantum.c
quantum/quantum.h
tmk_core/chibios.mk
tmk_core/common/host_driver.h
tmk_core/common/keyboard.c
tmk_core/common/report.h
tmk_core/protocol/chibios.mk
tmk_core/protocol/chibios/lufa_utils/LUFA/Drivers/USB/USB.h [new file with mode: 0644]
tmk_core/protocol/chibios/main.c
tmk_core/protocol/chibios/usb_main.c
tmk_core/protocol/chibios/usb_main.h
tmk_core/protocol/lufa.mk
tmk_core/protocol/lufa/descriptor.c [deleted file]
tmk_core/protocol/lufa/descriptor.h [deleted file]
tmk_core/protocol/lufa/lufa.c
tmk_core/protocol/lufa/lufa.h
tmk_core/protocol/midi.mk
tmk_core/protocol/midi/bytequeue/interrupt_setting.c
tmk_core/protocol/midi/qmk_midi.c [new file with mode: 0644]
tmk_core/protocol/midi/qmk_midi.h [new file with mode: 0644]
tmk_core/protocol/usb_descriptor.c [new file with mode: 0644]
tmk_core/protocol/usb_descriptor.h [new file with mode: 0644]

index bee8fcc8748a0a142bf1392632ee66b65ed203dd..921159a5dda896e6de91ffe2fed25dbf745b43a0 100644 (file)
@@ -121,7 +121,6 @@ else
 endif
 
 ifeq ($(PLATFORM),CHIBIOS)
-    include $(TMK_PATH)/protocol/chibios.mk
     include $(TMK_PATH)/chibios.mk
     OPT_OS = chibios
     ifneq ("$(wildcard $(KEYBOARD_PATH_5)/bootloader_defs.h)","")
@@ -197,7 +196,7 @@ else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.c)","")
     KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
 else ifneq ($(LAYOUTS),)
     include build_layout.mk
-else 
+else
     $(error Could not find keymap)
     # this state should never be reached
 endif
@@ -247,6 +246,10 @@ endif
     include $(TMK_PATH)/avr.mk
 endif
 
+ifeq ($(PLATFORM),CHIBIOS)
+    include $(TMK_PATH)/protocol/chibios.mk
+endif
+
 ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
     VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer
     VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer
index c32a77b37f72c4abf4c963ca6af3c7a5b0377761..89eb1f33b4d5964458ba76c91aca9730133609fe 100644 (file)
@@ -24,11 +24,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define DEVICE_VER      0x0001
 /* in python2: list(u"whatever".encode('utf-16-le')) */
 /*   at most 32 characters or the ugly hack in usb_main.c borks */
-#define MANUFACTURER "QMK"
-#define USBSTR_MANUFACTURER    'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', '\xc6', '\x00'
-#define PRODUCT "ChibiOS QMK test"
-#define USBSTR_PRODUCT         'C', '\x00', 'h', '\x00', 'i', '\x00', 'b', '\x00', 'i', '\x00', 'O', '\x00', 'S', '\x00', ' ', '\x00', 'Q', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', 't', '\x00', 'e', '\x00', 's', '\x00', 't', '\x00'
-#define DESCRIPTION "QMK keyboard firmware test for ChibiOS"
+#define MANUFACTURER QMK
+#define PRODUCT ChibiOS QMK test
+#define DESCRIPTION QMK keyboard firmware test for ChibiOS
 
 /* key matrix size */
 #define MATRIX_ROWS 1
index 1a450d632733ad9fa9ec83d36d64712bc7c78ce4..46b37a4f4696c192cd6c9d1ff5c983e4f0b5f0d8 100644 (file)
  * @brief   Enables the SERIAL over USB subsystem.
  */
 #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL_USB          FALSE
+#define HAL_USE_SERIAL_USB          TRUE
 #endif
 
 /**
index 1a450d632733ad9fa9ec83d36d64712bc7c78ce4..46b37a4f4696c192cd6c9d1ff5c983e4f0b5f0d8 100644 (file)
  * @brief   Enables the SERIAL over USB subsystem.
  */
 #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL_USB          FALSE
+#define HAL_USE_SERIAL_USB          TRUE
 #endif
 
 /**
index 0436408b09c67c186ba77ea1d0a5e1bbe6dea0b9..f7121f1a9056ba0572730a82817dd0652eaccf32 100644 (file)
  * @brief   Enables the SERIAL over USB subsystem.
  */
 #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL_USB          FALSE
+#define HAL_USE_SERIAL_USB          TRUE
 #endif
 
 /**
index 333698a0877b0b0ff8c4e4ff8b1ecd2a70136ab7..5c5a86296f954a67f1c3fbbd940368ccfa2993c2 100644 (file)
 #define VENDOR_ID       0xC1ED
 #define PRODUCT_ID      0x2350
 #define DEVICE_VER      0x0001
-#define MANUFACTURER    "Clueboard"
-#define USBSTR_MANUFACTURER 'C', '\x00', 'l', '\x00', 'u', '\x00', 'e', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00'
-#define PRODUCT         "Clueboard60"
-#define USBSTR_PRODUCT 'C', '\x00', 'l', '\x00', 'u', '\x00', 'e', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00', ' ', '\x00', '6', '\x00', '0', '\x00', '%', '\x00'
-#define DESCRIPTION     "Clueboard 60%"
+#define MANUFACTURER    Clueboard
+#define PRODUCT         Clueboard 60%
+#define DESCRIPTION     Clueboard 60%
 
 /* key matrix size */
 #define MATRIX_ROWS 5
index 094761e0b472d2e080abd0f01d9139229689a0bd..2f1be0d28288d63394047f22b72af8a9c34c396e 100644 (file)
@@ -23,12 +23,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define VENDOR_ID       0xFEED
 #define PRODUCT_ID      0x6464
 #define DEVICE_VER      0x0001
-/* in python2: list(u"whatever".encode('utf-16-le')) */
-/*   at most 32 characters or the ugly hack in usb_main.c borks */
-#define MANUFACTURER "TMK"
-#define USBSTR_MANUFACTURER    'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00'
-#define PRODUCT "Infinity keyboard/TMK"
-#define USBSTR_PRODUCT         'I', '\x00', 'n', '\x00', 'f', '\x00', 'i', '\x00', 'n', '\x00', 'i', '\x00', 't', '\x00', 'y', '\x00', ' ', '\x00', 'k', '\x00', 'e', '\x00', 'y', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00', '/', '\x00', 'T', '\x00', 'M', '\x00', 'K', '\x00'
+#define MANUFACTURER Input Club
+#define PRODUCT Ergodox Infinity (QMK)
 
 #define MOUSEKEY_INTERVAL       20
 #define MOUSEKEY_DELAY          0
index 83930901cb58051e4c10e60678b5ee83d4992be0..0a2f93e22bde53f5a527b4d859e6438131bdff0c 100644 (file)
@@ -26,10 +26,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define DEVICE_VER      0x0001
 /* in python2: list(u"whatever".encode('utf-16-le')) */
 /*   at most 32 characters or the ugly hack in usb_main.c borks */
-#define MANUFACTURER "Input Club"
-#define USBSTR_MANUFACTURER    'I', '\x00', 'n', '\x00', 'p', '\x00', 'u', '\x00', 't', '\x00', ' ', '\x00', 'C', '\x00', 'l', '\x00', 'u', '\x00', 'b', '\x00'
-#define PRODUCT "Infinity keyboard/QMK"
-#define USBSTR_PRODUCT         'I', '\x00', 'n', '\x00', 'f', '\x00', 'i', '\x00', 'n', '\x00', 'i', '\x00', 't', '\x00', 'y', '\x00', ' ', '\x00', 'k', '\x00', 'e', '\x00', 'y', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00', '/', '\x00', 'Q', '\x00', 'M', '\x00', 'K', '\x00'
+#define MANUFACTURER Input Club
+#define PRODUCT Infinity 60% keyboard (QMK)
 /* key matrix size */
 #define MATRIX_ROWS 9
 #define MATRIX_COLS 7
index f89dfc2e1ef026918564f4cb9c8aea1805cba030..b38031529881c096eb1c2c3cf1544a31603dfca2 100644 (file)
  * @brief   Enables the SERIAL over USB subsystem.
  */
 #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL_USB          FALSE
+#define HAL_USE_SERIAL_USB          TRUE
 #endif
 
 /**
index 2596413313edc299ec7e548c5cbf230fbbd1c351..847cf20780f00bfb52935350a2fe1d312b65d9bb 100644 (file)
@@ -26,11 +26,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define DEVICE_VER      0x0001
 /* in python2: list(u"whatever".encode('utf-16-le')) */
 /*   at most 32 characters or the ugly hack in usb_main.c borks */
-#define MANUFACTURER "JMWS"
-#define USBSTR_MANUFACTURER    'J', '\x00', 'M', '\x00', 'W', '\x00', 'S', '\x00'
-#define PRODUCT "JM60 RGB Keyboard(QMK)"
-#define USBSTR_PRODUCT 'J', '\x00', 'M', '\x00', '6', '\x00', '0', '\x00', ' ', '\x00', 'R', '\x00', 'G', '\x00', 'B', '\x00', ' ', '\x00', 'K', '\x00', 'e', '\x00', 'y', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00', '(', '\x00', 'Q', '\x00', 'M', '\x00', 'K', '\x00', ')', '\x00'
-#define DESCRIPTION "QMK keyboard firmware for JM60 RGB Keyboard"
+#define MANUFACTURER JMWS
+#define PRODUCT JM60 RGB Keyboard(QMK)
+#define DESCRIPTION QMK keyboard firmware for JM60 RGB Keyboard
 
 /* key matrix size */
 #define MATRIX_ROWS 5
index 1a450d632733ad9fa9ec83d36d64712bc7c78ce4..46b37a4f4696c192cd6c9d1ff5c983e4f0b5f0d8 100644 (file)
  * @brief   Enables the SERIAL over USB subsystem.
  */
 #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL_USB          FALSE
+#define HAL_USE_SERIAL_USB          TRUE
 #endif
 
 /**
index dc33a7ce5bc634b6a91f1b0e08e07d9a10179394..9397bd61f84eb0c79fa0f3a8d4022914d7e23819 100644 (file)
@@ -26,10 +26,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define DEVICE_VER      0x0001
 /* in python2: list(u"whatever".encode('utf-16-le')) */
 /*   at most 32 characters or the ugly hack in usb_main.c borks */
-#define MANUFACTURER "Input Club"
-#define USBSTR_MANUFACTURER    'I', '\x00', 'n', '\x00', 'p', '\x00', 'u', '\x00', 't', '\x00', ' ', '\x00', 'C', '\x00', 'l', '\x00', 'u', '\x00', 'b', '\x00'
-#define PRODUCT "WhiteFox/QMK"
-#define USBSTR_PRODUCT         'W', '\x00', 'h', '\x00', 'i', '\x00', 't', '\x00', 'e', '\x00', 'F', '\x00', 'o', '\x00', 'x', '\x00', ' ', '\x00'
+#define MANUFACTURER Input Club
+#define PRODUCT WhiteFox (QMK)
 
 /* key matrix size */
 #define MATRIX_ROWS 9
@@ -81,4 +79,4 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //#define NO_ACTION_MACRO
 //#define NO_ACTION_FUNCTION
 
-#endif
\ No newline at end of file
+#endif
index e26cb16a7296a196d7c74eae22cbee00989cb7b6..587968d6cbc2b0e1c7147540872f2a67e59ca18b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit e26cb16a7296a196d7c74eae22cbee00989cb7b6
+Subproject commit 587968d6cbc2b0e1c7147540872f2a67e59ca18b
index 432bc1762f17eb7b506e8fbca8ec30a3d61629b8..ede48346eee4b8d6847c19bc01420bee76a5e486 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 432bc1762f17eb7b506e8fbca8ec30a3d61629b8
+Subproject commit ede48346eee4b8d6847c19bc01420bee76a5e486
index 6a2ee90124a0a38eb5f00f531712eab3ac826b2d..89c66a2a20d026f3d064b68c16f78d39315829c4 100644 (file)
@@ -16,6 +16,7 @@
 #include "api_sysex.h"
 #include "sysex_tools.h"
 #include "print.h"
+#include "qmk_midi.h"
 
 void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) {
     // SEND_STRING("\nTX: ");
index 5d64be19c87f0c1bd2e15ad53c7bfe36a35ecdd5..bfcb2f7cd517d861c032951f351da510c399c8f5 100644 (file)
@@ -23,6 +23,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "action.h"
 #if defined(__AVR__)
 #include <avr/pgmspace.h>
+#elif defined PROTOCOL_CHIBIOS
+//We need to ensure that chibios is include before redefining reset
+#include "ch.h"
 #endif
 #include "keycode.h"
 #include "action_macro.h"
index 9184feaae846027500a1d302592567e00e825f96..9728076dfd3d58b063d14a339608b2a44d977a6c 100644 (file)
 #include "process_midi.h"
 
 #ifdef MIDI_ENABLE
+#include <LUFA/Drivers/USB/USB.h>
 #include "midi.h"
+#include "qmk_midi.h"
 
 #ifdef MIDI_BASIC
 
-void process_midi_basic_noteon(uint8_t note) 
+void process_midi_basic_noteon(uint8_t note)
 {
     midi_send_noteon(&midi_device, 0, note, 128);
 }
@@ -46,6 +48,7 @@ static uint8_t tone_status[MIDI_TONE_COUNT];
 static uint8_t midi_modulation;
 static int8_t midi_modulation_step;
 static uint16_t midi_modulation_timer;
+midi_config_t midi_config;
 
 inline uint8_t compute_velocity(uint8_t setting)
 {
@@ -70,30 +73,6 @@ void midi_init(void)
     midi_modulation_timer = 0;
 }
 
-void midi_task(void)
-{
-    if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
-        return;
-    midi_modulation_timer = timer_read();
-
-    if (midi_modulation_step != 0)
-    {
-        dprintf("midi modulation %d\n", midi_modulation);
-        midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
-
-        if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
-            midi_modulation = 0;
-            midi_modulation_step = 0;
-            return;
-        }
-
-        midi_modulation += midi_modulation_step;
-
-        if (midi_modulation > 127)
-            midi_modulation = 127;
-    }
-}
-
 uint8_t midi_compute_note(uint16_t keycode)
 {
     return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose;
@@ -250,4 +229,33 @@ bool process_midi(uint16_t keycode, keyrecord_t *record)
 
 #endif // MIDI_ADVANCED
 
+void midi_task(void)
+{
+    midi_device_process(&midi_device);
+#ifdef MIDI_ADVANCED
+    if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
+        return;
+    midi_modulation_timer = timer_read();
+
+    if (midi_modulation_step != 0)
+    {
+        dprintf("midi modulation %d\n", midi_modulation);
+        midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
+
+        if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
+            midi_modulation = 0;
+            midi_modulation_step = 0;
+            return;
+        }
+
+        midi_modulation += midi_modulation_step;
+
+        if (midi_modulation > 127)
+            midi_modulation = 127;
+    }
+#endif
+}
+
+
+
 #endif // MIDI_ENABLE
index ccac8981a6e4850ca64385f5fc9658fd2b87e184..1968fbe3fa9b9d847f207a6211af359690eb4cf1 100644 (file)
@@ -27,6 +27,8 @@ void process_midi_basic_noteoff(uint8_t note);
 void process_midi_all_notes_off(void);
 #endif
 
+void midi_task(void);
+
 #ifdef MIDI_ADVANCED
 typedef union {
   uint32_t raw;
@@ -39,10 +41,9 @@ typedef union {
   };
 } midi_config_t;
 
-midi_config_t midi_config;
+extern midi_config_t midi_config;
 
 void midi_init(void);
-void midi_task(void);
 bool process_midi(uint16_t keycode, keyrecord_t *record);
 
 #define MIDI_INVALID_NOTE 0xFF
index d3685f50b86499fb5da139d7c81839e5dc405107..bd95d5ea80881b9b6317a59c0ab054a9f9975546 100644 (file)
@@ -34,6 +34,14 @@ extern backlight_config_t backlight_config;
 #include "fauxclicky.h"
 #endif
 
+#ifdef API_ENABLE
+#include "api.h"
+#endif
+
+#ifdef MIDI_ENABLE
+#include "process_midi.h"
+#endif
+
 #ifdef AUDIO_ENABLE
   #ifndef GOODBYE_SONG
     #define GOODBYE_SONG SONG(GOODBYE_SOUND)
index 6ca5ecb5cf5966555227660c1c8ad5b32152594c..b4c9e0b894c48acae66226af33d9e11ad62a3296 100644 (file)
@@ -49,7 +49,6 @@ extern uint32_t default_layer_state;
 #endif
 
 #ifdef MIDI_ENABLE
-       #include <lufa.h>
 #ifdef MIDI_ADVANCED
        #include "process_midi.h"
 #endif
index 1cd0146fe088610c8b7ef5a51c2209f19c72bbd9..7c7f658b25a2e0fee825f0df504950fcf3b8256d 100644 (file)
@@ -149,6 +149,7 @@ COMPILEFLAGS += -falign-functions=16
 COMPILEFLAGS += -ffunction-sections
 COMPILEFLAGS += -fdata-sections
 COMPILEFLAGS += -fno-common
+COMPILEFLAGS += -fshort-wchar
 COMPILEFLAGS += $(THUMBFLAGS)
 
 CFLAGS += $(COMPILEFLAGS)
@@ -159,6 +160,7 @@ CPPFLAGS += $(COMPILEFLAGS)
 CPPFLAGS += -fno-rtti
 
 LDFLAGS +=-Wl,--gc-sections
+LDFLAGS +=-Wl,--no-wchar-size-warning
 LDFLAGS += -mno-thumb-interwork -mthumb
 LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE)
 LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE)
index 588d1c0be8f304214b2a12e70f5870c6781039df..e40f0bfd65900a335b5edfd07c839f83fbb33f86 100644 (file)
@@ -30,11 +30,6 @@ typedef struct {
     void (*send_mouse)(report_mouse_t *);
     void (*send_system)(uint16_t);
     void (*send_consumer)(uint16_t);
-#ifdef MIDI_ENABLE
-    void (*usb_send_func)(MidiDevice *, uint16_t, uint8_t, uint8_t, uint8_t);
-    void (*usb_get_midi)(MidiDevice *);
-    void (*midi_usb_init)(MidiDevice *);
-#endif
 } host_driver_t;
 
 #endif
index 436fb6073475d0f6774d901e1ae4fb75915952ac..001fb00ce52f0981e1e15f96be9df92a221799ab 100644 (file)
@@ -66,6 +66,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifdef POINTING_DEVICE_ENABLE
 #   include "pointing_device.h"
 #endif
+#ifdef MIDI_ENABLE
+#   include "process_midi.h"
+#endif
 
 #ifdef MATRIX_HAS_GHOST
 extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
@@ -260,6 +263,10 @@ MATRIX_LOOP_END:
     pointing_device_task();
 #endif
 
+#ifdef MIDI_ENABLE
+    midi_task();
+#endif
+
     // update LED
     if (led_status != host_keyboard_leds()) {
         led_status = host_keyboard_leds();
index a0811f9a3c8d20f8fade80a9b0eed2078adf3cad..6c27eb9dc6509b4052f97e21c01b16357c005f7a 100644 (file)
@@ -73,22 +73,20 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 /* key report size(NKRO or boot mode) */
-#if defined(PROTOCOL_PJRC) && defined(NKRO_ENABLE)
-#   include "usb.h"
-#   define KEYBOARD_REPORT_SIZE KBD2_SIZE
-#   define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
-#   define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
-
-#elif defined(PROTOCOL_LUFA) && defined(NKRO_ENABLE)
-#   include "protocol/lufa/descriptor.h"
-#   define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
-#   define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
-#   define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
-#elif defined(PROTOCOL_CHIBIOS) && defined(NKRO_ENABLE)
-#   include "protocol/chibios/usb_main.h"
-#   define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
-#   define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
-#   define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
+#if defined(NKRO_ENABLE)
+  #if defined(PROTOCOL_PJRC)
+    #include "usb.h"
+    #define KEYBOARD_REPORT_SIZE KBD2_SIZE
+    #define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
+    #define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
+  #elif defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
+    #include "protocol/usb_descriptor.h"
+    #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
+    #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
+    #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
+  #else
+    #error "NKRO not supported with this protocol"
+#endif
 
 #else
 #   define KEYBOARD_REPORT_SIZE 8
index 3f4e0a71fc85c7710588ee564026f6967285c223..6e7cfbd83298a61eb15deb0adfb7125e11528481 100644 (file)
@@ -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
 
diff --git a/tmk_core/protocol/chibios/lufa_utils/LUFA/Drivers/USB/USB.h b/tmk_core/protocol/chibios/lufa_utils/LUFA/Drivers/USB/USB.h
new file mode 100644 (file)
index 0000000..a5374d8
--- /dev/null
@@ -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"
index 47a7eb09abc1a19ea49bc8db0744b7910f20fc8b..f2abc438d47d45d36976982bd540052957c52b13 100644 (file)
@@ -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
   }
 }
index caa2770b5c53f5ecd08b6241ee3946aca2f9e587..f980024ab80d2e2a277b7430131818cd59c74ab5 100644 (file)
@@ -28,6 +28,7 @@
 #include "led.h"
 #endif
 #include "wait.h"
+#include "usb_descriptor.h"
 
 #ifdef NKRO_ENABLE
   #include "keycode_config.h"
@@ -63,24 +64,12 @@ report_mouse_t mouse_report_blank = {0};
 uint8_t extra_report_blank[3] = {0};
 #endif /* EXTRAKEY_ENABLE */
 
-#ifdef CONSOLE_ENABLE
-/* The emission buffers queue */
-output_buffers_queue_t console_buf_queue;
-static uint8_t console_queue_buffer[BQ_BUFFER_SIZE(CONSOLE_QUEUE_CAPACITY, CONSOLE_EPSIZE)];
-
-static virtual_timer_t console_flush_timer;
-void console_queue_onotify(io_buffers_queue_t *bqp);
-static void console_flush_cb(void *arg);
-#endif /* CONSOLE_ENABLE */
-
 /* ---------------------------------------------------------
  *            Descriptors and USB driver objects
  * ---------------------------------------------------------
  */
 
 /* HID specific constants */
-#define USB_DESCRIPTOR_HID 0x21
-#define USB_DESCRIPTOR_HID_REPORT 0x22
 #define HID_GET_REPORT 0x01
 #define HID_GET_IDLE 0x02
 #define HID_GET_PROTOCOL 0x03
@@ -88,593 +77,21 @@ static void console_flush_cb(void *arg);
 #define HID_SET_IDLE 0x0A
 #define HID_SET_PROTOCOL 0x0B
 
-/* USB Device Descriptor */
-static const uint8_t usb_device_descriptor_data[] = {
-  USB_DESC_DEVICE(0x0200,      // bcdUSB (1.1)
-                  0,           // bDeviceClass (defined in later in interface)
-                  0,           // bDeviceSubClass
-                  0,           // bDeviceProtocol
-                  64,          // bMaxPacketSize (64 bytes) (the driver didn't work with 32)
-                  VENDOR_ID,   // idVendor
-                  PRODUCT_ID,  // idProduct
-                  DEVICE_VER,      // bcdDevice
-                  1,           // iManufacturer
-                  2,           // iProduct
-                  3,           // iSerialNumber
-                  1)           // bNumConfigurations
-};
-
-/* Device Descriptor wrapper */
-static const USBDescriptor usb_device_descriptor = {
-  sizeof usb_device_descriptor_data,
-  usb_device_descriptor_data
-};
-
-/*
- * HID Report Descriptor
- *
- * See "Device Class Definition for Human Interface Devices (HID)"
- * (http://www.usb.org/developers/hidpage/HID1_11.pdf) for the
- * detailed descrition of all the fields
- */
-
-/* Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 */
-static const uint8_t keyboard_hid_report_desc_data[] = {
-  0x05, 0x01,                // Usage Page (Generic Desktop),
-  0x09, 0x06,                // Usage (Keyboard),
-  0xA1, 0x01,                // Collection (Application),
-  0x75, 0x01,                //   Report Size (1),
-  0x95, 0x08,                //   Report Count (8),
-  0x05, 0x07,                //   Usage Page (Key Codes),
-  0x19, 0xE0,                //   Usage Minimum (224),
-  0x29, 0xE7,                //   Usage Maximum (231),
-  0x15, 0x00,                //   Logical Minimum (0),
-  0x25, 0x01,                //   Logical Maximum (1),
-  0x81, 0x02,                //   Input (Data, Variable, Absolute), ;Modifier byte
-  0x95, 0x01,                //   Report Count (1),
-  0x75, 0x08,                //   Report Size (8),
-  0x81, 0x03,                //   Input (Constant),                 ;Reserved byte
-  0x95, 0x05,                //   Report Count (5),
-  0x75, 0x01,                //   Report Size (1),
-  0x05, 0x08,                //   Usage Page (LEDs),
-  0x19, 0x01,                //   Usage Minimum (1),
-  0x29, 0x05,                //   Usage Maximum (5),
-  0x91, 0x02,                //   Output (Data, Variable, Absolute), ;LED report
-  0x95, 0x01,                //   Report Count (1),
-  0x75, 0x03,                //   Report Size (3),
-  0x91, 0x03,                //   Output (Constant),                 ;LED report padding
-  0x95, KBD_REPORT_KEYS,          //   Report Count (),
-  0x75, 0x08,                //   Report Size (8),
-  0x15, 0x00,                //   Logical Minimum (0),
-  0x26, 0xFF, 0x00,          //   Logical Maximum(255),
-  0x05, 0x07,                //   Usage Page (Key Codes),
-  0x19, 0x00,                //   Usage Minimum (0),
-  0x29, 0xFF,                //   Usage Maximum (255),
-  0x81, 0x00,                //   Input (Data, Array),
-  0xc0                       // End Collection
-};
-/* wrapper */
-static const USBDescriptor keyboard_hid_report_descriptor = {
-  sizeof keyboard_hid_report_desc_data,
-  keyboard_hid_report_desc_data
-};
-
-#ifdef NKRO_ENABLE
-static const uint8_t nkro_hid_report_desc_data[] = {
-  0x05, 0x01,                           // Usage Page (Generic Desktop),
-  0x09, 0x06,                           // Usage (Keyboard),
-  0xA1, 0x01,                           // Collection (Application),
-  // bitmap of modifiers
-  0x75, 0x01,                           //   Report Size (1),
-  0x95, 0x08,                           //   Report Count (8),
-  0x05, 0x07,                           //   Usage Page (Key Codes),
-  0x19, 0xE0,                           //   Usage Minimum (224),
-  0x29, 0xE7,                           //   Usage Maximum (231),
-  0x15, 0x00,                           //   Logical Minimum (0),
-  0x25, 0x01,                           //   Logical Maximum (1),
-  0x81, 0x02,                           //   Input (Data, Variable, Absolute), ;Modifier byte
-  // LED output report
-  0x95, 0x05,                           //   Report Count (5),
-  0x75, 0x01,                           //   Report Size (1),
-  0x05, 0x08,                           //   Usage Page (LEDs),
-  0x19, 0x01,                           //   Usage Minimum (1),
-  0x29, 0x05,                           //   Usage Maximum (5),
-  0x91, 0x02,                           //   Output (Data, Variable, Absolute),
-  0x95, 0x01,                           //   Report Count (1),
-  0x75, 0x03,                           //   Report Size (3),
-  0x91, 0x03,                           //   Output (Constant),
-  // bitmap of keys
-  0x95, NKRO_REPORT_KEYS * 8,           //   Report Count (),
-  0x75, 0x01,                           //   Report Size (1),
-  0x15, 0x00,                           //   Logical Minimum (0),
-  0x25, 0x01,                           //   Logical Maximum(1),
-  0x05, 0x07,                           //   Usage Page (Key Codes),
-  0x19, 0x00,                           //   Usage Minimum (0),
-  0x29, NKRO_REPORT_KEYS * 8 - 1,       //   Usage Maximum (),
-  0x81, 0x02,                           //   Input (Data, Variable, Absolute),
-  0xc0                                  // End Collection
-};
-/* wrapper */
-static const USBDescriptor nkro_hid_report_descriptor = {
-  sizeof nkro_hid_report_desc_data,
-  nkro_hid_report_desc_data
-};
-#endif /* NKRO_ENABLE */
-
-#ifdef MOUSE_ENABLE
-/* Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
- * http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
- * http://www.keil.com/forum/15671/
- * http://www.microsoft.com/whdc/device/input/wheel.mspx */
-static const uint8_t mouse_hid_report_desc_data[] = {
-  /* mouse */
-  0x05, 0x01,                      // USAGE_PAGE (Generic Desktop)
-  0x09, 0x02,                      // USAGE (Mouse)
-  0xa1, 0x01,                      // COLLECTION (Application)
-  //0x85, REPORT_ID_MOUSE,         //   REPORT_ID (1)
-  0x09, 0x01,                      //   USAGE (Pointer)
-  0xa1, 0x00,                      //   COLLECTION (Physical)
-                                   // ----------------------------  Buttons
-  0x05, 0x09,                      //     USAGE_PAGE (Button)
-  0x19, 0x01,                      //     USAGE_MINIMUM (Button 1)
-  0x29, 0x05,                      //     USAGE_MAXIMUM (Button 5)
-  0x15, 0x00,                      //     LOGICAL_MINIMUM (0)
-  0x25, 0x01,                      //     LOGICAL_MAXIMUM (1)
-  0x75, 0x01,                      //     REPORT_SIZE (1)
-  0x95, 0x05,                      //     REPORT_COUNT (5)
-  0x81, 0x02,                      //     INPUT (Data,Var,Abs)
-  0x75, 0x03,                      //     REPORT_SIZE (3)
-  0x95, 0x01,                      //     REPORT_COUNT (1)
-  0x81, 0x03,                      //     INPUT (Cnst,Var,Abs)
-                                   // ----------------------------  X,Y position
-  0x05, 0x01,                      //     USAGE_PAGE (Generic Desktop)
-  0x09, 0x30,                      //     USAGE (X)
-  0x09, 0x31,                      //     USAGE (Y)
-  0x15, 0x81,                      //     LOGICAL_MINIMUM (-127)
-  0x25, 0x7f,                      //     LOGICAL_MAXIMUM (127)
-  0x75, 0x08,                      //     REPORT_SIZE (8)
-  0x95, 0x02,                      //     REPORT_COUNT (2)
-  0x81, 0x06,                      //     INPUT (Data,Var,Rel)
-                                   // ----------------------------  Vertical wheel
-  0x09, 0x38,                      //     USAGE (Wheel)
-  0x15, 0x81,                      //     LOGICAL_MINIMUM (-127)
-  0x25, 0x7f,                      //     LOGICAL_MAXIMUM (127)
-  0x35, 0x00,                      //     PHYSICAL_MINIMUM (0)        - reset physical
-  0x45, 0x00,                      //     PHYSICAL_MAXIMUM (0)
-  0x75, 0x08,                      //     REPORT_SIZE (8)
-  0x95, 0x01,                      //     REPORT_COUNT (1)
-  0x81, 0x06,                      //     INPUT (Data,Var,Rel)
-                                   // ----------------------------  Horizontal wheel
-  0x05, 0x0c,                      //     USAGE_PAGE (Consumer Devices)
-  0x0a, 0x38, 0x02,                //     USAGE (AC Pan)
-  0x15, 0x81,                      //     LOGICAL_MINIMUM (-127)
-  0x25, 0x7f,                      //     LOGICAL_MAXIMUM (127)
-  0x75, 0x08,                      //     REPORT_SIZE (8)
-  0x95, 0x01,                      //     REPORT_COUNT (1)
-  0x81, 0x06,                      //     INPUT (Data,Var,Rel)
-  0xc0,                            //   END_COLLECTION
-  0xc0,                            // END_COLLECTION
-};
-/* wrapper */
-static const USBDescriptor mouse_hid_report_descriptor = {
-  sizeof mouse_hid_report_desc_data,
-  mouse_hid_report_desc_data
-};
-#endif /* MOUSE_ENABLE */
-
-#ifdef CONSOLE_ENABLE
-static const uint8_t console_hid_report_desc_data[] = {
-  0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
-  0x09, 0x74,       // Usage 0x74
-  0xA1, 0x53,       // Collection 0x53
-  0x75, 0x08,       // report size = 8 bits
-  0x15, 0x00,       // logical minimum = 0
-  0x26, 0xFF, 0x00, // logical maximum = 255
-  0x95, CONSOLE_EPSIZE, // report count
-  0x09, 0x75,       // usage
-  0x81, 0x02,       // Input (array)
-  0xC0              // end collection
-};
-/* wrapper */
-static const USBDescriptor console_hid_report_descriptor = {
-  sizeof console_hid_report_desc_data,
-  console_hid_report_desc_data
-};
-#endif /* CONSOLE_ENABLE */
-
-#ifdef EXTRAKEY_ENABLE
-/* audio controls & system controls
- * http://www.microsoft.com/whdc/archive/w2kbd.mspx */
-static const uint8_t extra_hid_report_desc_data[] = {
-  /* system control */
-  0x05, 0x01,                      // USAGE_PAGE (Generic Desktop)
-  0x09, 0x80,                      // USAGE (System Control)
-  0xa1, 0x01,                      // COLLECTION (Application)
-  0x85, REPORT_ID_SYSTEM,          //   REPORT_ID (2)
-  0x15, 0x01,                      //   LOGICAL_MINIMUM (0x1)
-  0x25, 0xb7,                      //   LOGICAL_MAXIMUM (0xb7)
-  0x19, 0x01,                      //   USAGE_MINIMUM (0x1)
-  0x29, 0xb7,                      //   USAGE_MAXIMUM (0xb7)
-  0x75, 0x10,                      //   REPORT_SIZE (16)
-  0x95, 0x01,                      //   REPORT_COUNT (1)
-  0x81, 0x00,                      //   INPUT (Data,Array,Abs)
-  0xc0,                            // END_COLLECTION
-  /* consumer */
-  0x05, 0x0c,                      // USAGE_PAGE (Consumer Devices)
-  0x09, 0x01,                      // USAGE (Consumer Control)
-  0xa1, 0x01,                      // COLLECTION (Application)
-  0x85, REPORT_ID_CONSUMER,        //   REPORT_ID (3)
-  0x15, 0x01,                      //   LOGICAL_MINIMUM (0x1)
-  0x26, 0x9c, 0x02,                //   LOGICAL_MAXIMUM (0x29c)
-  0x19, 0x01,                      //   USAGE_MINIMUM (0x1)
-  0x2a, 0x9c, 0x02,                //   USAGE_MAXIMUM (0x29c)
-  0x75, 0x10,                      //   REPORT_SIZE (16)
-  0x95, 0x01,                      //   REPORT_COUNT (1)
-  0x81, 0x00,                      //   INPUT (Data,Array,Abs)
-  0xc0,                            // END_COLLECTION
-};
-/* wrapper */
-static const USBDescriptor extra_hid_report_descriptor = {
-  sizeof extra_hid_report_desc_data,
-  extra_hid_report_desc_data
-};
-#endif /* EXTRAKEY_ENABLE */
-
-
-/*
- * Configuration Descriptor tree for a HID device
- *
- * The HID Specifications version 1.11 require the following order:
- * - Configuration Descriptor
- * - Interface Descriptor
- * - HID Descriptor
- * - Endpoints Descriptors
- */
-#define KBD_HID_DESC_NUM                0
-#define KBD_HID_DESC_OFFSET             (9 + (9 + 9 + 7) * KBD_HID_DESC_NUM + 9)
-
-#ifdef MOUSE_ENABLE
-#   define MOUSE_HID_DESC_NUM           (KBD_HID_DESC_NUM + 1)
-#   define MOUSE_HID_DESC_OFFSET        (9 + (9 + 9 + 7) * MOUSE_HID_DESC_NUM + 9)
-#else /* MOUSE_ENABLE */
-#   define MOUSE_HID_DESC_NUM           (KBD_HID_DESC_NUM + 0)
-#endif /* MOUSE_ENABLE */
-
-#ifdef CONSOLE_ENABLE
-#define CONSOLE_HID_DESC_NUM            (MOUSE_HID_DESC_NUM + 1)
-#define CONSOLE_HID_DESC_OFFSET         (9 + (9 + 9 + 7) * CONSOLE_HID_DESC_NUM + 9)
-#else /* CONSOLE_ENABLE */
-#   define CONSOLE_HID_DESC_NUM         (MOUSE_HID_DESC_NUM + 0)
-#endif /* CONSOLE_ENABLE */
-
-#ifdef EXTRAKEY_ENABLE
-#   define EXTRA_HID_DESC_NUM           (CONSOLE_HID_DESC_NUM + 1)
-#   define EXTRA_HID_DESC_OFFSET        (9 + (9 + 9 + 7) * EXTRA_HID_DESC_NUM + 9)
-#else /* EXTRAKEY_ENABLE */
-#   define EXTRA_HID_DESC_NUM           (CONSOLE_HID_DESC_NUM + 0)
-#endif /* EXTRAKEY_ENABLE */
-
-#ifdef NKRO_ENABLE
-#   define NKRO_HID_DESC_NUM            (EXTRA_HID_DESC_NUM + 1)
-#   define NKRO_HID_DESC_OFFSET         (9 + (9 + 9 + 7) * EXTRA_HID_DESC_NUM + 9)
-#else /* NKRO_ENABLE */
-#   define NKRO_HID_DESC_NUM            (EXTRA_HID_DESC_NUM + 0)
-#endif /* NKRO_ENABLE */
-
-#define NUM_INTERFACES                  (NKRO_HID_DESC_NUM + 1)
-#define CONFIG1_DESC_SIZE               (9 + (9 + 9 + 7) * NUM_INTERFACES)
-
-static const uint8_t hid_configuration_descriptor_data[] = {
-  /* Configuration Descriptor (9 bytes) USB spec 9.6.3, page 264-266, Table 9-10 */
-  USB_DESC_CONFIGURATION(CONFIG1_DESC_SIZE, // wTotalLength
-                         NUM_INTERFACES,    // bNumInterfaces
-                         1,    // bConfigurationValue
-                         0,    // iConfiguration
-                         0xA0, // bmAttributes (RESERVED|REMOTEWAKEUP)
-                         50),  // bMaxPower (50mA)
-
-  /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
-  USB_DESC_INTERFACE(KBD_INTERFACE,        // bInterfaceNumber
-                     0,        // bAlternateSetting
-                     1,        // bNumEndpoints
-                     0x03,     // bInterfaceClass: HID
-                     0x01,     // bInterfaceSubClass: Boot
-                     0x01,     // bInterfaceProtocol: Keyboard
-                     0),       // iInterface
-
-  /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
-  USB_DESC_BYTE(9),            // bLength
-  USB_DESC_BYTE(0x21),         // bDescriptorType (HID class)
-  USB_DESC_BCD(0x0111),        // bcdHID: HID version 1.11
-  USB_DESC_BYTE(0),            // bCountryCode
-  USB_DESC_BYTE(1),            // bNumDescriptors
-  USB_DESC_BYTE(0x22),         // bDescriptorType (report desc)
-  USB_DESC_WORD(sizeof(keyboard_hid_report_desc_data)), // wDescriptorLength
-
-  /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
-  USB_DESC_ENDPOINT(KBD_ENDPOINT | 0x80,  // bEndpointAddress
-                    0x03,      // bmAttributes (Interrupt)
-                    KBD_EPSIZE,// wMaxPacketSize
-                    10),       // bInterval
-
-  #ifdef MOUSE_ENABLE
-  /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
-  USB_DESC_INTERFACE(MOUSE_INTERFACE,   // bInterfaceNumber
-                     0,        // bAlternateSetting
-                     1,        // bNumEndpoints
-                     0x03,     // bInterfaceClass (0x03 = HID)
-                     // ThinkPad T23 BIOS doesn't work with boot mouse.
-                     0x00,     // bInterfaceSubClass (0x01 = Boot)
-                     0x00,     // bInterfaceProtocol (0x02 = Mouse)
-                     /*
-                        0x01,      // bInterfaceSubClass (0x01 = Boot)
-                        0x02,      // bInterfaceProtocol (0x02 = Mouse)
-                      */
-                     0),        // iInterface
-
-  /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
-  USB_DESC_BYTE(9),            // bLength
-  USB_DESC_BYTE(0x21),         // bDescriptorType (HID class)
-  USB_DESC_BCD(0x0111),        // bcdHID: HID version 1.11
-  USB_DESC_BYTE(0),            // bCountryCode
-  USB_DESC_BYTE(1),            // bNumDescriptors
-  USB_DESC_BYTE(0x22),         // bDescriptorType (report desc)
-  USB_DESC_WORD(sizeof(mouse_hid_report_desc_data)), // wDescriptorLength
-
-  /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
-  USB_DESC_ENDPOINT(MOUSE_ENDPOINT | 0x80,  // bEndpointAddress
-                    0x03,      // bmAttributes (Interrupt)
-                    MOUSE_EPSIZE,  // wMaxPacketSize
-                    1),        // bInterval
-  #endif /* MOUSE_ENABLE */
-
-  #ifdef CONSOLE_ENABLE
-  /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
-  USB_DESC_INTERFACE(CONSOLE_INTERFACE, // bInterfaceNumber
-                     0,        // bAlternateSetting
-                     1,        // bNumEndpoints
-                     0x03,     // bInterfaceClass: HID
-                     0x00,     // bInterfaceSubClass: None
-                     0x00,     // bInterfaceProtocol: None
-                     0),       // iInterface
-
-  /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
-  USB_DESC_BYTE(9),            // bLength
-  USB_DESC_BYTE(0x21),         // bDescriptorType (HID class)
-  USB_DESC_BCD(0x0111),        // bcdHID: HID version 1.11
-  USB_DESC_BYTE(0),            // bCountryCode
-  USB_DESC_BYTE(1),            // bNumDescriptors
-  USB_DESC_BYTE(0x22),         // bDescriptorType (report desc)
-  USB_DESC_WORD(sizeof(console_hid_report_desc_data)), // wDescriptorLength
-
-  /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
-  USB_DESC_ENDPOINT(CONSOLE_ENDPOINT | 0x80,  // bEndpointAddress
-                    0x03,      // bmAttributes (Interrupt)
-                    CONSOLE_EPSIZE, // wMaxPacketSize
-                    1),        // bInterval
-  #endif /* CONSOLE_ENABLE */
-
-  #ifdef EXTRAKEY_ENABLE
-  /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
-  USB_DESC_INTERFACE(EXTRA_INTERFACE, // bInterfaceNumber
-                     0,        // bAlternateSetting
-                     1,        // bNumEndpoints
-                     0x03,     // bInterfaceClass: HID
-                     0x00,     // bInterfaceSubClass: None
-                     0x00,     // bInterfaceProtocol: None
-                     0),       // iInterface
-
-  /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
-  USB_DESC_BYTE(9),            // bLength
-  USB_DESC_BYTE(0x21),         // bDescriptorType (HID class)
-  USB_DESC_BCD(0x0111),        // bcdHID: HID version 1.11
-  USB_DESC_BYTE(0),            // bCountryCode
-  USB_DESC_BYTE(1),            // bNumDescriptors
-  USB_DESC_BYTE(0x22),         // bDescriptorType (report desc)
-  USB_DESC_WORD(sizeof(extra_hid_report_desc_data)), // wDescriptorLength
-
-  /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
-  USB_DESC_ENDPOINT(EXTRA_ENDPOINT | 0x80,  // bEndpointAddress
-                    0x03,      // bmAttributes (Interrupt)
-                    EXTRA_EPSIZE, // wMaxPacketSize
-                    10),       // bInterval
-  #endif /* EXTRAKEY_ENABLE */
-
-  #ifdef NKRO_ENABLE
-  /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
-  USB_DESC_INTERFACE(NKRO_INTERFACE, // bInterfaceNumber
-                     0,        // bAlternateSetting
-                     1,        // bNumEndpoints
-                     0x03,     // bInterfaceClass: HID
-                     0x00,     // bInterfaceSubClass: None
-                     0x00,     // bInterfaceProtocol: None
-                     0),       // iInterface
-
-  /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
-  USB_DESC_BYTE(9),            // bLength
-  USB_DESC_BYTE(0x21),         // bDescriptorType (HID class)
-  USB_DESC_BCD(0x0111),        // bcdHID: HID version 1.11
-  USB_DESC_BYTE(0),            // bCountryCode
-  USB_DESC_BYTE(1),            // bNumDescriptors
-  USB_DESC_BYTE(0x22),         // bDescriptorType (report desc)
-  USB_DESC_WORD(sizeof(nkro_hid_report_desc_data)), // wDescriptorLength
-
-  /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
-  USB_DESC_ENDPOINT(NKRO_ENDPOINT | 0x80,  // bEndpointAddress
-                    0x03,      // bmAttributes (Interrupt)
-                    NKRO_EPSIZE, // wMaxPacketSize
-                    1),       // bInterval
-  #endif /* NKRO_ENABLE */
-};
-
-/* Configuration Descriptor wrapper */
-static const USBDescriptor hid_configuration_descriptor = {
-  sizeof hid_configuration_descriptor_data,
-  hid_configuration_descriptor_data
-};
-
-/* wrappers */
-#define HID_DESCRIPTOR_SIZE 9
-static const USBDescriptor keyboard_hid_descriptor = {
-  HID_DESCRIPTOR_SIZE,
-  &hid_configuration_descriptor_data[KBD_HID_DESC_OFFSET]
-};
-#ifdef MOUSE_ENABLE
-static const USBDescriptor mouse_hid_descriptor = {
-  HID_DESCRIPTOR_SIZE,
-  &hid_configuration_descriptor_data[MOUSE_HID_DESC_OFFSET]
-};
-#endif /* MOUSE_ENABLE */
-#ifdef CONSOLE_ENABLE
-static const USBDescriptor console_hid_descriptor = {
-  HID_DESCRIPTOR_SIZE,
-  &hid_configuration_descriptor_data[CONSOLE_HID_DESC_OFFSET]
-};
-#endif /* CONSOLE_ENABLE */
-#ifdef EXTRAKEY_ENABLE
-static const USBDescriptor extra_hid_descriptor = {
-  HID_DESCRIPTOR_SIZE,
-  &hid_configuration_descriptor_data[EXTRA_HID_DESC_OFFSET]
-};
-#endif /* EXTRAKEY_ENABLE */
-#ifdef NKRO_ENABLE
-static const USBDescriptor nkro_hid_descriptor = {
-  HID_DESCRIPTOR_SIZE,
-  &hid_configuration_descriptor_data[NKRO_HID_DESC_OFFSET]
-};
-#endif /* NKRO_ENABLE */
-
-
-/* U.S. English language identifier */
-static const uint8_t usb_string_langid[] = {
-  USB_DESC_BYTE(4),                        // bLength
-  USB_DESC_BYTE(USB_DESCRIPTOR_STRING),    // bDescriptorType
-  USB_DESC_WORD(0x0409)                    // wLANGID (U.S. English)
-};
-
-/* ugly ugly hack */
-#define PP_NARG(...) \
-         PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
-#define PP_NARG_(...) \
-         PP_ARG_N(__VA_ARGS__)
-#define PP_ARG_N( \
-          _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
-         _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
-         _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
-         _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
-         _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
-         _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
-         _61,_62,_63,N,...) N
-#define PP_RSEQ_N() \
-         63,62,61,60,                   \
-         59,58,57,56,55,54,53,52,51,50, \
-         49,48,47,46,45,44,43,42,41,40, \
-         39,38,37,36,35,34,33,32,31,30, \
-         29,28,27,26,25,24,23,22,21,20, \
-         19,18,17,16,15,14,13,12,11,10, \
-         9,8,7,6,5,4,3,2,1,0
-
-/* Vendor string = manufacturer */
-static const uint8_t usb_string_vendor[] = {
-  USB_DESC_BYTE(PP_NARG(USBSTR_MANUFACTURER)+2),                       // bLength
-  USB_DESC_BYTE(USB_DESCRIPTOR_STRING),    // bDescriptorType
-  USBSTR_MANUFACTURER
-};
-
-/* Device Description string = product */
-static const uint8_t usb_string_description[] = {
-  USB_DESC_BYTE(PP_NARG(USBSTR_PRODUCT)+2),           // bLength
-  USB_DESC_BYTE(USB_DESCRIPTOR_STRING),    // bDescriptorType
-  USBSTR_PRODUCT
-};
-
-/* Serial Number string (will be filled by the function init_usb_serial_string) */
-static uint8_t usb_string_serial[] = {
-  USB_DESC_BYTE(22),                       // bLength
-  USB_DESC_BYTE(USB_DESCRIPTOR_STRING),    // bDescriptorType
-  '0', 0, 'x', 0, 'D', 0, 'E', 0, 'A', 0, 'D', 0, 'B', 0, 'E', 0, 'E', 0, 'F', 0
-};
-
-/* Strings wrappers array */
-static const USBDescriptor usb_strings[] = {
-  { sizeof usb_string_langid, usb_string_langid }
-  ,
-  { sizeof usb_string_vendor, usb_string_vendor }
-  ,
-  { sizeof usb_string_description, usb_string_description }
-  ,
-  { sizeof usb_string_serial, usb_string_serial }
-};
-
 /*
  * Handles the GET_DESCRIPTOR callback
  *
  * Returns the proper descriptor
  */
-static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t lang) {
+static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t wIndex) {
   (void)usbp;
-  (void)lang;
-  switch(dtype) {
-  /* Generic descriptors */
-  case USB_DESCRIPTOR_DEVICE:   /* Device Descriptor */
-    return &usb_device_descriptor;
-
-  case USB_DESCRIPTOR_CONFIGURATION:    /* Configuration Descriptor */
-    return &hid_configuration_descriptor;
-
-  case USB_DESCRIPTOR_STRING:   /* Strings */
-    if(dindex < 4)
-      return &usb_strings[dindex];
-    break;
-
-  /* HID specific descriptors */
-  case USB_DESCRIPTOR_HID:      /* HID Descriptors */
-    switch(lang) {    /* yea, poor label, it's actually wIndex from the setup packet */
-    case KBD_INTERFACE:
-      return &keyboard_hid_descriptor;
-
-#ifdef MOUSE_ENABLE
-    case MOUSE_INTERFACE:
-      return &mouse_hid_descriptor;
-#endif /* MOUSE_ENABLE */
-#ifdef CONSOLE_ENABLE
-    case CONSOLE_INTERFACE:
-      return &console_hid_descriptor;
-#endif /* CONSOLE_ENABLE */
-#ifdef EXTRAKEY_ENABLE
-    case EXTRA_INTERFACE:
-      return &extra_hid_descriptor;
-#endif /* EXTRAKEY_ENABLE */
-#ifdef NKRO_ENABLE
-    case NKRO_INTERFACE:
-      return &nkro_hid_descriptor;
-#endif /* NKRO_ENABLE */
-    }
-
-  case USB_DESCRIPTOR_HID_REPORT:       /* HID Report Descriptor */
-    switch(lang) {
-    case KBD_INTERFACE:
-      return &keyboard_hid_report_descriptor;
-
-#ifdef MOUSE_ENABLE
-    case MOUSE_INTERFACE:
-      return &mouse_hid_report_descriptor;
-#endif /* MOUSE_ENABLE */
-#ifdef CONSOLE_ENABLE
-    case CONSOLE_INTERFACE:
-      return &console_hid_report_descriptor;
-#endif /* CONSOLE_ENABLE */
-#ifdef EXTRAKEY_ENABLE
-    case EXTRA_INTERFACE:
-      return &extra_hid_report_descriptor;
-#endif /* EXTRAKEY_ENABLE */
-#ifdef NKRO_ENABLE
-    case NKRO_INTERFACE:
-      return &nkro_hid_report_descriptor;
-#endif /* NKRO_ENABLE */
-    }
-  }
-  return NULL;
+  static USBDescriptor desc;
+  uint16_t wValue = ((uint16_t)dtype << 8) | dindex;
+  desc.ud_string = NULL;
+  desc.ud_size = get_usb_descriptor(wValue, wIndex, (const void** const)&desc.ud_string);
+  if (desc.ud_string == NULL)
+    return NULL;
+  else
+    return &desc;
 }
 
 /* keyboard endpoint state structure */
@@ -685,7 +102,7 @@ static const USBEndpointConfig kbd_ep_config = {
   NULL,                         /* SETUP packet notification callback */
   kbd_in_cb,                    /* IN notification callback */
   NULL,                         /* OUT notification callback */
-  KBD_EPSIZE,                   /* IN maximum packet size */
+  KEYBOARD_EPSIZE,              /* IN maximum packet size */
   0,                            /* OUT maximum packet size */
   &kbd_ep_state,                /* IN Endpoint state */
   NULL,                         /* OUT endpoint state */
@@ -712,25 +129,6 @@ static const USBEndpointConfig mouse_ep_config = {
 };
 #endif /* MOUSE_ENABLE */
 
-#ifdef CONSOLE_ENABLE
-/* console endpoint state structure */
-static USBInEndpointState console_ep_state;
-
-/* console endpoint initialization structure (IN) */
-static const USBEndpointConfig console_ep_config = {
-  USB_EP_MODE_TYPE_INTR,        /* Interrupt EP */
-  NULL,                         /* SETUP packet notification callback */
-  console_in_cb,                /* IN notification callback */
-  NULL,                         /* OUT notification callback */
-  CONSOLE_EPSIZE,               /* IN maximum packet size */
-  0,                            /* OUT maximum packet size */
-  &console_ep_state,            /* IN Endpoint state */
-  NULL,                         /* OUT endpoint state */
-  2,                            /* IN multiplier */
-  NULL                          /* SETUP buffer (not a SETUP endpoint) */
-};
-#endif /* CONSOLE_ENABLE */
-
 #ifdef EXTRAKEY_ENABLE
 /* extrakey endpoint state structure */
 static USBInEndpointState extra_ep_state;
@@ -741,7 +139,7 @@ static const USBEndpointConfig extra_ep_config = {
   NULL,                         /* SETUP packet notification callback */
   extra_in_cb,                  /* IN notification callback */
   NULL,                         /* OUT notification callback */
-  EXTRA_EPSIZE,                 /* IN maximum packet size */
+  EXTRAKEY_EPSIZE,              /* IN maximum packet size */
   0,                            /* OUT maximum packet size */
   &extra_ep_state,              /* IN Endpoint state */
   NULL,                         /* OUT endpoint state */
@@ -769,6 +167,129 @@ static const USBEndpointConfig nkro_ep_config = {
 };
 #endif /* NKRO_ENABLE */
 
+typedef struct {
+  size_t queue_capacity_in;
+  size_t queue_capacity_out;
+  uint8_t* queue_buffer_in;
+  uint8_t* queue_buffer_out;
+  USBInEndpointState in_ep_state;
+  USBOutEndpointState out_ep_state;
+  USBInEndpointState int_ep_state;
+  USBEndpointConfig in_ep_config;
+  USBEndpointConfig out_ep_config;
+  USBEndpointConfig int_ep_config;
+  const SerialUSBConfig config;
+  SerialUSBDriver driver;
+} stream_driver_t;
+
+#define STREAM_DRIVER(stream, notification) { \
+  .queue_capacity_in = stream##_IN_CAPACITY, \
+  .queue_capacity_out = stream##_OUT_CAPACITY, \
+  .queue_buffer_in = (uint8_t[BQ_BUFFER_SIZE(stream##_IN_CAPACITY, stream##_EPSIZE)]) {}, \
+  .queue_buffer_out = (uint8_t[BQ_BUFFER_SIZE(stream##_OUT_CAPACITY,stream##_EPSIZE)]) {}, \
+  .in_ep_config = { \
+    .ep_mode = stream##_IN_MODE, \
+    .setup_cb = NULL, \
+    .in_cb = sduDataTransmitted, \
+    .out_cb = NULL, \
+    .in_maxsize = stream##_EPSIZE, \
+    .out_maxsize = 0, \
+    /* The pointer to the states will be filled during initialization */ \
+    .in_state = NULL, \
+    .out_state = NULL, \
+    .ep_buffers = 2, \
+    .setup_buf = NULL \
+  }, \
+  .out_ep_config = { \
+    .ep_mode = stream##_OUT_MODE, \
+    .setup_cb = NULL, \
+    .in_cb = NULL, \
+    .out_cb = sduDataReceived, \
+    .in_maxsize = 0, \
+    .out_maxsize = stream##_EPSIZE, \
+    /* The pointer to the states will be filled during initialization */ \
+    .in_state = NULL, \
+    .out_state = NULL, \
+    .ep_buffers = 2, \
+    .setup_buf = NULL, \
+  }, \
+  .int_ep_config = { \
+    .ep_mode = USB_EP_MODE_TYPE_INTR, \
+    .setup_cb = NULL, \
+    .in_cb = sduInterruptTransmitted, \
+    .out_cb = NULL, \
+    .in_maxsize = CDC_NOTIFICATION_EPSIZE, \
+    .out_maxsize = 0, \
+    /* The pointer to the states will be filled during initialization */ \
+    .in_state = NULL, \
+    .out_state = NULL, \
+    .ep_buffers = 2, \
+    .setup_buf = NULL, \
+  }, \
+  .config = { \
+    .usbp = &USB_DRIVER, \
+    .bulk_in = stream##_IN_EPNUM, \
+    .bulk_out = stream##_OUT_EPNUM, \
+    .int_in = notification \
+  } \
+}
+
+typedef struct {
+  union {
+    struct {
+#ifdef CONSOLE_ENABLE
+      stream_driver_t console_driver;
+#endif
+#ifdef RAW_ENABLE
+      stream_driver_t raw_driver;
+#endif
+#ifdef MIDI_ENABLE
+      stream_driver_t midi_driver;
+#endif
+#ifdef VIRTSER_ENABLE
+      stream_driver_t serial_driver;
+#endif
+    };
+    stream_driver_t array[0];
+  };
+} stream_drivers_t;
+
+static stream_drivers_t drivers = {
+#ifdef CONSOLE_ENABLE
+  #define CONSOLE_IN_CAPACITY 4
+  #define CONSOLE_OUT_CAPACITY 4
+  #define CONSOLE_IN_MODE USB_EP_MODE_TYPE_INTR
+  #define CONSOLE_OUT_MODE USB_EP_MODE_TYPE_INTR
+  .console_driver = STREAM_DRIVER(CONSOLE, 0),
+#endif
+#ifdef RAW_ENABLE
+  #define RAW_IN_CAPACITY 4
+  #define RAW_OUT_CAPACITY 4
+  #define RAW_IN_MODE USB_EP_MODE_TYPE_INTR
+  #define RAW_OUT_MODE USB_EP_MODE_TYPE_INTR
+  .raw_driver = STREAM_DRIVER(RAW, 0),
+#endif
+
+#ifdef MIDI_ENABLE
+  #define MIDI_STREAM_IN_CAPACITY 4
+  #define MIDI_STREAM_OUT_CAPACITY 4
+  #define MIDI_STREAM_IN_MODE USB_EP_MODE_TYPE_BULK
+  #define MIDI_STREAM_OUT_MODE USB_EP_MODE_TYPE_BULK
+  .midi_driver = STREAM_DRIVER(MIDI_STREAM, 0),
+#endif
+
+#ifdef VIRTSER_ENABLE
+  #define CDC_IN_CAPACITY 4
+  #define CDC_OUT_CAPACITY 4
+  #define CDC_IN_MODE USB_EP_MODE_TYPE_BULK
+  #define CDC_OUT_MODE USB_EP_MODE_TYPE_BULK
+  .serial_driver = STREAM_DRIVER(CDC, CDC_NOTIFICATION_EPNUM),
+#endif
+};
+
+#define NUM_STREAM_DRIVERS (sizeof(drivers) / sizeof(stream_driver_t))
+
+
 /* ---------------------------------------------------------
  *                  USB driver functions
  * ---------------------------------------------------------
@@ -784,24 +305,27 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
   case USB_EVENT_CONFIGURED:
     osalSysLockFromISR();
     /* Enable the endpoints specified into the configuration. */
-    usbInitEndpointI(usbp, KBD_ENDPOINT, &kbd_ep_config);
+    usbInitEndpointI(usbp, KEYBOARD_IN_EPNUM, &kbd_ep_config);
 #ifdef MOUSE_ENABLE
-    usbInitEndpointI(usbp, MOUSE_ENDPOINT, &mouse_ep_config);
+    usbInitEndpointI(usbp, MOUSE_IN_EPNUM, &mouse_ep_config);
 #endif /* MOUSE_ENABLE */
-#ifdef CONSOLE_ENABLE
-    usbInitEndpointI(usbp, CONSOLE_ENDPOINT, &console_ep_config);
-    /* don't need to start the flush timer, it starts from console_in_cb automatically */
-#endif /* CONSOLE_ENABLE */
 #ifdef EXTRAKEY_ENABLE
-    usbInitEndpointI(usbp, EXTRA_ENDPOINT, &extra_ep_config);
+    usbInitEndpointI(usbp, EXTRAKEY_IN_EPNUM, &extra_ep_config);
 #endif /* EXTRAKEY_ENABLE */
 #ifdef NKRO_ENABLE
-    usbInitEndpointI(usbp, NKRO_ENDPOINT, &nkro_ep_config);
+    usbInitEndpointI(usbp, NKRO_IN_EPNUM, &nkro_ep_config);
 #endif /* NKRO_ENABLE */
+    for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
+      usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].in_ep_config);
+      usbInitEndpointI(usbp, drivers.array[i].config.bulk_out, &drivers.array[i].out_ep_config);
+      if (drivers.array[i].config.int_in) {
+        usbInitEndpointI(usbp, drivers.array[i].config.int_in, &drivers.array[i].int_ep_config);
+      }
+      sduConfigureHookI(&drivers.array[i].driver);
+    }
     osalSysUnlockFromISR();
     return;
   case USB_EVENT_SUSPEND:
-    //TODO: from ISR! print("[S]");
 #ifdef SLEEP_LED_ENABLE
     sleep_led_enable();
 #endif /* SLEEP_LED_ENABLE */
@@ -809,10 +333,22 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
   case USB_EVENT_UNCONFIGURED:
     /* Falls into.*/
   case USB_EVENT_RESET:
+      for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
+        chSysLockFromISR();
+        /* Disconnection event on suspend.*/
+        sduSuspendHookI(&drivers.array[i].driver);
+        chSysUnlockFromISR();
+      }
     return;
 
   case USB_EVENT_WAKEUP:
     //TODO: from ISR! print("[W]");
+      for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
+        chSysLockFromISR();
+        /* Disconnection event on suspend.*/
+        sduWakeupHookI(&drivers.array[i].driver);
+        chSysUnlockFromISR();
+      }
     suspend_wakeup_init();
 #ifdef SLEEP_LED_ENABLE
     sleep_led_disable();
@@ -868,7 +404,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
       switch(usbp->setup[1]) {   /* bRequest */
       case HID_GET_REPORT:
         switch(usbp->setup[4]) {     /* LSB(wIndex) (check MSB==0?) */
-        case KBD_INTERFACE:
+        case KEYBOARD_INTERFACE:
 #ifdef NKRO_ENABLE
         case NKRO_INTERFACE:
 #endif /* NKRO_ENABLE */
@@ -883,15 +419,8 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
           break;
 #endif /* MOUSE_ENABLE */
 
-#ifdef CONSOLE_ENABLE
-        case CONSOLE_INTERFACE:
-          usbSetupTransfer(usbp, console_queue_buffer, CONSOLE_EPSIZE, NULL);
-          return TRUE;
-          break;
-#endif /* CONSOLE_ENABLE */
-
 #ifdef EXTRAKEY_ENABLE
-        case EXTRA_INTERFACE:
+        case EXTRAKEY_INTERFACE:
           if(usbp->setup[3] == 1) { /* MSB(wValue) [Report Type] == 1 [Input Report] */
             switch(usbp->setup[2]) { /* LSB(wValue) [Report ID] */
               case REPORT_ID_SYSTEM:
@@ -921,7 +450,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
         break;
 
       case HID_GET_PROTOCOL:
-        if((usbp->setup[4] == KBD_INTERFACE) && (usbp->setup[5] == 0)) {   /* wIndex */
+        if((usbp->setup[4] == KEYBOARD_INTERFACE) && (usbp->setup[5] == 0)) {   /* wIndex */
           usbSetupTransfer(usbp, &keyboard_protocol, 1, NULL);
           return TRUE;
         }
@@ -938,7 +467,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
       switch(usbp->setup[1]) {   /* bRequest */
       case HID_SET_REPORT:
         switch(usbp->setup[4]) {       /* LSB(wIndex) (check MSB==0 and wLength==1?) */
-        case KBD_INTERFACE:
+        case KEYBOARD_INTERFACE:
 #ifdef NKRO_ENABLE
         case NKRO_INTERFACE:
 #endif  /* NKRO_ENABLE */
@@ -951,7 +480,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
         break;
 
       case HID_SET_PROTOCOL:
-        if((usbp->setup[4] == KBD_INTERFACE) && (usbp->setup[5] == 0)) {   /* wIndex */
+        if((usbp->setup[4] == KEYBOARD_INTERFACE) && (usbp->setup[5] == 0)) {   /* wIndex */
           keyboard_protocol = ((usbp->setup[2]) != 0x00);   /* LSB(wValue) */
 #ifdef NKRO_ENABLE
           keymap_config.nkro = !!keyboard_protocol;
@@ -998,12 +527,24 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
     return TRUE;
   }
 
+  for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
+    if (drivers.array[i].config.int_in) {
+      // NOTE: Assumes that we only have one serial driver
+      return sduRequestsHook(usbp);
+    }
+  }
+
   return FALSE;
 }
 
 /* Start-of-frame callback */
 static void usb_sof_cb(USBDriver *usbp) {
   kbd_sof_cb(usbp);
+  osalSysLockFromISR();
+  for (int i=0; i<NUM_STREAM_DRIVERS;i++) {
+    sduSOFHookI(&drivers.array[i].driver);
+  }
+  osalSysUnlockFromISR();
 }
 
 
@@ -1019,6 +560,19 @@ static const USBConfig usbcfg = {
  * Initialize the USB driver
  */
 void init_usb_driver(USBDriver *usbp) {
+  for (int i=0; i<NUM_STREAM_DRIVERS;i++) {
+    SerialUSBDriver* driver = &drivers.array[i].driver;
+    drivers.array[i].in_ep_config.in_state = &drivers.array[i].in_ep_state;
+    drivers.array[i].out_ep_config.out_state = &drivers.array[i].out_ep_state;
+    drivers.array[i].int_ep_config.in_state = &drivers.array[i].int_ep_state;
+    sduObjectInit(driver);
+    bqnotify_t notify = driver->ibqueue.notify;
+    ibqObjectInit(&driver->ibqueue, false, drivers.array[i].queue_buffer_in, drivers.array[i].in_ep_config.in_maxsize, drivers.array[i].queue_capacity_in, notify, driver);
+    notify = driver->obqueue.notify;
+    ibqObjectInit(&driver->ibqueue, false, drivers.array[i].queue_buffer_out, drivers.array[i].out_ep_config.out_maxsize, drivers.array[i].queue_capacity_out, notify, driver);
+    sduStart(driver, &drivers.array[i].config);
+  }
+
   /*
    * Activates the USB driver and then the USB bus pull-up on D+.
    * Note, a delay is inserted in order to not have to disconnect the cable
@@ -1030,17 +584,12 @@ void init_usb_driver(USBDriver *usbp) {
   usbConnectBus(usbp);
 
   chVTObjectInit(&keyboard_idle_timer);
-#ifdef CONSOLE_ENABLE
-  obqObjectInit(&console_buf_queue, false, console_queue_buffer, CONSOLE_EPSIZE, CONSOLE_QUEUE_CAPACITY, console_queue_onotify, (void*)usbp);
-  chVTObjectInit(&console_flush_timer);
-#endif
 }
 
 /* ---------------------------------------------------------
  *                  Keyboard functions
  * ---------------------------------------------------------
  */
-
 /* keyboard IN callback hander (a kbd report has made it IN) */
 void kbd_in_cb(USBDriver *usbp, usbep_t ep) {
   /* STUB */
@@ -1084,8 +633,8 @@ static void keyboard_idle_timer_cb(void *arg) {
   if(keyboard_idle) {
 #endif /* NKRO_ENABLE */
     /* TODO: are we sure we want the KBD_ENDPOINT? */
-    if(!usbGetTransmitStatusI(usbp, KBD_ENDPOINT)) {
-      usbStartTransmitI(usbp, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, KBD_EPSIZE);
+    if(!usbGetTransmitStatusI(usbp, KEYBOARD_IN_EPNUM)) {
+      usbStartTransmitI(usbp, KEYBOARD_IN_EPNUM, (uint8_t *)&keyboard_report_sent, KEYBOARD_EPSIZE);
     }
     /* rearm the timer */
     chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
@@ -1119,14 +668,14 @@ void send_keyboard(report_keyboard_t *report) {
      * this is more efficient */
     /* busy wait, should be short and not very common */
     osalSysLock();
-    if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_ENDPOINT)) {
+    if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_IN_EPNUM)) {
       /* Need to either suspend, or loop and call unlock/lock during
        * every iteration - otherwise the system will remain locked,
        * no interrupts served, so USB not going through as well.
        * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
-      osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_ENDPOINT]->in_state->thread);
+      osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_IN_EPNUM]->in_state->thread);
     }
-    usbStartTransmitI(&USB_DRIVER, NKRO_ENDPOINT, (uint8_t *)report, sizeof(report_keyboard_t));
+    usbStartTransmitI(&USB_DRIVER, NKRO_IN_EPNUM, (uint8_t *)report, sizeof(report_keyboard_t));
     osalSysUnlock();
   } else
 #endif /* NKRO_ENABLE */
@@ -1134,14 +683,14 @@ void send_keyboard(report_keyboard_t *report) {
     /* need to wait until the previous packet has made it through */
     /* busy wait, should be short and not very common */
     osalSysLock();
-    if(usbGetTransmitStatusI(&USB_DRIVER, KBD_ENDPOINT)) {
+    if(usbGetTransmitStatusI(&USB_DRIVER, KEYBOARD_IN_EPNUM)) {
       /* Need to either suspend, or loop and call unlock/lock during
        * every iteration - otherwise the system will remain locked,
        * no interrupts served, so USB not going through as well.
        * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
-      osalThreadSuspendS(&(&USB_DRIVER)->epc[KBD_ENDPOINT]->in_state->thread);
+      osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread);
     }
-    usbStartTransmitI(&USB_DRIVER, KBD_ENDPOINT, (uint8_t *)report, KBD_EPSIZE);
+    usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, (uint8_t *)report, KEYBOARD_EPSIZE);
     osalSysUnlock();
   }
   keyboard_report_sent = *report;
@@ -1174,7 +723,7 @@ void send_mouse(report_mouse_t *report) {
    */
 
   osalSysLock();
-  usbStartTransmitI(&USB_DRIVER, MOUSE_ENDPOINT, (uint8_t *)report, sizeof(report_mouse_t));
+  usbStartTransmitI(&USB_DRIVER, MOUSE_IN_EPNUM, (uint8_t *)report, sizeof(report_mouse_t));
   osalSysUnlock();
 }
 
@@ -1210,7 +759,7 @@ static void send_extra_report(uint8_t report_id, uint16_t data) {
     .usage = data
   };
 
-  usbStartTransmitI(&USB_DRIVER, EXTRA_ENDPOINT, (uint8_t *)&report, sizeof(report_extra_t));
+  usbStartTransmitI(&USB_DRIVER, EXTRAKEY_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t));
   osalSysUnlock();
 }
 
@@ -1238,125 +787,107 @@ void send_consumer(uint16_t data) {
 
 #ifdef CONSOLE_ENABLE
 
-/* console IN callback hander */
-void console_in_cb(USBDriver *usbp, usbep_t ep) {
-  (void)ep; /* should have ep == CONSOLE_ENDPOINT, so use that to save time/space */
-  uint8_t *buf;
-  size_t n;
+int8_t sendchar(uint8_t c) {
+  // The previous implmentation had timeouts, but I think it's better to just slow down
+  // and make sure that everything is transferred, rather than dropping stuff
+  return chnWrite(&drivers.console_driver.driver, &c, 1);
+}
 
-  osalSysLockFromISR();
+// Just a dummy function for now, this could be exposed as a weak function
+// Or connected to the actual QMK console
+static void console_receive( uint8_t *data, uint8_t length ) {
+  (void)data;
+  (void)length;
+}
 
-  /* rearm the timer */
-  chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
+void console_task(void) {
+  uint8_t buffer[CONSOLE_EPSIZE];
+  size_t size = 0;
+  do {
+    size_t size = chnReadTimeout(&drivers.console_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
+    if (size > 0) {
+        console_receive(buffer, size);
+    }
+  } while(size > 0);
+}
 
-  /* Freeing the buffer just transmitted, if it was not a zero size packet.*/
-  if (usbp->epc[CONSOLE_ENDPOINT]->in_state->txsize > 0U) {
-    obqReleaseEmptyBufferI(&console_buf_queue);
-  }
+#else /* CONSOLE_ENABLE */
+int8_t sendchar(uint8_t c) {
+  (void)c;
+  return 0;
+}
+#endif /* CONSOLE_ENABLE */
 
-  /* Checking if there is a buffer ready for transmission.*/
-  buf = obqGetFullBufferI(&console_buf_queue, &n);
+void sendchar_pf(void *p, char c) {
+  (void)p;
+  sendchar((uint8_t)c);
+}
 
-  if (buf != NULL) {
-    /* The endpoint cannot be busy, we are in the context of the callback,
-       so it is safe to transmit without a check.*/
-    /* Should have n == CONSOLE_EPSIZE; check it? */
-    usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE);
-  } else {
-    /* Nothing to transmit.*/
-  }
+#ifdef RAW_ENABLE
+void raw_hid_send( uint8_t *data, uint8_t length ) {
+       // TODO: implement variable size packet
+       if ( length != RAW_EPSIZE )
+       {
+               return;
 
-  osalSysUnlockFromISR();
+       }
+  chnWrite(&drivers.raw_driver.driver, data, length);
 }
 
-/* Callback when data is inserted into the output queue
- * Called from a locked state */
-void console_queue_onotify(io_buffers_queue_t *bqp) {
-  size_t n;
-  USBDriver *usbp = bqGetLinkX(bqp);
-
-  if(usbGetDriverStateI(usbp) != USB_ACTIVE)
-    return;
+__attribute__ ((weak))
+void raw_hid_receive( uint8_t *data, uint8_t length ) {
+       // Users should #include "raw_hid.h" in their own code
+       // and implement this function there. Leave this as weak linkage
+       // so users can opt to not handle data coming in.
+}
 
-  /* Checking if there is already a transaction ongoing on the endpoint.*/
-  if (!usbGetTransmitStatusI(usbp, CONSOLE_ENDPOINT)) {
-    /* Trying to get a full buffer.*/
-    uint8_t *buf = obqGetFullBufferI(&console_buf_queue, &n);
-    if (buf != NULL) {
-      /* Buffer found, starting a new transaction.*/
-      /* Should have n == CONSOLE_EPSIZE; check this? */
-      usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE);
+void raw_hid_task(void) {
+  uint8_t buffer[RAW_EPSIZE];
+  size_t size = 0;
+  do {
+    size_t size = chnReadTimeout(&drivers.raw_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
+    if (size > 0) {
+        raw_hid_receive(buffer, size);
     }
-  }
+  } while(size > 0);
 }
 
-/* Flush timer code
- * callback (called from ISR, unlocked state) */
-static void console_flush_cb(void *arg) {
-  USBDriver *usbp = (USBDriver *)arg;
-  osalSysLockFromISR();
+#endif
 
-  /* check that the states of things are as they're supposed to */
-  if(usbGetDriverStateI(usbp) != USB_ACTIVE) {
-    /* rearm the timer */
-    chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
-    osalSysUnlockFromISR();
-    return;
-  }
+#ifdef MIDI_ENABLE
 
-  /* If there is already a transaction ongoing then another one cannot be
-     started.*/
-  if (usbGetTransmitStatusI(usbp, CONSOLE_ENDPOINT)) {
-    /* rearm the timer */
-    chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
-    osalSysUnlockFromISR();
-    return;
-  }
+void send_midi_packet(MIDI_EventPacket_t* event) {
+  chnWrite(&drivers.midi_driver.driver, (uint8_t*)event, sizeof(MIDI_EventPacket_t));
+}
 
-  /* Checking if there only a buffer partially filled, if so then it is
-     enforced in the queue and transmitted.*/
-  if(obqTryFlushI(&console_buf_queue)) {
-    size_t n,i;
-    uint8_t *buf = obqGetFullBufferI(&console_buf_queue, &n);
+bool recv_midi_packet(MIDI_EventPacket_t* const event) {
+  size_t size = chnReadTimeout(&drivers.midi_driver.driver, (uint8_t*)event, sizeof(MIDI_EventPacket_t), TIME_IMMEDIATE);
+  return size == sizeof(MIDI_EventPacket_t);
+}
 
-    osalDbgAssert(buf != NULL, "queue is empty");
+#endif
 
-    /* zero the rest of the buffer (buf should point to allocated space) */
-    for(i=n; i<CONSOLE_EPSIZE; i++)
-      buf[i]=0;
-    usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE);
-  }
+#ifdef VIRTSER_ENABLE
 
-  /* rearm the timer */
-  chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
-  osalSysUnlockFromISR();
+void virtser_send(const uint8_t byte) {
+  chnWrite(&drivers.serial_driver.driver, &byte, 1);
 }
 
-
-int8_t sendchar(uint8_t c) {
-  osalSysLock();
-  if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
-    osalSysUnlock();
-    return 0;
-  }
-  osalSysUnlock();
-  /* Timeout after 100us if the queue is full.
-   * Increase this timeout if too much stuff is getting
-   * dropped (i.e. the buffer is getting full too fast
-   * for USB/HIDRAW to dequeue). Another possibility
-   * for fixing this kind of thing is to increase
-   * CONSOLE_QUEUE_CAPACITY. */
-  return(obqPutTimeout(&console_buf_queue, c, US2ST(100)));
+__attribute__ ((weak))
+void virtser_recv(uint8_t c)
+{
+  // Ignore by default
 }
 
-#else /* CONSOLE_ENABLE */
-int8_t sendchar(uint8_t c) {
-  (void)c;
-  return 0;
+void virtser_task(void) {
+  uint8_t numBytesReceived = 0;
+  uint8_t buffer[16];
+  do {
+    numBytesReceived = chnReadTimeout(&drivers.serial_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
+    for (int i=0;i<numBytesReceived;i++) {
+      virtser_recv(buffer[i]);
+    }
+  } while (numBytesReceived > 0);
 }
-#endif /* CONSOLE_ENABLE */
 
-void sendchar_pf(void *p, char c) {
-  (void)p;
-  sendchar((uint8_t)c);
-}
+#endif
index b4f894f2f3dac66db9e8194142b84ac6d02e3c2b..1f7eb12f8db5c5e0e2a7c84d29eea8c0e351479f 100644 (file)
@@ -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);
index 4d005debcd56a2542dba7984575d7391ffce1f13..bb82a31e17cc37b6866514e1d6fc5d1773382973 100644 (file)
@@ -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
 
diff --git a/tmk_core/protocol/lufa/descriptor.c b/tmk_core/protocol/lufa/descriptor.c
deleted file mode 100644 (file)
index bfa91f2..0000000
+++ /dev/null
@@ -1,1003 +0,0 @@
-/*
- * Copyright 2012 Jun Wako <wakojun@gmail.com>
- * This file is based on:
- *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
- *     LUFA-120219/Demos/Device/Lowlevel/GenericHID
- */
-
-/*
-             LUFA Library
-     Copyright (C) Dean Camera, 2012.
-
-  dean [at] fourwalledcubicle [dot] com
-           www.lufa-lib.org
-*/
-
-/*
-  Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)
-  Copyright 2010  Denver Gingerich (denver [at] ossguy [dot] com)
-
-  Permission to use, copy, modify, distribute, and sell this
-  software and its documentation for any purpose is hereby granted
-  without fee, provided that the above copyright notice appear in
-  all copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting
-  documentation, and that the name of the author not be used in
-  advertising or publicity pertaining to distribution of the
-  software without specific, written prior permission.
-
-  The author disclaim all warranties with regard to this
-  software, including all implied warranties of merchantability
-  and fitness.  In no event shall the author be liable for any
-  special, indirect or consequential damages or any damages
-  whatsoever resulting from loss of use, data or profits, whether
-  in an action of contract, negligence or other tortious action,
-  arising out of or in connection with the use or performance of
-  this software.
-*/
-
-#include "util.h"
-#include "report.h"
-#include "descriptor.h"
-
-#ifndef USB_MAX_POWER_CONSUMPTION
-#define USB_MAX_POWER_CONSUMPTION 500
-#endif
-
-/*******************************************************************************
- * HID Report Descriptors
- ******************************************************************************/
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
-{
-    HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
-    HID_RI_USAGE(8, 0x06), /* Keyboard */
-    HID_RI_COLLECTION(8, 0x01), /* Application */
-        HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
-        HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
-        HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
-        HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(8, 0x01),
-        HID_RI_REPORT_COUNT(8, 0x08),
-        HID_RI_REPORT_SIZE(8, 0x01),
-        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-
-        HID_RI_REPORT_COUNT(8, 0x01),
-        HID_RI_REPORT_SIZE(8, 0x08),
-        HID_RI_INPUT(8, HID_IOF_CONSTANT),  /* reserved */
-
-        HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
-        HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
-        HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
-        HID_RI_REPORT_COUNT(8, 0x05),
-        HID_RI_REPORT_SIZE(8, 0x01),
-        HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
-        HID_RI_REPORT_COUNT(8, 0x01),
-        HID_RI_REPORT_SIZE(8, 0x03),
-        HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
-
-        HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
-        HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
-        HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
-        HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
-        HID_RI_REPORT_COUNT(8, 0x06),
-        HID_RI_REPORT_SIZE(8, 0x08),
-        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
-    HID_RI_END_COLLECTION(0),
-};
-
-#ifdef MOUSE_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
-{
-    HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
-    HID_RI_USAGE(8, 0x02), /* Mouse */
-    HID_RI_COLLECTION(8, 0x01), /* Application */
-        HID_RI_USAGE(8, 0x01), /* Pointer */
-        HID_RI_COLLECTION(8, 0x00), /* Physical */
-
-            HID_RI_USAGE_PAGE(8, 0x09), /* Button */
-            HID_RI_USAGE_MINIMUM(8, 0x01),  /* Button 1 */
-            HID_RI_USAGE_MAXIMUM(8, 0x05),  /* Button 5 */
-            HID_RI_LOGICAL_MINIMUM(8, 0x00),
-            HID_RI_LOGICAL_MAXIMUM(8, 0x01),
-            HID_RI_REPORT_COUNT(8, 0x05),
-            HID_RI_REPORT_SIZE(8, 0x01),
-            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-            HID_RI_REPORT_COUNT(8, 0x01),
-            HID_RI_REPORT_SIZE(8, 0x03),
-            HID_RI_INPUT(8, HID_IOF_CONSTANT),
-
-            HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
-            HID_RI_USAGE(8, 0x30), /* Usage X */
-            HID_RI_USAGE(8, 0x31), /* Usage Y */
-            HID_RI_LOGICAL_MINIMUM(8, -127),
-            HID_RI_LOGICAL_MAXIMUM(8, 127),
-            HID_RI_REPORT_COUNT(8, 0x02),
-            HID_RI_REPORT_SIZE(8, 0x08),
-            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
-
-            HID_RI_USAGE(8, 0x38), /* Wheel */
-            HID_RI_LOGICAL_MINIMUM(8, -127),
-            HID_RI_LOGICAL_MAXIMUM(8, 127),
-            HID_RI_REPORT_COUNT(8, 0x01),
-            HID_RI_REPORT_SIZE(8, 0x08),
-            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
-
-            HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
-            HID_RI_USAGE(16, 0x0238), /* AC Pan (Horizontal wheel) */
-            HID_RI_LOGICAL_MINIMUM(8, -127),
-            HID_RI_LOGICAL_MAXIMUM(8, 127),
-            HID_RI_REPORT_COUNT(8, 0x01),
-            HID_RI_REPORT_SIZE(8, 0x08),
-            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
-
-        HID_RI_END_COLLECTION(0),
-    HID_RI_END_COLLECTION(0),
-};
-#endif
-
-#ifdef EXTRAKEY_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
-{
-    HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
-    HID_RI_USAGE(8, 0x80), /* System Control */
-    HID_RI_COLLECTION(8, 0x01), /* Application */
-        HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
-        HID_RI_LOGICAL_MINIMUM(16, 0x0001),
-        HID_RI_LOGICAL_MAXIMUM(16, 0x0003),
-        HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
-        HID_RI_USAGE_MAXIMUM(16, 0x0083), /* System Wake Up */
-        HID_RI_REPORT_SIZE(8, 16),
-        HID_RI_REPORT_COUNT(8, 1),
-        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
-    HID_RI_END_COLLECTION(0),
-
-    HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
-    HID_RI_USAGE(8, 0x01), /* Consumer Control */
-    HID_RI_COLLECTION(8, 0x01), /* Application */
-        HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
-        HID_RI_LOGICAL_MINIMUM(16, 0x0001),
-        HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
-        HID_RI_USAGE_MINIMUM(16, 0x0001), /* +10 */
-        HID_RI_USAGE_MAXIMUM(16, 0x029C), /* AC Distribute Vertically */
-        HID_RI_REPORT_SIZE(8, 16),
-        HID_RI_REPORT_COUNT(8, 1),
-        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
-    HID_RI_END_COLLECTION(0),
-};
-#endif
-
-#ifdef RAW_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] =
-{
-    HID_RI_USAGE_PAGE(16, 0xFF60), /* Vendor Page 0xFF60 */
-    HID_RI_USAGE(8, 0x61), /* Vendor Usage 0x61 */
-    HID_RI_COLLECTION(8, 0x01), /* Application */
-        HID_RI_USAGE(8, 0x62), /* Vendor Usage 0x62 */
-        HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
-        HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
-        HID_RI_REPORT_SIZE(8, 0x08),
-        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-        HID_RI_USAGE(8, 0x63), /* Vendor Usage 0x63 */
-        HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
-        HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
-        HID_RI_REPORT_SIZE(8, 0x08),
-        HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
-    HID_RI_END_COLLECTION(0),
-};
-#endif
-
-#ifdef CONSOLE_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
-{
-    HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */
-    HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */
-    HID_RI_COLLECTION(8, 0x01), /* Application */
-        HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
-        HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
-        HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
-        HID_RI_REPORT_SIZE(8, 0x08),
-        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-        HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
-        HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
-        HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
-        HID_RI_REPORT_SIZE(8, 0x08),
-        HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
-    HID_RI_END_COLLECTION(0),
-};
-#endif
-
-#ifdef NKRO_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
-{
-    HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
-    HID_RI_USAGE(8, 0x06), /* Keyboard */
-    HID_RI_COLLECTION(8, 0x01), /* Application */
-        HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
-        HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
-        HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
-        HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(8, 0x01),
-        HID_RI_REPORT_COUNT(8, 0x08),
-        HID_RI_REPORT_SIZE(8, 0x01),
-        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-
-        HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
-        HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
-        HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
-        HID_RI_REPORT_COUNT(8, 0x05),
-        HID_RI_REPORT_SIZE(8, 0x01),
-        HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
-        HID_RI_REPORT_COUNT(8, 0x01),
-        HID_RI_REPORT_SIZE(8, 0x03),
-        HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
-
-        HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
-        HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
-        HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
-        HID_RI_LOGICAL_MINIMUM(8, 0x00),
-        HID_RI_LOGICAL_MAXIMUM(8, 0x01),
-        HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
-        HID_RI_REPORT_SIZE(8, 0x01),
-        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-    HID_RI_END_COLLECTION(0),
-};
-#endif
-
-/*******************************************************************************
- * Device Descriptors
- ******************************************************************************/
-const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
-{
-    .Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
-
-    .USBSpecification       = VERSION_BCD(1,1,0),
-#if VIRTSER_ENABLE
-    .Class                  = USB_CSCP_IADDeviceClass,
-    .SubClass               = USB_CSCP_IADDeviceSubclass,
-    .Protocol               = USB_CSCP_IADDeviceProtocol,
-#else
-    .Class                  = USB_CSCP_NoDeviceClass,
-    .SubClass               = USB_CSCP_NoDeviceSubclass,
-    .Protocol               = USB_CSCP_NoDeviceProtocol,
-#endif
-
-    .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
-
-    /* specified in config.h */
-    .VendorID               = VENDOR_ID,
-    .ProductID              = PRODUCT_ID,
-    .ReleaseNumber          = DEVICE_VER,
-
-    .ManufacturerStrIndex   = 0x01,
-    .ProductStrIndex        = 0x02,
-    .SerialNumStrIndex      = 0x03,
-
-    .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
-};
-
-/*******************************************************************************
- * Configuration Descriptors
- ******************************************************************************/
-const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
-{
-    .Config =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
-
-            .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
-            .TotalInterfaces        = TOTAL_INTERFACES,
-
-            .ConfigurationNumber    = 1,
-            .ConfigurationStrIndex  = NO_DESCRIPTOR,
-
-            .ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
-
-            .MaxPowerConsumption    = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)
-        },
-
-    /*
-     * Keyboard
-     */
-    .Keyboard_Interface =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-            .InterfaceNumber        = KEYBOARD_INTERFACE,
-            .AlternateSetting       = 0x00,
-
-            .TotalEndpoints         = 1,
-
-            .Class                  = HID_CSCP_HIDClass,
-            .SubClass               = HID_CSCP_BootSubclass,
-            .Protocol               = HID_CSCP_KeyboardBootProtocol,
-
-            .InterfaceStrIndex      = NO_DESCRIPTOR
-        },
-
-    .Keyboard_HID =
-        {
-            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
-
-            .HIDSpec                = VERSION_BCD(1,1,1),
-            .CountryCode            = 0x00,
-            .TotalReportDescriptors = 1,
-            .HIDReportType          = HID_DTYPE_Report,
-            .HIDReportLength        = sizeof(KeyboardReport)
-        },
-
-    .Keyboard_INEndpoint =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-            .EndpointAddress        = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
-            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-            .EndpointSize           = KEYBOARD_EPSIZE,
-            .PollingIntervalMS      = 0x0A
-        },
-
-    /*
-     * Mouse
-     */
-#ifdef MOUSE_ENABLE
-    .Mouse_Interface =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-            .InterfaceNumber        = MOUSE_INTERFACE,
-            .AlternateSetting       = 0x00,
-
-            .TotalEndpoints         = 1,
-
-            .Class                  = HID_CSCP_HIDClass,
-            .SubClass               = HID_CSCP_BootSubclass,
-            .Protocol               = HID_CSCP_MouseBootProtocol,
-
-            .InterfaceStrIndex      = NO_DESCRIPTOR
-        },
-
-    .Mouse_HID =
-        {
-            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
-
-            .HIDSpec                = VERSION_BCD(1,1,1),
-            .CountryCode            = 0x00,
-            .TotalReportDescriptors = 1,
-            .HIDReportType          = HID_DTYPE_Report,
-            .HIDReportLength        = sizeof(MouseReport)
-        },
-
-    .Mouse_INEndpoint =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-            .EndpointAddress        = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
-            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-            .EndpointSize           = MOUSE_EPSIZE,
-            .PollingIntervalMS      = 0x0A
-        },
-#endif
-
-    /*
-     * Extra
-     */
-#ifdef EXTRAKEY_ENABLE
-    .Extrakey_Interface =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-            .InterfaceNumber        = EXTRAKEY_INTERFACE,
-            .AlternateSetting       = 0x00,
-
-            .TotalEndpoints         = 1,
-
-            .Class                  = HID_CSCP_HIDClass,
-            .SubClass               = HID_CSCP_NonBootSubclass,
-            .Protocol               = HID_CSCP_NonBootProtocol,
-
-            .InterfaceStrIndex      = NO_DESCRIPTOR
-        },
-
-    .Extrakey_HID =
-        {
-            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
-
-            .HIDSpec                = VERSION_BCD(1,1,1),
-            .CountryCode            = 0x00,
-            .TotalReportDescriptors = 1,
-            .HIDReportType          = HID_DTYPE_Report,
-            .HIDReportLength        = sizeof(ExtrakeyReport)
-        },
-
-    .Extrakey_INEndpoint =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-            .EndpointAddress        = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
-            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-            .EndpointSize           = EXTRAKEY_EPSIZE,
-            .PollingIntervalMS      = 0x0A
-        },
-#endif
-
-               /*
-            * Raw
-            */
-       #ifdef RAW_ENABLE
-           .Raw_Interface =
-               {
-                   .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-                   .InterfaceNumber        = RAW_INTERFACE,
-                   .AlternateSetting       = 0x00,
-
-                   .TotalEndpoints         = 2,
-
-                   .Class                  = HID_CSCP_HIDClass,
-                   .SubClass               = HID_CSCP_NonBootSubclass,
-                   .Protocol               = HID_CSCP_NonBootProtocol,
-
-                   .InterfaceStrIndex      = NO_DESCRIPTOR
-               },
-
-           .Raw_HID =
-               {
-                   .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
-
-                   .HIDSpec                = VERSION_BCD(1,1,1),
-                   .CountryCode            = 0x00,
-                   .TotalReportDescriptors = 1,
-                   .HIDReportType          = HID_DTYPE_Report,
-                   .HIDReportLength        = sizeof(RawReport)
-               },
-
-           .Raw_INEndpoint =
-               {
-                   .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-                   .EndpointAddress        = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
-                   .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-                   .EndpointSize           = RAW_EPSIZE,
-                   .PollingIntervalMS      = 0x01
-               },
-
-           .Raw_OUTEndpoint =
-               {
-                   .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-                   .EndpointAddress        = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
-                   .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-                   .EndpointSize           = RAW_EPSIZE,
-                   .PollingIntervalMS      = 0x01
-               },
-       #endif
-
-    /*
-     * Console
-     */
-#ifdef CONSOLE_ENABLE
-    .Console_Interface =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-            .InterfaceNumber        = CONSOLE_INTERFACE,
-            .AlternateSetting       = 0x00,
-
-            .TotalEndpoints         = 2,
-
-            .Class                  = HID_CSCP_HIDClass,
-            .SubClass               = HID_CSCP_NonBootSubclass,
-            .Protocol               = HID_CSCP_NonBootProtocol,
-
-            .InterfaceStrIndex      = NO_DESCRIPTOR
-        },
-
-    .Console_HID =
-        {
-            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
-
-            .HIDSpec                = VERSION_BCD(1,1,1),
-            .CountryCode            = 0x00,
-            .TotalReportDescriptors = 1,
-            .HIDReportType          = HID_DTYPE_Report,
-            .HIDReportLength        = sizeof(ConsoleReport)
-        },
-
-    .Console_INEndpoint =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-            .EndpointAddress        = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
-            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-            .EndpointSize           = CONSOLE_EPSIZE,
-            .PollingIntervalMS      = 0x01
-        },
-
-    .Console_OUTEndpoint =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-            .EndpointAddress        = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM),
-            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-            .EndpointSize           = CONSOLE_EPSIZE,
-            .PollingIntervalMS      = 0x01
-        },
-#endif
-
-    /*
-     * NKRO
-     */
-#ifdef NKRO_ENABLE
-    .NKRO_Interface =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-            .InterfaceNumber        = NKRO_INTERFACE,
-            .AlternateSetting       = 0x00,
-
-            .TotalEndpoints         = 1,
-
-            .Class                  = HID_CSCP_HIDClass,
-            .SubClass               = HID_CSCP_NonBootSubclass,
-            .Protocol               = HID_CSCP_NonBootProtocol,
-
-            .InterfaceStrIndex      = NO_DESCRIPTOR
-        },
-
-    .NKRO_HID =
-        {
-            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
-
-            .HIDSpec                = VERSION_BCD(1,1,1),
-            .CountryCode            = 0x00,
-            .TotalReportDescriptors = 1,
-            .HIDReportType          = HID_DTYPE_Report,
-            .HIDReportLength        = sizeof(NKROReport)
-        },
-
-    .NKRO_INEndpoint =
-        {
-            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-            .EndpointAddress        = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
-            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-            .EndpointSize           = NKRO_EPSIZE,
-            .PollingIntervalMS      = 0x01
-        },
-#endif
-
-#ifdef MIDI_ENABLE
-    .Audio_ControlInterface =
-        {
-            .Header                   = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-            .InterfaceNumber          = AC_INTERFACE,
-            .AlternateSetting         = 0,
-
-            .TotalEndpoints           = 0,
-
-            .Class                    = AUDIO_CSCP_AudioClass,
-            .SubClass                 = AUDIO_CSCP_ControlSubclass,
-            .Protocol                 = AUDIO_CSCP_ControlProtocol,
-
-            .InterfaceStrIndex        = NO_DESCRIPTOR
-        },
-
-    .Audio_ControlInterface_SPC =
-        {
-            .Header                   = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
-            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_Header,
-
-            .ACSpecification          = VERSION_BCD(1,0,0),
-            .TotalLength              = sizeof(USB_Audio_Descriptor_Interface_AC_t),
-
-            .InCollection             = 1,
-            .InterfaceNumber          = AS_INTERFACE,
-        },
-
-    .Audio_StreamInterface =
-        {
-            .Header                   = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-            .InterfaceNumber          = AS_INTERFACE,
-            .AlternateSetting         = 0,
-
-            .TotalEndpoints           = 2,
-
-            .Class                    = AUDIO_CSCP_AudioClass,
-            .SubClass                 = AUDIO_CSCP_MIDIStreamingSubclass,
-            .Protocol                 = AUDIO_CSCP_StreamingProtocol,
-
-            .InterfaceStrIndex        = NO_DESCRIPTOR
-        },
-
-    .Audio_StreamInterface_SPC =
-        {
-            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
-            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_General,
-
-            .AudioSpecification       = VERSION_BCD(1,0,0),
-
-            .TotalLength              = (sizeof(USB_Descriptor_Configuration_t) -
-                                         offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
-        },
-
-    .MIDI_In_Jack_Emb =
-        {
-            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
-            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
-
-            .JackType                 = MIDI_JACKTYPE_Embedded,
-            .JackID                   = 0x01,
-
-            .JackStrIndex             = NO_DESCRIPTOR
-        },
-
-    .MIDI_In_Jack_Ext =
-        {
-            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
-            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
-
-            .JackType                 = MIDI_JACKTYPE_External,
-            .JackID                   = 0x02,
-
-            .JackStrIndex             = NO_DESCRIPTOR
-        },
-
-    .MIDI_Out_Jack_Emb =
-        {
-            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
-            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
-
-            .JackType                 = MIDI_JACKTYPE_Embedded,
-            .JackID                   = 0x03,
-
-            .NumberOfPins             = 1,
-            .SourceJackID             = {0x02},
-            .SourcePinID              = {0x01},
-
-            .JackStrIndex             = NO_DESCRIPTOR
-        },
-
-    .MIDI_Out_Jack_Ext =
-        {
-            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
-            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
-
-            .JackType                 = MIDI_JACKTYPE_External,
-            .JackID                   = 0x04,
-
-            .NumberOfPins             = 1,
-            .SourceJackID             = {0x01},
-            .SourcePinID              = {0x01},
-
-            .JackStrIndex             = NO_DESCRIPTOR
-        },
-
-    .MIDI_In_Jack_Endpoint =
-        {
-            .Endpoint =
-                {
-                    .Header              = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
-
-                    .EndpointAddress     = MIDI_STREAM_OUT_EPADDR,
-                    .Attributes          = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-                    .EndpointSize        = MIDI_STREAM_EPSIZE,
-                    .PollingIntervalMS   = 0x05
-                },
-
-            .Refresh                  = 0,
-            .SyncEndpointNumber       = 0
-        },
-
-    .MIDI_In_Jack_Endpoint_SPC =
-        {
-            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
-            .Subtype                  = AUDIO_DSUBTYPE_CSEndpoint_General,
-
-            .TotalEmbeddedJacks       = 0x01,
-            .AssociatedJackID         = {0x01}
-        },
-
-    .MIDI_Out_Jack_Endpoint =
-        {
-            .Endpoint =
-                {
-                    .Header              = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
-
-                    .EndpointAddress     = MIDI_STREAM_IN_EPADDR,
-                    .Attributes          = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-                    .EndpointSize        = MIDI_STREAM_EPSIZE,
-                    .PollingIntervalMS   = 0x05
-                },
-
-            .Refresh                  = 0,
-            .SyncEndpointNumber       = 0
-        },
-
-    .MIDI_Out_Jack_Endpoint_SPC =
-        {
-            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
-            .Subtype                  = AUDIO_DSUBTYPE_CSEndpoint_General,
-
-            .TotalEmbeddedJacks       = 0x01,
-            .AssociatedJackID         = {0x03}
-        },
-#endif
-
-#ifdef VIRTSER_ENABLE
-    .CDC_Interface_Association =
-            {
-                    .Header                 = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
-
-                    .FirstInterfaceIndex    = CCI_INTERFACE,
-                    .TotalInterfaces        = 2,
-
-                    .Class                  = CDC_CSCP_CDCClass,
-                    .SubClass               = CDC_CSCP_ACMSubclass,
-                    .Protocol               = CDC_CSCP_ATCommandProtocol,
-
-                    .IADStrIndex            = NO_DESCRIPTOR,
-            },
-
-    .CDC_CCI_Interface =
-            {
-                    .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-                    .InterfaceNumber        = CCI_INTERFACE,
-                    .AlternateSetting       = 0,
-
-                    .TotalEndpoints         = 1,
-
-                    .Class                  = CDC_CSCP_CDCClass,
-                    .SubClass               = CDC_CSCP_ACMSubclass,
-                    .Protocol               = CDC_CSCP_ATCommandProtocol,
-
-                    .InterfaceStrIndex      = NO_DESCRIPTOR
-            },
-
-    .CDC_Functional_Header =
-            {
-                    .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
-                    .Subtype                = 0x00,
-
-                    .CDCSpecification       = VERSION_BCD(1,1,0),
-            },
-
-    .CDC_Functional_ACM =
-            {
-                    .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
-                    .Subtype                = 0x02,
-
-                    .Capabilities           = 0x02,
-            },
-
-    .CDC_Functional_Union =
-            {
-                    .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
-                    .Subtype                = 0x06,
-
-                    .MasterInterfaceNumber  = CCI_INTERFACE,
-                    .SlaveInterfaceNumber   = CDI_INTERFACE,
-            },
-
-    .CDC_NotificationEndpoint =
-            {
-                    .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-                    .EndpointAddress        = CDC_NOTIFICATION_EPADDR,
-                    .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-                    .EndpointSize           = CDC_NOTIFICATION_EPSIZE,
-                    .PollingIntervalMS      = 0xFF
-            },
-
-    .CDC_DCI_Interface =
-            {
-                    .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
-                    .InterfaceNumber        = CDI_INTERFACE,
-                    .AlternateSetting       = 0,
-
-                    .TotalEndpoints         = 2,
-
-                    .Class                  = CDC_CSCP_CDCDataClass,
-                    .SubClass               = CDC_CSCP_NoDataSubclass,
-                    .Protocol               = CDC_CSCP_NoDataProtocol,
-
-                    .InterfaceStrIndex      = NO_DESCRIPTOR
-            },
-
-    .CDC_DataOutEndpoint =
-            {
-                    .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-                    .EndpointAddress        = CDC_OUT_EPADDR,
-                    .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-                    .EndpointSize           = CDC_EPSIZE,
-                    .PollingIntervalMS      = 0x05
-            },
-
-    .CDC_DataInEndpoint =
-            {
-                    .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-                    .EndpointAddress        = CDC_IN_EPADDR,
-                    .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-                    .EndpointSize           = CDC_EPSIZE,
-                    .PollingIntervalMS      = 0x05
-            },
-#endif
-};
-
-
-/*******************************************************************************
- * String Descriptors
- ******************************************************************************/
-const USB_Descriptor_String_t PROGMEM LanguageString =
-{
-    .Header                 = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
-
-    .UnicodeString          = {LANGUAGE_ID_ENG}
-};
-
-const USB_Descriptor_String_t PROGMEM ManufacturerString =
-{
-    /* subtract 1 for null terminator */
-    .Header                 = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String},
-
-    .UnicodeString          = LSTR(MANUFACTURER)
-};
-
-const USB_Descriptor_String_t PROGMEM ProductString =
-{
-    /* subtract 1 for null terminator */
-    .Header                 = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String},
-
-    .UnicodeString          = LSTR(PRODUCT)
-};
-
-#ifndef SERIAL_NUMBER
-    #define SERIAL_NUMBER 0
-#endif
-
-const USB_Descriptor_String_t PROGMEM SerialNumberString =
-{
-    /* subtract 1 for null terminator */
-    .Header                 = {.Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER))-1), .Type = DTYPE_String},
-
-    .UnicodeString          = LSTR(SERIAL_NUMBER)
-};
-
-
-/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
- *  documentation) by the application code so that the address and size of a requested descriptor can be given
- *  to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
- *  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)
-{
-    const uint8_t  DescriptorType   = (wValue >> 8);
-    const uint8_t  DescriptorIndex  = (wValue & 0xFF);
-
-    const void* Address = NULL;
-    uint16_t    Size    = NO_DESCRIPTOR;
-
-    switch (DescriptorType)
-    {
-        case DTYPE_Device:
-            Address = &DeviceDescriptor;
-            Size    = sizeof(USB_Descriptor_Device_t);
-            break;
-        case DTYPE_Configuration:
-            Address = &ConfigurationDescriptor;
-            Size    = sizeof(USB_Descriptor_Configuration_t);
-            break;
-        case DTYPE_String:
-            switch (DescriptorIndex )
-            {
-                case 0x00:
-                    Address = &LanguageString;
-                    Size    = pgm_read_byte(&LanguageString.Header.Size);
-                    break;
-                case 0x01:
-                    Address = &ManufacturerString;
-                    Size    = pgm_read_byte(&ManufacturerString.Header.Size);
-                    break;
-                case 0x02:
-                    Address = &ProductString;
-                    Size    = pgm_read_byte(&ProductString.Header.Size);
-                    break;
-                case 0x03:
-                    Address = &SerialNumberString;
-                    Size    = pgm_read_byte(&SerialNumberString.Header.Size);
-                    break;
-            }
-            break;
-        case HID_DTYPE_HID:
-            switch (wIndex) {
-            case KEYBOARD_INTERFACE:
-                Address = &ConfigurationDescriptor.Keyboard_HID;
-                Size    = sizeof(USB_HID_Descriptor_HID_t);
-                break;
-#ifdef MOUSE_ENABLE
-            case MOUSE_INTERFACE:
-                Address = &ConfigurationDescriptor.Mouse_HID;
-                Size    = sizeof(USB_HID_Descriptor_HID_t);
-                break;
-#endif
-#ifdef EXTRAKEY_ENABLE
-            case EXTRAKEY_INTERFACE:
-                Address = &ConfigurationDescriptor.Extrakey_HID;
-                Size    = sizeof(USB_HID_Descriptor_HID_t);
-                break;
-#endif
-#ifdef RAW_ENABLE
-            case RAW_INTERFACE:
-                Address = &ConfigurationDescriptor.Raw_HID;
-                Size    = sizeof(USB_HID_Descriptor_HID_t);
-                break;
-#endif
-#ifdef CONSOLE_ENABLE
-            case CONSOLE_INTERFACE:
-                Address = &ConfigurationDescriptor.Console_HID;
-                Size    = sizeof(USB_HID_Descriptor_HID_t);
-                break;
-#endif
-#ifdef NKRO_ENABLE
-            case NKRO_INTERFACE:
-                Address = &ConfigurationDescriptor.NKRO_HID;
-                Size    = sizeof(USB_HID_Descriptor_HID_t);
-                break;
-#endif
-            }
-            break;
-        case HID_DTYPE_Report:
-            switch (wIndex) {
-            case KEYBOARD_INTERFACE:
-                Address = &KeyboardReport;
-                Size    = sizeof(KeyboardReport);
-                break;
-#ifdef MOUSE_ENABLE
-            case MOUSE_INTERFACE:
-                Address = &MouseReport;
-                Size    = sizeof(MouseReport);
-                break;
-#endif
-#ifdef EXTRAKEY_ENABLE
-            case EXTRAKEY_INTERFACE:
-                Address = &ExtrakeyReport;
-                Size    = sizeof(ExtrakeyReport);
-                break;
-#endif
-#ifdef RAW_ENABLE
-            case RAW_INTERFACE:
-                Address = &RawReport;
-                Size    = sizeof(RawReport);
-                break;
-#endif
-#ifdef CONSOLE_ENABLE
-            case CONSOLE_INTERFACE:
-                Address = &ConsoleReport;
-                Size    = sizeof(ConsoleReport);
-                break;
-#endif
-#ifdef NKRO_ENABLE
-            case NKRO_INTERFACE:
-                Address = &NKROReport;
-                Size    = sizeof(NKROReport);
-                break;
-#endif
-            }
-            break;
-    }
-
-    *DescriptorAddress = Address;
-    return Size;
-}
diff --git a/tmk_core/protocol/lufa/descriptor.h b/tmk_core/protocol/lufa/descriptor.h
deleted file mode 100644 (file)
index 61c42c9..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
- * This file is based on:
- *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
- *     LUFA-120219/Demos/Device/Lowlevel/GenericHID
- */
-
-/*
-             LUFA Library
-     Copyright (C) Dean Camera, 2012.
-
-  dean [at] fourwalledcubicle [dot] com
-           www.lufa-lib.org
-*/
-
-/*
-  Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)
-  Copyright 2010  Denver Gingerich (denver [at] ossguy [dot] com)
-
-  Permission to use, copy, modify, distribute, and sell this
-  software and its documentation for any purpose is hereby granted
-  without fee, provided that the above copyright notice appear in
-  all copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting
-  documentation, and that the name of the author not be used in
-  advertising or publicity pertaining to distribution of the
-  software without specific, written prior permission.
-
-  The author disclaim all warranties with regard to this
-  software, including all implied warranties of merchantability
-  and fitness.  In no event shall the author be liable for any
-  special, indirect or consequential damages or any damages
-  whatsoever resulting from loss of use, data or profits, whether
-  in an action of contract, negligence or other tortious action,
-  arising out of or in connection with the use or performance of
-  this software.
-*/
-
-/** \file
- *
- *  Header file for Descriptors.c.
- */
-
-#ifndef _DESCRIPTORS_H_
-#define _DESCRIPTORS_H_
-
-#include <LUFA/Drivers/USB/USB.h>
-#include <avr/pgmspace.h>
-
-
-typedef struct
-{
-    USB_Descriptor_Configuration_Header_t Config;
-
-    // Keyboard HID Interface
-    USB_Descriptor_Interface_t            Keyboard_Interface;
-    USB_HID_Descriptor_HID_t              Keyboard_HID;
-    USB_Descriptor_Endpoint_t             Keyboard_INEndpoint;
-
-#ifdef MOUSE_ENABLE
-    // Mouse HID Interface
-    USB_Descriptor_Interface_t            Mouse_Interface;
-    USB_HID_Descriptor_HID_t              Mouse_HID;
-    USB_Descriptor_Endpoint_t             Mouse_INEndpoint;
-#endif
-
-#ifdef EXTRAKEY_ENABLE
-    // Extrakey HID Interface
-    USB_Descriptor_Interface_t            Extrakey_Interface;
-    USB_HID_Descriptor_HID_t              Extrakey_HID;
-    USB_Descriptor_Endpoint_t             Extrakey_INEndpoint;
-#endif
-
-#ifdef RAW_ENABLE
-    // Raw HID Interface
-    USB_Descriptor_Interface_t            Raw_Interface;
-    USB_HID_Descriptor_HID_t              Raw_HID;
-    USB_Descriptor_Endpoint_t             Raw_INEndpoint;
-    USB_Descriptor_Endpoint_t             Raw_OUTEndpoint;
-#endif
-
-#ifdef CONSOLE_ENABLE
-    // Console HID Interface
-    USB_Descriptor_Interface_t            Console_Interface;
-    USB_HID_Descriptor_HID_t              Console_HID;
-    USB_Descriptor_Endpoint_t             Console_INEndpoint;
-    USB_Descriptor_Endpoint_t             Console_OUTEndpoint;
-#endif
-
-#ifdef NKRO_ENABLE
-    // NKRO HID Interface
-    USB_Descriptor_Interface_t            NKRO_Interface;
-    USB_HID_Descriptor_HID_t              NKRO_HID;
-    USB_Descriptor_Endpoint_t             NKRO_INEndpoint;
-#endif
-
-#ifdef MIDI_ENABLE
-      // 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;
-#endif
-
-#ifdef VIRTSER_ENABLE
-        USB_Descriptor_Interface_Association_t   CDC_Interface_Association;
-
-       // CDC Control Interface
-       USB_Descriptor_Interface_t               CDC_CCI_Interface;
-       USB_CDC_Descriptor_FunctionalHeader_t    CDC_Functional_Header;
-       USB_CDC_Descriptor_FunctionalACM_t       CDC_Functional_ACM;
-       USB_CDC_Descriptor_FunctionalUnion_t     CDC_Functional_Union;
-       USB_Descriptor_Endpoint_t                CDC_NotificationEndpoint;
-
-       // CDC Data Interface
-       USB_Descriptor_Interface_t               CDC_DCI_Interface;
-       USB_Descriptor_Endpoint_t                CDC_DataOutEndpoint;
-       USB_Descriptor_Endpoint_t                CDC_DataInEndpoint;
-#endif
-} USB_Descriptor_Configuration_t;
-
-
-/* index of interface */
-#define KEYBOARD_INTERFACE          0
-
-// It is important that the Raw HID interface is at a constant
-// interface number, to support Linux/OSX platforms and chrome.hid
-// If Raw HID is enabled, let it be always 1.
-#ifdef RAW_ENABLE
-#   define RAW_INTERFACE               (KEYBOARD_INTERFACE + 1)
-#else
-#   define RAW_INTERFACE               KEYBOARD_INTERFACE
-#endif
-
-#ifdef MOUSE_ENABLE
-#   define MOUSE_INTERFACE          (RAW_INTERFACE + 1)
-#else
-#   define MOUSE_INTERFACE          RAW_INTERFACE
-#endif
-
-#ifdef EXTRAKEY_ENABLE
-#   define EXTRAKEY_INTERFACE       (MOUSE_INTERFACE + 1)
-#else
-#   define EXTRAKEY_INTERFACE       MOUSE_INTERFACE
-#endif
-
-#ifdef CONSOLE_ENABLE
-#   define CONSOLE_INTERFACE        (EXTRAKEY_INTERFACE + 1)
-#else
-#   define CONSOLE_INTERFACE        EXTRAKEY_INTERFACE
-#endif
-
-#ifdef NKRO_ENABLE
-#   define NKRO_INTERFACE           (CONSOLE_INTERFACE + 1)
-#else
-#   define NKRO_INTERFACE           CONSOLE_INTERFACE
-#endif
-
-#ifdef MIDI_ENABLE
-#   define AC_INTERFACE           (NKRO_INTERFACE + 1)
-#   define AS_INTERFACE           (NKRO_INTERFACE + 2)
-#else
-#   define AS_INTERFACE           NKRO_INTERFACE
-#endif
-
-#ifdef VIRTSER_ENABLE
-#   define CCI_INTERFACE         (AS_INTERFACE + 1)
-#   define CDI_INTERFACE         (AS_INTERFACE + 2)
-#else
-#   define CDI_INTERFACE         AS_INTERFACE
-#endif
-
-/* nubmer of interfaces */
-#define TOTAL_INTERFACES            (CDI_INTERFACE + 1)
-
-
-// Endopoint number and size
-#define KEYBOARD_IN_EPNUM           1
-
-#ifdef MOUSE_ENABLE
-#   define MOUSE_IN_EPNUM           (KEYBOARD_IN_EPNUM + 1)
-#else
-#   define MOUSE_IN_EPNUM           KEYBOARD_IN_EPNUM
-#endif
-
-#ifdef EXTRAKEY_ENABLE
-#   define EXTRAKEY_IN_EPNUM        (MOUSE_IN_EPNUM + 1)
-#else
-#   define EXTRAKEY_IN_EPNUM        MOUSE_IN_EPNUM
-#endif
-
-#ifdef RAW_ENABLE
-#   define RAW_IN_EPNUM         (EXTRAKEY_IN_EPNUM + 1)
-#   define RAW_OUT_EPNUM        (EXTRAKEY_IN_EPNUM + 2)
-#else
-#   define RAW_OUT_EPNUM        EXTRAKEY_IN_EPNUM
-#endif
-
-#ifdef CONSOLE_ENABLE
-#   define CONSOLE_IN_EPNUM         (RAW_OUT_EPNUM + 1)
-//#   define CONSOLE_OUT_EPNUM        (RAW_OUT_EPNUM + 2)
-#   define CONSOLE_OUT_EPNUM        (RAW_OUT_EPNUM + 1)
-#else
-#   define CONSOLE_OUT_EPNUM        RAW_OUT_EPNUM
-#endif
-
-#ifdef NKRO_ENABLE
-#   define NKRO_IN_EPNUM            (CONSOLE_OUT_EPNUM + 1)
-#else
-#   define NKRO_IN_EPNUM            CONSOLE_OUT_EPNUM
-#endif
-
-#ifdef MIDI_ENABLE
-#   define MIDI_STREAM_IN_EPNUM     (NKRO_IN_EPNUM + 1)
-// #   define MIDI_STREAM_OUT_EPNUM    (NKRO_IN_EPNUM + 1)
-#   define MIDI_STREAM_OUT_EPNUM    (NKRO_IN_EPNUM + 2)
-#   define MIDI_STREAM_IN_EPADDR    (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM)
-#   define MIDI_STREAM_OUT_EPADDR   (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM)
-#else
-#   define MIDI_STREAM_OUT_EPNUM     NKRO_IN_EPNUM
-#endif
-
-#ifdef VIRTSER_ENABLE
-#   define CDC_NOTIFICATION_EPNUM   (MIDI_STREAM_OUT_EPNUM + 1)
-#   define CDC_IN_EPNUM                    (MIDI_STREAM_OUT_EPNUM + 2)
-#   define CDC_OUT_EPNUM                   (MIDI_STREAM_OUT_EPNUM + 3)
-#   define CDC_NOTIFICATION_EPADDR        (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM)
-#   define CDC_IN_EPADDR                  (ENDPOINT_DIR_IN | CDC_IN_EPNUM)
-#   define CDC_OUT_EPADDR                  (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM)
-#else
-#   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)"
-#endif
-
-#define KEYBOARD_EPSIZE             8
-#define MOUSE_EPSIZE                8
-#define EXTRAKEY_EPSIZE             8
-#define RAW_EPSIZE                     32
-#define CONSOLE_EPSIZE              32
-#define NKRO_EPSIZE                 32
-#define MIDI_STREAM_EPSIZE          64
-#define CDC_NOTIFICATION_EPSIZE     8
-#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);
-
-
-/* new API */
-#if LUFA_VERSION_INTEGER < 0x140302
-    #undef VERSION_BCD
-    #define VERSION_BCD(Major, Minor, Revision) \
-                                              CPU_TO_LE16( ((Major & 0xFF) << 8) | \
-                                                           ((Minor & 0x0F) << 4) | \
-                                                           (Revision & 0x0F) )
-#endif
-
-#endif
index e3f8724e81c01586e16f1640c56c4e46a297e2d5..a1cab98a66abd18c9a580c3859427a0d45d9562a 100644 (file)
@@ -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
-}
-
-
-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
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+                                    const uint16_t wIndex,
+                                    const void** const DescriptorAddress)
+{
+  return get_usb_descriptor(wValue, wIndex, DescriptorAddress);
 }
 
-
-#endif
index a515737862df0f7c429c6e1a9d3a08354de75d86..7364cdf7ceb3ad10fc99e721632acf7dea423dbf 100644 (file)
@@ -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
index 4855b23d3017a63670863864cc5bb81690aecff6..a5f76b2d31f6b76d48a3f2f7dfecfa73bb84fce0 100644 (file)
@@ -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)
\ No newline at end of file
+VPATH += $(TMK_PATH)/$(MIDI_DIR)
index eafef527c02329432918d1595b9d47007ddc3e84..0ab8b546208a38579bc0a14d41984f044ee4900b 100755 (executable)
@@ -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
 
diff --git a/tmk_core/protocol/midi/qmk_midi.c b/tmk_core/protocol/midi/qmk_midi.c
new file mode 100644 (file)
index 0000000..d4de6ca
--- /dev/null
@@ -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
+}
diff --git a/tmk_core/protocol/midi/qmk_midi.h b/tmk_core/protocol/midi/qmk_midi.h
new file mode 100644 (file)
index 0000000..7282a19
--- /dev/null
@@ -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
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
new file mode 100644 (file)
index 0000000..cab3446
--- /dev/null
@@ -0,0 +1,1017 @@
+/*
+ * Copyright 2012 Jun Wako <wakojun@gmail.com>
+ * This file is based on:
+ *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
+ *     LUFA-120219/Demos/Device/Lowlevel/GenericHID
+ */
+
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2012.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+  Copyright 2010  Denver Gingerich (denver [at] ossguy [dot] com)
+
+  Permission to use, copy, modify, distribute, and sell this
+  software and its documentation for any purpose is hereby granted
+  without fee, provided that the above copyright notice appear in
+  all copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#include "util.h"
+#include "report.h"
+#include "usb_descriptor.h"
+
+#ifndef USB_MAX_POWER_CONSUMPTION
+#define USB_MAX_POWER_CONSUMPTION 500
+#endif
+
+/*******************************************************************************
+ * HID Report Descriptors
+ ******************************************************************************/
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
+{
+    HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+    HID_RI_USAGE(8, 0x06), /* Keyboard */
+    HID_RI_COLLECTION(8, 0x01), /* Application */
+        HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+        HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
+        HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
+        HID_RI_LOGICAL_MINIMUM(8, 0x00),
+        HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+        HID_RI_REPORT_COUNT(8, 0x08),
+        HID_RI_REPORT_SIZE(8, 0x01),
+        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+
+        HID_RI_REPORT_COUNT(8, 0x01),
+        HID_RI_REPORT_SIZE(8, 0x08),
+        HID_RI_INPUT(8, HID_IOF_CONSTANT),  /* reserved */
+
+        HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
+        HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
+        HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
+        HID_RI_REPORT_COUNT(8, 0x05),
+        HID_RI_REPORT_SIZE(8, 0x01),
+        HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+        HID_RI_REPORT_COUNT(8, 0x01),
+        HID_RI_REPORT_SIZE(8, 0x03),
+        HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
+
+        HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
+        HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
+        HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
+        HID_RI_LOGICAL_MINIMUM(8, 0x00),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+        HID_RI_REPORT_COUNT(8, 0x06),
+        HID_RI_REPORT_SIZE(8, 0x08),
+        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
+    HID_RI_END_COLLECTION(0),
+};
+
+#ifdef MOUSE_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
+{
+    HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+    HID_RI_USAGE(8, 0x02), /* Mouse */
+    HID_RI_COLLECTION(8, 0x01), /* Application */
+        HID_RI_USAGE(8, 0x01), /* Pointer */
+        HID_RI_COLLECTION(8, 0x00), /* Physical */
+
+            HID_RI_USAGE_PAGE(8, 0x09), /* Button */
+            HID_RI_USAGE_MINIMUM(8, 0x01),  /* Button 1 */
+            HID_RI_USAGE_MAXIMUM(8, 0x05),  /* Button 5 */
+            HID_RI_LOGICAL_MINIMUM(8, 0x00),
+            HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+            HID_RI_REPORT_COUNT(8, 0x05),
+            HID_RI_REPORT_SIZE(8, 0x01),
+            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+            HID_RI_REPORT_COUNT(8, 0x01),
+            HID_RI_REPORT_SIZE(8, 0x03),
+            HID_RI_INPUT(8, HID_IOF_CONSTANT),
+
+            HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+            HID_RI_USAGE(8, 0x30), /* Usage X */
+            HID_RI_USAGE(8, 0x31), /* Usage Y */
+            HID_RI_LOGICAL_MINIMUM(8, -127),
+            HID_RI_LOGICAL_MAXIMUM(8, 127),
+            HID_RI_REPORT_COUNT(8, 0x02),
+            HID_RI_REPORT_SIZE(8, 0x08),
+            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
+
+            HID_RI_USAGE(8, 0x38), /* Wheel */
+            HID_RI_LOGICAL_MINIMUM(8, -127),
+            HID_RI_LOGICAL_MAXIMUM(8, 127),
+            HID_RI_REPORT_COUNT(8, 0x01),
+            HID_RI_REPORT_SIZE(8, 0x08),
+            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
+
+            HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
+            HID_RI_USAGE(16, 0x0238), /* AC Pan (Horizontal wheel) */
+            HID_RI_LOGICAL_MINIMUM(8, -127),
+            HID_RI_LOGICAL_MAXIMUM(8, 127),
+            HID_RI_REPORT_COUNT(8, 0x01),
+            HID_RI_REPORT_SIZE(8, 0x08),
+            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
+
+        HID_RI_END_COLLECTION(0),
+    HID_RI_END_COLLECTION(0),
+};
+#endif
+
+#ifdef EXTRAKEY_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
+{
+    HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+    HID_RI_USAGE(8, 0x80), /* System Control */
+    HID_RI_COLLECTION(8, 0x01), /* Application */
+        HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
+        HID_RI_LOGICAL_MINIMUM(16, 0x0001),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x0003),
+        HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
+        HID_RI_USAGE_MAXIMUM(16, 0x0083), /* System Wake Up */
+        HID_RI_REPORT_SIZE(8, 16),
+        HID_RI_REPORT_COUNT(8, 1),
+        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
+    HID_RI_END_COLLECTION(0),
+
+    HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */
+    HID_RI_USAGE(8, 0x01), /* Consumer Control */
+    HID_RI_COLLECTION(8, 0x01), /* Application */
+        HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
+        HID_RI_LOGICAL_MINIMUM(16, 0x0001),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
+        HID_RI_USAGE_MINIMUM(16, 0x0001), /* +10 */
+        HID_RI_USAGE_MAXIMUM(16, 0x029C), /* AC Distribute Vertically */
+        HID_RI_REPORT_SIZE(8, 16),
+        HID_RI_REPORT_COUNT(8, 1),
+        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
+    HID_RI_END_COLLECTION(0),
+};
+#endif
+
+#ifdef RAW_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] =
+{
+    HID_RI_USAGE_PAGE(16, 0xFF60), /* Vendor Page 0xFF60 */
+    HID_RI_USAGE(8, 0x61), /* Vendor Usage 0x61 */
+    HID_RI_COLLECTION(8, 0x01), /* Application */
+        HID_RI_USAGE(8, 0x62), /* Vendor Usage 0x62 */
+        HID_RI_LOGICAL_MINIMUM(8, 0x00),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+        HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
+        HID_RI_REPORT_SIZE(8, 0x08),
+        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+        HID_RI_USAGE(8, 0x63), /* Vendor Usage 0x63 */
+        HID_RI_LOGICAL_MINIMUM(8, 0x00),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+        HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
+        HID_RI_REPORT_SIZE(8, 0x08),
+        HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+    HID_RI_END_COLLECTION(0),
+};
+#endif
+
+#ifdef CONSOLE_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
+{
+    HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */
+    HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */
+    HID_RI_COLLECTION(8, 0x01), /* Application */
+        HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
+        HID_RI_LOGICAL_MINIMUM(8, 0x00),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+        HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
+        HID_RI_REPORT_SIZE(8, 0x08),
+        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+        HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
+        HID_RI_LOGICAL_MINIMUM(8, 0x00),
+        HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
+        HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
+        HID_RI_REPORT_SIZE(8, 0x08),
+        HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+    HID_RI_END_COLLECTION(0),
+};
+#endif
+
+#ifdef NKRO_ENABLE
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
+{
+    HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+    HID_RI_USAGE(8, 0x06), /* Keyboard */
+    HID_RI_COLLECTION(8, 0x01), /* Application */
+        HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+        HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
+        HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
+        HID_RI_LOGICAL_MINIMUM(8, 0x00),
+        HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+        HID_RI_REPORT_COUNT(8, 0x08),
+        HID_RI_REPORT_SIZE(8, 0x01),
+        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+
+        HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
+        HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
+        HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
+        HID_RI_REPORT_COUNT(8, 0x05),
+        HID_RI_REPORT_SIZE(8, 0x01),
+        HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+        HID_RI_REPORT_COUNT(8, 0x01),
+        HID_RI_REPORT_SIZE(8, 0x03),
+        HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
+
+        HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+        HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
+        HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
+        HID_RI_LOGICAL_MINIMUM(8, 0x00),
+        HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+        HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
+        HID_RI_REPORT_SIZE(8, 0x01),
+        HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+    HID_RI_END_COLLECTION(0),
+};
+#endif
+
+/*******************************************************************************
+ * Device Descriptors
+ ******************************************************************************/
+const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
+{
+    .Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+    .USBSpecification       = VERSION_BCD(1,1,0),
+#if VIRTSER_ENABLE
+    .Class                  = USB_CSCP_IADDeviceClass,
+    .SubClass               = USB_CSCP_IADDeviceSubclass,
+    .Protocol               = USB_CSCP_IADDeviceProtocol,
+#else
+    .Class                  = USB_CSCP_NoDeviceClass,
+    .SubClass               = USB_CSCP_NoDeviceSubclass,
+    .Protocol               = USB_CSCP_NoDeviceProtocol,
+#endif
+
+    .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
+
+    /* specified in config.h */
+    .VendorID               = VENDOR_ID,
+    .ProductID              = PRODUCT_ID,
+    .ReleaseNumber          = DEVICE_VER,
+
+    .ManufacturerStrIndex   = 0x01,
+    .ProductStrIndex        = 0x02,
+    .SerialNumStrIndex      = 0x03,
+
+    .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/*******************************************************************************
+ * Configuration Descriptors
+ ******************************************************************************/
+const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
+{
+    .Config =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+            .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
+            .TotalInterfaces        = TOTAL_INTERFACES,
+
+            .ConfigurationNumber    = 1,
+            .ConfigurationStrIndex  = NO_DESCRIPTOR,
+
+            .ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
+
+            .MaxPowerConsumption    = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)
+        },
+
+    /*
+     * Keyboard
+     */
+    .Keyboard_Interface =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+            .InterfaceNumber        = KEYBOARD_INTERFACE,
+            .AlternateSetting       = 0x00,
+
+            .TotalEndpoints         = 1,
+
+            .Class                  = HID_CSCP_HIDClass,
+            .SubClass               = HID_CSCP_BootSubclass,
+            .Protocol               = HID_CSCP_KeyboardBootProtocol,
+
+            .InterfaceStrIndex      = NO_DESCRIPTOR
+        },
+
+    .Keyboard_HID =
+        {
+            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+            .HIDSpec                = VERSION_BCD(1,1,1),
+            .CountryCode            = 0x00,
+            .TotalReportDescriptors = 1,
+            .HIDReportType          = HID_DTYPE_Report,
+            .HIDReportLength        = sizeof(KeyboardReport)
+        },
+
+    .Keyboard_INEndpoint =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+            .EndpointAddress        = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
+            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+            .EndpointSize           = KEYBOARD_EPSIZE,
+            .PollingIntervalMS      = 0x0A
+        },
+
+    /*
+     * Mouse
+     */
+#ifdef MOUSE_ENABLE
+    .Mouse_Interface =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+            .InterfaceNumber        = MOUSE_INTERFACE,
+            .AlternateSetting       = 0x00,
+
+            .TotalEndpoints         = 1,
+
+            .Class                  = HID_CSCP_HIDClass,
+            .SubClass               = HID_CSCP_BootSubclass,
+            .Protocol               = HID_CSCP_MouseBootProtocol,
+
+            .InterfaceStrIndex      = NO_DESCRIPTOR
+        },
+
+    .Mouse_HID =
+        {
+            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+            .HIDSpec                = VERSION_BCD(1,1,1),
+            .CountryCode            = 0x00,
+            .TotalReportDescriptors = 1,
+            .HIDReportType          = HID_DTYPE_Report,
+            .HIDReportLength        = sizeof(MouseReport)
+        },
+
+    .Mouse_INEndpoint =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+            .EndpointAddress        = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
+            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+            .EndpointSize           = MOUSE_EPSIZE,
+            .PollingIntervalMS      = 0x0A
+        },
+#endif
+
+    /*
+     * Extra
+     */
+#ifdef EXTRAKEY_ENABLE
+    .Extrakey_Interface =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+            .InterfaceNumber        = EXTRAKEY_INTERFACE,
+            .AlternateSetting       = 0x00,
+
+            .TotalEndpoints         = 1,
+
+            .Class                  = HID_CSCP_HIDClass,
+            .SubClass               = HID_CSCP_NonBootSubclass,
+            .Protocol               = HID_CSCP_NonBootProtocol,
+
+            .InterfaceStrIndex      = NO_DESCRIPTOR
+        },
+
+    .Extrakey_HID =
+        {
+            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+            .HIDSpec                = VERSION_BCD(1,1,1),
+            .CountryCode            = 0x00,
+            .TotalReportDescriptors = 1,
+            .HIDReportType          = HID_DTYPE_Report,
+            .HIDReportLength        = sizeof(ExtrakeyReport)
+        },
+
+    .Extrakey_INEndpoint =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+            .EndpointAddress        = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
+            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+            .EndpointSize           = EXTRAKEY_EPSIZE,
+            .PollingIntervalMS      = 0x0A
+        },
+#endif
+
+               /*
+            * Raw
+            */
+       #ifdef RAW_ENABLE
+           .Raw_Interface =
+               {
+                   .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+                   .InterfaceNumber        = RAW_INTERFACE,
+                   .AlternateSetting       = 0x00,
+
+                   .TotalEndpoints         = 2,
+
+                   .Class                  = HID_CSCP_HIDClass,
+                   .SubClass               = HID_CSCP_NonBootSubclass,
+                   .Protocol               = HID_CSCP_NonBootProtocol,
+
+                   .InterfaceStrIndex      = NO_DESCRIPTOR
+               },
+
+           .Raw_HID =
+               {
+                   .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+                   .HIDSpec                = VERSION_BCD(1,1,1),
+                   .CountryCode            = 0x00,
+                   .TotalReportDescriptors = 1,
+                   .HIDReportType          = HID_DTYPE_Report,
+                   .HIDReportLength        = sizeof(RawReport)
+               },
+
+           .Raw_INEndpoint =
+               {
+                   .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+                   .EndpointAddress        = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
+                   .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+                   .EndpointSize           = RAW_EPSIZE,
+                   .PollingIntervalMS      = 0x01
+               },
+
+           .Raw_OUTEndpoint =
+               {
+                   .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+                   .EndpointAddress        = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
+                   .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+                   .EndpointSize           = RAW_EPSIZE,
+                   .PollingIntervalMS      = 0x01
+               },
+       #endif
+
+    /*
+     * Console
+     */
+#ifdef CONSOLE_ENABLE
+    .Console_Interface =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+            .InterfaceNumber        = CONSOLE_INTERFACE,
+            .AlternateSetting       = 0x00,
+
+            .TotalEndpoints         = 2,
+
+            .Class                  = HID_CSCP_HIDClass,
+            .SubClass               = HID_CSCP_NonBootSubclass,
+            .Protocol               = HID_CSCP_NonBootProtocol,
+
+            .InterfaceStrIndex      = NO_DESCRIPTOR
+        },
+
+    .Console_HID =
+        {
+            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+            .HIDSpec                = VERSION_BCD(1,1,1),
+            .CountryCode            = 0x00,
+            .TotalReportDescriptors = 1,
+            .HIDReportType          = HID_DTYPE_Report,
+            .HIDReportLength        = sizeof(ConsoleReport)
+        },
+
+    .Console_INEndpoint =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+            .EndpointAddress        = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM),
+            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+            .EndpointSize           = CONSOLE_EPSIZE,
+            .PollingIntervalMS      = 0x01
+        },
+
+    .Console_OUTEndpoint =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+            .EndpointAddress        = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM),
+            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+            .EndpointSize           = CONSOLE_EPSIZE,
+            .PollingIntervalMS      = 0x01
+        },
+#endif
+
+    /*
+     * NKRO
+     */
+#ifdef NKRO_ENABLE
+    .NKRO_Interface =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+            .InterfaceNumber        = NKRO_INTERFACE,
+            .AlternateSetting       = 0x00,
+
+            .TotalEndpoints         = 1,
+
+            .Class                  = HID_CSCP_HIDClass,
+            .SubClass               = HID_CSCP_NonBootSubclass,
+            .Protocol               = HID_CSCP_NonBootProtocol,
+
+            .InterfaceStrIndex      = NO_DESCRIPTOR
+        },
+
+    .NKRO_HID =
+        {
+            .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+            .HIDSpec                = VERSION_BCD(1,1,1),
+            .CountryCode            = 0x00,
+            .TotalReportDescriptors = 1,
+            .HIDReportType          = HID_DTYPE_Report,
+            .HIDReportLength        = sizeof(NKROReport)
+        },
+
+    .NKRO_INEndpoint =
+        {
+            .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+            .EndpointAddress        = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
+            .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+            .EndpointSize           = NKRO_EPSIZE,
+            .PollingIntervalMS      = 0x01
+        },
+#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},
+
+            .InterfaceNumber          = AC_INTERFACE,
+            .AlternateSetting         = 0,
+
+            .TotalEndpoints           = 0,
+
+            .Class                    = AUDIO_CSCP_AudioClass,
+            .SubClass                 = AUDIO_CSCP_ControlSubclass,
+            .Protocol                 = AUDIO_CSCP_ControlProtocol,
+
+            .InterfaceStrIndex        = NO_DESCRIPTOR
+        },
+
+    .Audio_ControlInterface_SPC =
+        {
+            .Header                   = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
+            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_Header,
+
+            .ACSpecification          = VERSION_BCD(1,0,0),
+            .TotalLength              = sizeof(USB_Audio_Descriptor_Interface_AC_t),
+
+            .InCollection             = 1,
+            .InterfaceNumber          = AS_INTERFACE,
+        },
+
+    .Audio_StreamInterface =
+        {
+            .Header                   = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+            .InterfaceNumber          = AS_INTERFACE,
+            .AlternateSetting         = 0,
+
+            .TotalEndpoints           = 2,
+
+            .Class                    = AUDIO_CSCP_AudioClass,
+            .SubClass                 = AUDIO_CSCP_MIDIStreamingSubclass,
+            .Protocol                 = AUDIO_CSCP_StreamingProtocol,
+
+            .InterfaceStrIndex        = NO_DESCRIPTOR
+        },
+
+    .Audio_StreamInterface_SPC =
+        {
+            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
+            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_General,
+
+            .AudioSpecification       = VERSION_BCD(1,0,0),
+
+            .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 =
+        {
+            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
+            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
+
+            .JackType                 = MIDI_JACKTYPE_Embedded,
+            .JackID                   = 0x01,
+
+            .JackStrIndex             = NO_DESCRIPTOR
+        },
+
+    .MIDI_In_Jack_Ext =
+        {
+            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
+            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
+
+            .JackType                 = MIDI_JACKTYPE_External,
+            .JackID                   = 0x02,
+
+            .JackStrIndex             = NO_DESCRIPTOR
+        },
+
+    .MIDI_Out_Jack_Emb =
+        {
+            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
+            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
+
+            .JackType                 = MIDI_JACKTYPE_Embedded,
+            .JackID                   = 0x03,
+
+            .NumberOfPins             = 1,
+            .SourceJackID             = {0x02},
+            .SourcePinID              = {0x01},
+
+            .JackStrIndex             = NO_DESCRIPTOR
+        },
+
+    .MIDI_Out_Jack_Ext =
+        {
+            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
+            .Subtype                  = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
+
+            .JackType                 = MIDI_JACKTYPE_External,
+            .JackID                   = 0x04,
+
+            .NumberOfPins             = 1,
+            .SourceJackID             = {0x01},
+            .SourcePinID              = {0x01},
+
+            .JackStrIndex             = NO_DESCRIPTOR
+        },
+
+    .MIDI_In_Jack_Endpoint =
+        {
+            .Endpoint =
+                {
+                    .Header              = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
+
+                    .EndpointAddress     = MIDI_STREAM_OUT_EPADDR,
+                    .Attributes          = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+                    .EndpointSize        = MIDI_STREAM_EPSIZE,
+                    .PollingIntervalMS   = 0x05
+                },
+
+            .Refresh                  = 0,
+            .SyncEndpointNumber       = 0
+        },
+
+    .MIDI_In_Jack_Endpoint_SPC =
+        {
+            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
+            .Subtype                  = AUDIO_DSUBTYPE_CSEndpoint_General,
+
+            .TotalEmbeddedJacks       = 0x01,
+            .AssociatedJackID         = {0x01}
+        },
+
+    .MIDI_Out_Jack_Endpoint =
+        {
+            .Endpoint =
+                {
+                    .Header              = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
+
+                    .EndpointAddress     = MIDI_STREAM_IN_EPADDR,
+                    .Attributes          = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+                    .EndpointSize        = MIDI_STREAM_EPSIZE,
+                    .PollingIntervalMS   = 0x05
+                },
+
+            .Refresh                  = 0,
+            .SyncEndpointNumber       = 0
+        },
+
+    .MIDI_Out_Jack_Endpoint_SPC =
+        {
+            .Header                   = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
+            .Subtype                  = AUDIO_DSUBTYPE_CSEndpoint_General,
+
+            .TotalEmbeddedJacks       = 0x01,
+            .AssociatedJackID         = {0x03}
+        },
+#endif
+
+#ifdef VIRTSER_ENABLE
+    .CDC_Interface_Association =
+            {
+                    .Header                 = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
+
+                    .FirstInterfaceIndex    = CCI_INTERFACE,
+                    .TotalInterfaces        = 2,
+
+                    .Class                  = CDC_CSCP_CDCClass,
+                    .SubClass               = CDC_CSCP_ACMSubclass,
+                    .Protocol               = CDC_CSCP_ATCommandProtocol,
+
+                    .IADStrIndex            = NO_DESCRIPTOR,
+            },
+
+    .CDC_CCI_Interface =
+            {
+                    .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+                    .InterfaceNumber        = CCI_INTERFACE,
+                    .AlternateSetting       = 0,
+
+                    .TotalEndpoints         = 1,
+
+                    .Class                  = CDC_CSCP_CDCClass,
+                    .SubClass               = CDC_CSCP_ACMSubclass,
+                    .Protocol               = CDC_CSCP_ATCommandProtocol,
+
+                    .InterfaceStrIndex      = NO_DESCRIPTOR
+            },
+
+    .CDC_Functional_Header =
+            {
+                    .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+                    .Subtype                = 0x00,
+
+                    .CDCSpecification       = VERSION_BCD(1,1,0),
+            },
+
+    .CDC_Functional_ACM =
+            {
+                    .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+                    .Subtype                = 0x02,
+
+                    .Capabilities           = 0x02,
+            },
+
+    .CDC_Functional_Union =
+            {
+                    .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+                    .Subtype                = 0x06,
+
+                    .MasterInterfaceNumber  = CCI_INTERFACE,
+                    .SlaveInterfaceNumber   = CDI_INTERFACE,
+            },
+
+    .CDC_NotificationEndpoint =
+            {
+                    .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+                    .EndpointAddress        = CDC_NOTIFICATION_EPADDR,
+                    .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+                    .EndpointSize           = CDC_NOTIFICATION_EPSIZE,
+                    .PollingIntervalMS      = 0xFF
+            },
+
+    .CDC_DCI_Interface =
+            {
+                    .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+                    .InterfaceNumber        = CDI_INTERFACE,
+                    .AlternateSetting       = 0,
+
+                    .TotalEndpoints         = 2,
+
+                    .Class                  = CDC_CSCP_CDCDataClass,
+                    .SubClass               = CDC_CSCP_NoDataSubclass,
+                    .Protocol               = CDC_CSCP_NoDataProtocol,
+
+                    .InterfaceStrIndex      = NO_DESCRIPTOR
+            },
+
+    .CDC_DataOutEndpoint =
+            {
+                    .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+                    .EndpointAddress        = CDC_OUT_EPADDR,
+                    .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+                    .EndpointSize           = CDC_EPSIZE,
+                    .PollingIntervalMS      = 0x05
+            },
+
+    .CDC_DataInEndpoint =
+            {
+                    .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+                    .EndpointAddress        = CDC_IN_EPADDR,
+                    .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+                    .EndpointSize           = CDC_EPSIZE,
+                    .PollingIntervalMS      = 0x05
+            },
+#endif
+};
+
+
+/*******************************************************************************
+ * String Descriptors
+ ******************************************************************************/
+const USB_Descriptor_String_t PROGMEM LanguageString =
+{
+    .Header                 = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+    .UnicodeString          = {LANGUAGE_ID_ENG}
+};
+
+const USB_Descriptor_String_t PROGMEM ManufacturerString =
+{
+    /* subtract 1 for null terminator */
+    .Header                 = {.Size = USB_STRING_LEN(sizeof(STR(MANUFACTURER))-1), .Type = DTYPE_String},
+
+    .UnicodeString          = LSTR(MANUFACTURER)
+};
+
+const USB_Descriptor_String_t PROGMEM ProductString =
+{
+    /* subtract 1 for null terminator */
+    .Header                 = {.Size = USB_STRING_LEN(sizeof(STR(PRODUCT))-1), .Type = DTYPE_String},
+
+    .UnicodeString          = LSTR(PRODUCT)
+};
+
+#ifndef SERIAL_NUMBER
+    #define SERIAL_NUMBER 0
+#endif
+
+const USB_Descriptor_String_t PROGMEM SerialNumberString =
+{
+    /* subtract 1 for null terminator */
+    .Header                 = {.Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER))-1), .Type = DTYPE_String},
+
+    .UnicodeString          = LSTR(SERIAL_NUMBER)
+};
+
+
+/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
+ *  documentation) by the application code so that the address and size of a requested descriptor can be given
+ *  to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ *  USB host.
+ */
+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);
+
+    const void* Address = NULL;
+    uint16_t    Size    = NO_DESCRIPTOR;
+
+    switch (DescriptorType)
+    {
+        case DTYPE_Device:
+            Address = &DeviceDescriptor;
+            Size    = sizeof(USB_Descriptor_Device_t);
+            break;
+        case DTYPE_Configuration:
+            Address = &ConfigurationDescriptor;
+            Size    = sizeof(USB_Descriptor_Configuration_t);
+            break;
+        case DTYPE_String:
+            switch (DescriptorIndex )
+            {
+                case 0x00:
+                    Address = &LanguageString;
+                    Size    = pgm_read_byte(&LanguageString.Header.Size);
+                    break;
+                case 0x01:
+                    Address = &ManufacturerString;
+                    Size    = pgm_read_byte(&ManufacturerString.Header.Size);
+                    break;
+                case 0x02:
+                    Address = &ProductString;
+                    Size    = pgm_read_byte(&ProductString.Header.Size);
+                    break;
+                case 0x03:
+                    Address = &SerialNumberString;
+                    Size    = pgm_read_byte(&SerialNumberString.Header.Size);
+                    break;
+            }
+            break;
+        case HID_DTYPE_HID:
+            switch (wIndex) {
+            case KEYBOARD_INTERFACE:
+                Address = &ConfigurationDescriptor.Keyboard_HID;
+                Size    = sizeof(USB_HID_Descriptor_HID_t);
+                break;
+#ifdef MOUSE_ENABLE
+            case MOUSE_INTERFACE:
+                Address = &ConfigurationDescriptor.Mouse_HID;
+                Size    = sizeof(USB_HID_Descriptor_HID_t);
+                break;
+#endif
+#ifdef EXTRAKEY_ENABLE
+            case EXTRAKEY_INTERFACE:
+                Address = &ConfigurationDescriptor.Extrakey_HID;
+                Size    = sizeof(USB_HID_Descriptor_HID_t);
+                break;
+#endif
+#ifdef RAW_ENABLE
+            case RAW_INTERFACE:
+                Address = &ConfigurationDescriptor.Raw_HID;
+                Size    = sizeof(USB_HID_Descriptor_HID_t);
+                break;
+#endif
+#ifdef CONSOLE_ENABLE
+            case CONSOLE_INTERFACE:
+                Address = &ConfigurationDescriptor.Console_HID;
+                Size    = sizeof(USB_HID_Descriptor_HID_t);
+                break;
+#endif
+#ifdef NKRO_ENABLE
+            case NKRO_INTERFACE:
+                Address = &ConfigurationDescriptor.NKRO_HID;
+                Size    = sizeof(USB_HID_Descriptor_HID_t);
+                break;
+#endif
+            }
+            break;
+        case HID_DTYPE_Report:
+            switch (wIndex) {
+            case KEYBOARD_INTERFACE:
+                Address = &KeyboardReport;
+                Size    = sizeof(KeyboardReport);
+                break;
+#ifdef MOUSE_ENABLE
+            case MOUSE_INTERFACE:
+                Address = &MouseReport;
+                Size    = sizeof(MouseReport);
+                break;
+#endif
+#ifdef EXTRAKEY_ENABLE
+            case EXTRAKEY_INTERFACE:
+                Address = &ExtrakeyReport;
+                Size    = sizeof(ExtrakeyReport);
+                break;
+#endif
+#ifdef RAW_ENABLE
+            case RAW_INTERFACE:
+                Address = &RawReport;
+                Size    = sizeof(RawReport);
+                break;
+#endif
+#ifdef CONSOLE_ENABLE
+            case CONSOLE_INTERFACE:
+                Address = &ConsoleReport;
+                Size    = sizeof(ConsoleReport);
+                break;
+#endif
+#ifdef NKRO_ENABLE
+            case NKRO_INTERFACE:
+                Address = &NKROReport;
+                Size    = sizeof(NKROReport);
+                break;
+#endif
+            }
+            break;
+    }
+
+    *DescriptorAddress = Address;
+    return Size;
+}
diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h
new file mode 100644 (file)
index 0000000..1eedfe5
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
+ * This file is based on:
+ *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
+ *     LUFA-120219/Demos/Device/Lowlevel/GenericHID
+ */
+
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2012.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+  Copyright 2010  Denver Gingerich (denver [at] ossguy [dot] com)
+
+  Permission to use, copy, modify, distribute, and sell this
+  software and its documentation for any purpose is hereby granted
+  without fee, provided that the above copyright notice appear in
+  all copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+/** \file
+ *
+ *  Header file for Descriptors.c.
+ */
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+#include <LUFA/Drivers/USB/USB.h>
+#ifdef PROTOCOL_CHIBIOS
+#include "hal.h"
+#endif
+
+typedef struct
+{
+    USB_Descriptor_Configuration_Header_t Config;
+
+    // Keyboard HID Interface
+    USB_Descriptor_Interface_t            Keyboard_Interface;
+    USB_HID_Descriptor_HID_t              Keyboard_HID;
+    USB_Descriptor_Endpoint_t             Keyboard_INEndpoint;
+
+#ifdef MOUSE_ENABLE
+    // Mouse HID Interface
+    USB_Descriptor_Interface_t            Mouse_Interface;
+    USB_HID_Descriptor_HID_t              Mouse_HID;
+    USB_Descriptor_Endpoint_t             Mouse_INEndpoint;
+#endif
+
+#ifdef EXTRAKEY_ENABLE
+    // Extrakey HID Interface
+    USB_Descriptor_Interface_t            Extrakey_Interface;
+    USB_HID_Descriptor_HID_t              Extrakey_HID;
+    USB_Descriptor_Endpoint_t             Extrakey_INEndpoint;
+#endif
+
+#ifdef RAW_ENABLE
+    // Raw HID Interface
+    USB_Descriptor_Interface_t            Raw_Interface;
+    USB_HID_Descriptor_HID_t              Raw_HID;
+    USB_Descriptor_Endpoint_t             Raw_INEndpoint;
+    USB_Descriptor_Endpoint_t             Raw_OUTEndpoint;
+#endif
+
+#ifdef CONSOLE_ENABLE
+    // Console HID Interface
+    USB_Descriptor_Interface_t            Console_Interface;
+    USB_HID_Descriptor_HID_t              Console_HID;
+    USB_Descriptor_Endpoint_t             Console_INEndpoint;
+    USB_Descriptor_Endpoint_t             Console_OUTEndpoint;
+#endif
+
+#ifdef NKRO_ENABLE
+    // NKRO HID Interface
+    USB_Descriptor_Interface_t            NKRO_Interface;
+    USB_HID_Descriptor_HID_t              NKRO_HID;
+    USB_Descriptor_Endpoint_t             NKRO_INEndpoint;
+#endif
+
+#ifdef MIDI_ENABLE
+    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;
+#endif
+
+#ifdef VIRTSER_ENABLE
+  USB_Descriptor_Interface_Association_t   CDC_Interface_Association;
+
+       // CDC Control Interface
+       USB_Descriptor_Interface_t               CDC_CCI_Interface;
+       USB_CDC_Descriptor_FunctionalHeader_t    CDC_Functional_Header;
+       USB_CDC_Descriptor_FunctionalACM_t       CDC_Functional_ACM;
+       USB_CDC_Descriptor_FunctionalUnion_t     CDC_Functional_Union;
+       USB_Descriptor_Endpoint_t                CDC_NotificationEndpoint;
+
+       // CDC Data Interface
+       USB_Descriptor_Interface_t               CDC_DCI_Interface;
+       USB_Descriptor_Endpoint_t                CDC_DataOutEndpoint;
+       USB_Descriptor_Endpoint_t                CDC_DataInEndpoint;
+#endif
+} USB_Descriptor_Configuration_t;
+
+
+/* index of interface */
+#define KEYBOARD_INTERFACE          0
+
+// It is important that the Raw HID interface is at a constant
+// interface number, to support Linux/OSX platforms and chrome.hid
+// If Raw HID is enabled, let it be always 1.
+#ifdef RAW_ENABLE
+#   define RAW_INTERFACE               (KEYBOARD_INTERFACE + 1)
+#else
+#   define RAW_INTERFACE               KEYBOARD_INTERFACE
+#endif
+
+#ifdef MOUSE_ENABLE
+#   define MOUSE_INTERFACE          (RAW_INTERFACE + 1)
+#else
+#   define MOUSE_INTERFACE          RAW_INTERFACE
+#endif
+
+#ifdef EXTRAKEY_ENABLE
+#   define EXTRAKEY_INTERFACE       (MOUSE_INTERFACE + 1)
+#else
+#   define EXTRAKEY_INTERFACE       MOUSE_INTERFACE
+#endif
+
+#ifdef CONSOLE_ENABLE
+#   define CONSOLE_INTERFACE        (EXTRAKEY_INTERFACE + 1)
+#else
+#   define CONSOLE_INTERFACE        EXTRAKEY_INTERFACE
+#endif
+
+#ifdef NKRO_ENABLE
+#   define NKRO_INTERFACE           (CONSOLE_INTERFACE + 1)
+#else
+#   define NKRO_INTERFACE           CONSOLE_INTERFACE
+#endif
+
+#ifdef MIDI_ENABLE
+#   define AC_INTERFACE           (NKRO_INTERFACE + 1)
+#   define AS_INTERFACE           (NKRO_INTERFACE + 2)
+#else
+#   define AS_INTERFACE           NKRO_INTERFACE
+#endif
+
+#ifdef VIRTSER_ENABLE
+#   define CCI_INTERFACE         (AS_INTERFACE + 1)
+#   define CDI_INTERFACE         (AS_INTERFACE + 2)
+#else
+#   define CDI_INTERFACE         AS_INTERFACE
+#endif
+
+/* nubmer of interfaces */
+#define TOTAL_INTERFACES            (CDI_INTERFACE + 1)
+
+
+// Endopoint number and size
+#define KEYBOARD_IN_EPNUM           1
+
+#ifdef MOUSE_ENABLE
+#   define MOUSE_IN_EPNUM           (KEYBOARD_IN_EPNUM + 1)
+#else
+#   define MOUSE_IN_EPNUM           KEYBOARD_IN_EPNUM
+#endif
+
+#ifdef EXTRAKEY_ENABLE
+#   define EXTRAKEY_IN_EPNUM        (MOUSE_IN_EPNUM + 1)
+#else
+#   define EXTRAKEY_IN_EPNUM        MOUSE_IN_EPNUM
+#endif
+
+#ifdef RAW_ENABLE
+#   define RAW_IN_EPNUM         (EXTRAKEY_IN_EPNUM + 1)
+#   define RAW_OUT_EPNUM        (EXTRAKEY_IN_EPNUM + 2)
+#else
+#   define RAW_OUT_EPNUM        EXTRAKEY_IN_EPNUM
+#endif
+
+#ifdef CONSOLE_ENABLE
+#   define CONSOLE_IN_EPNUM         (RAW_OUT_EPNUM + 1)
+#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
+
+#ifdef NKRO_ENABLE
+#   define NKRO_IN_EPNUM            (CONSOLE_OUT_EPNUM + 1)
+#else
+#   define NKRO_IN_EPNUM            CONSOLE_OUT_EPNUM
+#endif
+
+#ifdef MIDI_ENABLE
+#   define MIDI_STREAM_IN_EPNUM     (NKRO_IN_EPNUM + 1)
+// #   define MIDI_STREAM_OUT_EPNUM    (NKRO_IN_EPNUM + 1)
+#   define MIDI_STREAM_OUT_EPNUM    (NKRO_IN_EPNUM + 2)
+#   define MIDI_STREAM_IN_EPADDR    (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM)
+#   define MIDI_STREAM_OUT_EPADDR   (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM)
+#else
+#   define MIDI_STREAM_OUT_EPNUM     NKRO_IN_EPNUM
+#endif
+
+#ifdef VIRTSER_ENABLE
+#   define CDC_NOTIFICATION_EPNUM   (MIDI_STREAM_OUT_EPNUM + 1)
+#   define CDC_IN_EPNUM                    (MIDI_STREAM_OUT_EPNUM + 2)
+#   define CDC_OUT_EPNUM                   (MIDI_STREAM_OUT_EPNUM + 3)
+#   define CDC_NOTIFICATION_EPADDR        (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM)
+#   define CDC_IN_EPADDR                  (ENDPOINT_DIR_IN | CDC_IN_EPNUM)
+#   define CDC_OUT_EPADDR                  (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM)
+#else
+#   define CDC_OUT_EPNUM       MIDI_STREAM_OUT_EPNUM
+#endif
+
+#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 CONSOLE_EPSIZE              32
+#define NKRO_EPSIZE                 32
+#define MIDI_STREAM_EPSIZE          64
+#define CDC_NOTIFICATION_EPSIZE     32
+#define CDC_EPSIZE                  16
+
+uint16_t get_usb_descriptor(const uint16_t wValue,
+                            const uint16_t wIndex,
+                            const void** const DescriptorAddress);
+
+/* new API */
+#if LUFA_VERSION_INTEGER < 0x140302
+    #undef VERSION_BCD
+    #define VERSION_BCD(Major, Minor, Revision) \
+                                              CPU_TO_LE16( ((Major & 0xFF) << 8) | \
+                                                           ((Minor & 0x0F) << 4) | \
+                                                           (Revision & 0x0F) )
+#endif
+
+#endif