aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/chibios.mk2
-rw-r--r--tmk_core/common/host_driver.h5
-rw-r--r--tmk_core/common/keyboard.c7
-rw-r--r--tmk_core/common/report.h30
-rw-r--r--tmk_core/protocol/chibios.mk9
-rw-r--r--tmk_core/protocol/chibios/lufa_utils/LUFA/Drivers/USB/USB.h42
-rw-r--r--tmk_core/protocol/chibios/main.c27
-rw-r--r--tmk_core/protocol/chibios/usb_main.c1027
-rw-r--r--tmk_core/protocol/chibios/usb_main.h34
-rw-r--r--tmk_core/protocol/lufa.mk4
-rw-r--r--tmk_core/protocol/lufa/lufa.c338
-rw-r--r--tmk_core/protocol/lufa/lufa.h10
-rw-r--r--tmk_core/protocol/midi.mk3
-rwxr-xr-xtmk_core/protocol/midi/bytequeue/interrupt_setting.c15
-rw-r--r--tmk_core/protocol/midi/qmk_midi.c184
-rw-r--r--tmk_core/protocol/midi/qmk_midi.h9
-rw-r--r--tmk_core/protocol/usb_descriptor.c (renamed from tmk_core/protocol/lufa/descriptor.c)26
-rw-r--r--tmk_core/protocol/usb_descriptor.h (renamed from tmk_core/protocol/lufa/descriptor.h)65
18 files changed, 676 insertions, 1161 deletions
diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk
index 1cd0146fe..7c7f658b2 100644
--- a/tmk_core/chibios.mk
+++ b/tmk_core/chibios.mk
@@ -149,6 +149,7 @@ COMPILEFLAGS += -falign-functions=16
149COMPILEFLAGS += -ffunction-sections 149COMPILEFLAGS += -ffunction-sections
150COMPILEFLAGS += -fdata-sections 150COMPILEFLAGS += -fdata-sections
151COMPILEFLAGS += -fno-common 151COMPILEFLAGS += -fno-common
152COMPILEFLAGS += -fshort-wchar
152COMPILEFLAGS += $(THUMBFLAGS) 153COMPILEFLAGS += $(THUMBFLAGS)
153 154
154CFLAGS += $(COMPILEFLAGS) 155CFLAGS += $(COMPILEFLAGS)
@@ -159,6 +160,7 @@ CPPFLAGS += $(COMPILEFLAGS)
159CPPFLAGS += -fno-rtti 160CPPFLAGS += -fno-rtti
160 161
161LDFLAGS +=-Wl,--gc-sections 162LDFLAGS +=-Wl,--gc-sections
163LDFLAGS +=-Wl,--no-wchar-size-warning
162LDFLAGS += -mno-thumb-interwork -mthumb 164LDFLAGS += -mno-thumb-interwork -mthumb
163LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE) 165LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE)
164LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE) 166LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE)
diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h
index 588d1c0be..e40f0bfd6 100644
--- a/tmk_core/common/host_driver.h
+++ b/tmk_core/common/host_driver.h
@@ -30,11 +30,6 @@ typedef struct {
30 void (*send_mouse)(report_mouse_t *); 30 void (*send_mouse)(report_mouse_t *);
31 void (*send_system)(uint16_t); 31 void (*send_system)(uint16_t);
32 void (*send_consumer)(uint16_t); 32 void (*send_consumer)(uint16_t);
33#ifdef MIDI_ENABLE
34 void (*usb_send_func)(MidiDevice *, uint16_t, uint8_t, uint8_t, uint8_t);
35 void (*usb_get_midi)(MidiDevice *);
36 void (*midi_usb_init)(MidiDevice *);
37#endif
38} host_driver_t; 33} host_driver_t;
39 34
40#endif 35#endif
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 436fb6073..001fb00ce 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -66,6 +66,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
66#ifdef POINTING_DEVICE_ENABLE 66#ifdef POINTING_DEVICE_ENABLE
67# include "pointing_device.h" 67# include "pointing_device.h"
68#endif 68#endif
69#ifdef MIDI_ENABLE
70# include "process_midi.h"
71#endif
69 72
70#ifdef MATRIX_HAS_GHOST 73#ifdef MATRIX_HAS_GHOST
71extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; 74extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
@@ -260,6 +263,10 @@ MATRIX_LOOP_END:
260 pointing_device_task(); 263 pointing_device_task();
261#endif 264#endif
262 265
266#ifdef MIDI_ENABLE
267 midi_task();
268#endif
269
263 // update LED 270 // update LED
264 if (led_status != host_keyboard_leds()) { 271 if (led_status != host_keyboard_leds()) {
265 led_status = host_keyboard_leds(); 272 led_status = host_keyboard_leds();
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index a0811f9a3..6c27eb9dc 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -73,22 +73,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
73 73
74 74
75/* key report size(NKRO or boot mode) */ 75/* key report size(NKRO or boot mode) */
76#if defined(PROTOCOL_PJRC) && defined(NKRO_ENABLE) 76#if defined(NKRO_ENABLE)
77# include "usb.h" 77 #if defined(PROTOCOL_PJRC)
78# define KEYBOARD_REPORT_SIZE KBD2_SIZE 78 #include "usb.h"
79# define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2) 79 #define KEYBOARD_REPORT_SIZE KBD2_SIZE
80# define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1) 80 #define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
81 81 #define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
82#elif defined(PROTOCOL_LUFA) && defined(NKRO_ENABLE) 82 #elif defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
83# include "protocol/lufa/descriptor.h" 83 #include "protocol/usb_descriptor.h"
84# define KEYBOARD_REPORT_SIZE NKRO_EPSIZE 84 #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
85# define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2) 85 #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
86# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) 86 #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
87#elif defined(PROTOCOL_CHIBIOS) && defined(NKRO_ENABLE) 87 #else
88# include "protocol/chibios/usb_main.h" 88 #error "NKRO not supported with this protocol"
89# define KEYBOARD_REPORT_SIZE NKRO_EPSIZE 89#endif
90# define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
91# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
92 90
93#else 91#else
94# define KEYBOARD_REPORT_SIZE 8 92# define KEYBOARD_REPORT_SIZE 8
diff --git a/tmk_core/protocol/chibios.mk b/tmk_core/protocol/chibios.mk
index 3f4e0a71f..6e7cfbd83 100644
--- a/tmk_core/protocol/chibios.mk
+++ b/tmk_core/protocol/chibios.mk
@@ -4,7 +4,16 @@ CHIBIOS_DIR = $(PROTOCOL_DIR)/chibios
4 4
5SRC += $(CHIBIOS_DIR)/usb_main.c 5SRC += $(CHIBIOS_DIR)/usb_main.c
6SRC += $(CHIBIOS_DIR)/main.c 6SRC += $(CHIBIOS_DIR)/main.c
7SRC += usb_descriptor.c
7 8
8VPATH += $(TMK_PATH)/$(PROTOCOL_DIR) 9VPATH += $(TMK_PATH)/$(PROTOCOL_DIR)
9VPATH += $(TMK_PATH)/$(CHIBIOS_DIR) 10VPATH += $(TMK_PATH)/$(CHIBIOS_DIR)
11VPATH += $(TMK_PATH)/$(CHIBIOS_DIR)/lufa_utils
12
13OPT_DEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=64
14OPT_DEFS += -DFIXED_NUM_CONFIGURATIONS=1
15
16ifeq ($(strip $(MIDI_ENABLE)), yes)
17 include $(TMK_PATH)/protocol/midi.mk
18endif
10 19
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
index 000000000..a5374d820
--- /dev/null
+++ b/tmk_core/protocol/chibios/lufa_utils/LUFA/Drivers/USB/USB.h
@@ -0,0 +1,42 @@
1#include "progmem.h"
2#include "stddef.h"
3#include "inttypes.h"
4
5#define ATTR_PACKED __attribute__ ((packed))
6/** Concatenates the given input into a single token, via the C Preprocessor.
7 *
8 * \param[in] x First item to concatenate.
9 * \param[in] y Second item to concatenate.
10 *
11 * \return Concatenated version of the input.
12 */
13#define CONCAT(x, y) x ## y
14
15/** CConcatenates the given input into a single token after macro expansion, via the C Preprocessor.
16 *
17 * \param[in] x First item to concatenate.
18 * \param[in] y Second item to concatenate.
19 *
20 * \return Concatenated version of the expanded input.
21 */
22#define CONCAT_EXPANDED(x, y) CONCAT(x, y)
23#define CPU_TO_LE16(x) (x)
24
25// We don't need anything from the following files, or we have defined it already
26#define __LUFA_COMMON_H__
27#define __USBMODE_H__
28#define __USBEVENTS_H__
29#define __HIDPARSER_H__
30#define __USBCONTROLLER_AVR8_H__
31
32#define __INCLUDE_FROM_USB_DRIVER
33#define __INCLUDE_FROM_HID_DRIVER
34#define __INCLUDE_FROM_CDC_DRIVER
35#define __INCLUDE_FROM_AUDIO_DRIVER
36#define __INCLUDE_FROM_MIDI_DRIVER
37#include "lib/lufa/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h"
38#include "lib/lufa/LUFA/Drivers/USB/Class/Common/HIDReportData.h"
39#include "lib/lufa/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h"
40#include "lib/lufa/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h"
41#include "lib/lufa/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h"
42#include "lib/lufa/LUFA/Drivers/USB/Core/USBController.h"
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index 47a7eb09a..f2abc438d 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -41,6 +41,9 @@
41#ifdef VISUALIZER_ENABLE 41#ifdef VISUALIZER_ENABLE
42#include "visualizer/visualizer.h" 42#include "visualizer/visualizer.h"
43#endif 43#endif
44#ifdef MIDI_ENABLE
45#include "qmk_midi.h"
46#endif
44#include "suspend.h" 47#include "suspend.h"
45#include "wait.h" 48#include "wait.h"
46 49
@@ -65,6 +68,17 @@ host_driver_t chibios_driver = {
65 send_consumer 68 send_consumer
66}; 69};
67 70
71#ifdef VIRTSER_ENABLE
72void virtser_task(void);
73#endif
74
75#ifdef RAW_HID_ENABLE
76void raw_hid_task(void);
77#endif
78
79#ifdef CONSOLE_ENABLE
80void console_task(void);
81#endif
68 82
69/* TESTING 83/* TESTING
70 * Amber LED blinker thread, times are in milliseconds. 84 * Amber LED blinker thread, times are in milliseconds.
@@ -104,6 +118,10 @@ int main(void) {
104 /* init printf */ 118 /* init printf */
105 init_printf(NULL,sendchar_pf); 119 init_printf(NULL,sendchar_pf);
106 120
121#ifdef MIDI_ENABLE
122 setup_midi();
123#endif
124
107#ifdef SERIAL_LINK_ENABLE 125#ifdef SERIAL_LINK_ENABLE
108 init_serial_link(); 126 init_serial_link();
109#endif 127#endif
@@ -182,5 +200,14 @@ int main(void) {
182 } 200 }
183 201
184 keyboard_task(); 202 keyboard_task();
203#ifdef CONSOLE_ENABLE
204 console_task();
205#endif
206#ifdef VIRTSER_ENABLE
207 virtser_task();
208#endif
209#ifdef RAW_HID_ENABLE
210 raw_hid_task();
211#endif
185 } 212 }
186} 213}
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index caa2770b5..f980024ab 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -28,6 +28,7 @@
28#include "led.h" 28#include "led.h"
29#endif 29#endif
30#include "wait.h" 30#include "wait.h"
31#include "usb_descriptor.h"
31 32
32#ifdef NKRO_ENABLE 33#ifdef NKRO_ENABLE
33 #include "keycode_config.h" 34 #include "keycode_config.h"
@@ -63,24 +64,12 @@ report_mouse_t mouse_report_blank = {0};
63uint8_t extra_report_blank[3] = {0}; 64uint8_t extra_report_blank[3] = {0};
64#endif /* EXTRAKEY_ENABLE */ 65#endif /* EXTRAKEY_ENABLE */
65 66
66#ifdef CONSOLE_ENABLE
67/* The emission buffers queue */
68output_buffers_queue_t console_buf_queue;
69static uint8_t console_queue_buffer[BQ_BUFFER_SIZE(CONSOLE_QUEUE_CAPACITY, CONSOLE_EPSIZE)];
70
71static virtual_timer_t console_flush_timer;
72void console_queue_onotify(io_buffers_queue_t *bqp);
73static void console_flush_cb(void *arg);
74#endif /* CONSOLE_ENABLE */
75
76/* --------------------------------------------------------- 67/* ---------------------------------------------------------
77 * Descriptors and USB driver objects 68 * Descriptors and USB driver objects
78 * --------------------------------------------------------- 69 * ---------------------------------------------------------
79 */ 70 */
80 71
81/* HID specific constants */ 72/* HID specific constants */
82#define USB_DESCRIPTOR_HID 0x21
83#define USB_DESCRIPTOR_HID_REPORT 0x22
84#define HID_GET_REPORT 0x01 73#define HID_GET_REPORT 0x01
85#define HID_GET_IDLE 0x02 74#define HID_GET_IDLE 0x02
86#define HID_GET_PROTOCOL 0x03 75#define HID_GET_PROTOCOL 0x03
@@ -88,593 +77,21 @@ static void console_flush_cb(void *arg);
88#define HID_SET_IDLE 0x0A 77#define HID_SET_IDLE 0x0A
89#define HID_SET_PROTOCOL 0x0B 78#define HID_SET_PROTOCOL 0x0B
90 79
91/* USB Device Descriptor */
92static const uint8_t usb_device_descriptor_data[] = {
93 USB_DESC_DEVICE(0x0200, // bcdUSB (1.1)
94 0, // bDeviceClass (defined in later in interface)
95 0, // bDeviceSubClass
96 0, // bDeviceProtocol
97 64, // bMaxPacketSize (64 bytes) (the driver didn't work with 32)
98 VENDOR_ID, // idVendor
99 PRODUCT_ID, // idProduct
100 DEVICE_VER, // bcdDevice
101 1, // iManufacturer
102 2, // iProduct
103 3, // iSerialNumber
104 1) // bNumConfigurations
105};
106
107/* Device Descriptor wrapper */
108static const USBDescriptor usb_device_descriptor = {
109 sizeof usb_device_descriptor_data,
110 usb_device_descriptor_data
111};
112
113/*
114 * HID Report Descriptor
115 *
116 * See "Device Class Definition for Human Interface Devices (HID)"
117 * (http://www.usb.org/developers/hidpage/HID1_11.pdf) for the
118 * detailed descrition of all the fields
119 */
120
121/* Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 */
122static const uint8_t keyboard_hid_report_desc_data[] = {
123 0x05, 0x01, // Usage Page (Generic Desktop),
124 0x09, 0x06, // Usage (Keyboard),
125 0xA1, 0x01, // Collection (Application),
126 0x75, 0x01, // Report Size (1),
127 0x95, 0x08, // Report Count (8),
128 0x05, 0x07, // Usage Page (Key Codes),
129 0x19, 0xE0, // Usage Minimum (224),
130 0x29, 0xE7, // Usage Maximum (231),
131 0x15, 0x00, // Logical Minimum (0),
132 0x25, 0x01, // Logical Maximum (1),
133 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
134 0x95, 0x01, // Report Count (1),
135 0x75, 0x08, // Report Size (8),
136 0x81, 0x03, // Input (Constant), ;Reserved byte
137 0x95, 0x05, // Report Count (5),
138 0x75, 0x01, // Report Size (1),
139 0x05, 0x08, // Usage Page (LEDs),
140 0x19, 0x01, // Usage Minimum (1),
141 0x29, 0x05, // Usage Maximum (5),
142 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
143 0x95, 0x01, // Report Count (1),
144 0x75, 0x03, // Report Size (3),
145 0x91, 0x03, // Output (Constant), ;LED report padding
146 0x95, KBD_REPORT_KEYS, // Report Count (),
147 0x75, 0x08, // Report Size (8),
148 0x15, 0x00, // Logical Minimum (0),
149 0x26, 0xFF, 0x00, // Logical Maximum(255),
150 0x05, 0x07, // Usage Page (Key Codes),
151 0x19, 0x00, // Usage Minimum (0),
152 0x29, 0xFF, // Usage Maximum (255),
153 0x81, 0x00, // Input (Data, Array),
154 0xc0 // End Collection
155};
156/* wrapper */
157static const USBDescriptor keyboard_hid_report_descriptor = {
158 sizeof keyboard_hid_report_desc_data,
159 keyboard_hid_report_desc_data
160};
161
162#ifdef NKRO_ENABLE
163static const uint8_t nkro_hid_report_desc_data[] = {
164 0x05, 0x01, // Usage Page (Generic Desktop),
165 0x09, 0x06, // Usage (Keyboard),
166 0xA1, 0x01, // Collection (Application),
167 // bitmap of modifiers
168 0x75, 0x01, // Report Size (1),
169 0x95, 0x08, // Report Count (8),
170 0x05, 0x07, // Usage Page (Key Codes),
171 0x19, 0xE0, // Usage Minimum (224),
172 0x29, 0xE7, // Usage Maximum (231),
173 0x15, 0x00, // Logical Minimum (0),
174 0x25, 0x01, // Logical Maximum (1),
175 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
176 // LED output report
177 0x95, 0x05, // Report Count (5),
178 0x75, 0x01, // Report Size (1),
179 0x05, 0x08, // Usage Page (LEDs),
180 0x19, 0x01, // Usage Minimum (1),
181 0x29, 0x05, // Usage Maximum (5),
182 0x91, 0x02, // Output (Data, Variable, Absolute),
183 0x95, 0x01, // Report Count (1),
184 0x75, 0x03, // Report Size (3),
185 0x91, 0x03, // Output (Constant),
186 // bitmap of keys
187 0x95, NKRO_REPORT_KEYS * 8, // Report Count (),
188 0x75, 0x01, // Report Size (1),
189 0x15, 0x00, // Logical Minimum (0),
190 0x25, 0x01, // Logical Maximum(1),
191 0x05, 0x07, // Usage Page (Key Codes),
192 0x19, 0x00, // Usage Minimum (0),
193 0x29, NKRO_REPORT_KEYS * 8 - 1, // Usage Maximum (),
194 0x81, 0x02, // Input (Data, Variable, Absolute),
195 0xc0 // End Collection
196};
197/* wrapper */
198static const USBDescriptor nkro_hid_report_descriptor = {
199 sizeof nkro_hid_report_desc_data,
200 nkro_hid_report_desc_data
201};
202#endif /* NKRO_ENABLE */
203
204#ifdef MOUSE_ENABLE
205/* Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
206 * http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
207 * http://www.keil.com/forum/15671/
208 * http://www.microsoft.com/whdc/device/input/wheel.mspx */
209static const uint8_t mouse_hid_report_desc_data[] = {
210 /* mouse */
211 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
212 0x09, 0x02, // USAGE (Mouse)
213 0xa1, 0x01, // COLLECTION (Application)
214 //0x85, REPORT_ID_MOUSE, // REPORT_ID (1)
215 0x09, 0x01, // USAGE (Pointer)
216 0xa1, 0x00, // COLLECTION (Physical)
217 // ---------------------------- Buttons
218 0x05, 0x09, // USAGE_PAGE (Button)
219 0x19, 0x01, // USAGE_MINIMUM (Button 1)
220 0x29, 0x05, // USAGE_MAXIMUM (Button 5)
221 0x15, 0x00, // LOGICAL_MINIMUM (0)
222 0x25, 0x01, // LOGICAL_MAXIMUM (1)
223 0x75, 0x01, // REPORT_SIZE (1)
224 0x95, 0x05, // REPORT_COUNT (5)
225 0x81, 0x02, // INPUT (Data,Var,Abs)
226 0x75, 0x03, // REPORT_SIZE (3)
227 0x95, 0x01, // REPORT_COUNT (1)
228 0x81, 0x03, // INPUT (Cnst,Var,Abs)
229 // ---------------------------- X,Y position
230 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
231 0x09, 0x30, // USAGE (X)
232 0x09, 0x31, // USAGE (Y)
233 0x15, 0x81, // LOGICAL_MINIMUM (-127)
234 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
235 0x75, 0x08, // REPORT_SIZE (8)
236 0x95, 0x02, // REPORT_COUNT (2)
237 0x81, 0x06, // INPUT (Data,Var,Rel)
238 // ---------------------------- Vertical wheel
239 0x09, 0x38, // USAGE (Wheel)
240 0x15, 0x81, // LOGICAL_MINIMUM (-127)
241 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
242 0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical
243 0x45, 0x00, // PHYSICAL_MAXIMUM (0)
244 0x75, 0x08, // REPORT_SIZE (8)
245 0x95, 0x01, // REPORT_COUNT (1)
246 0x81, 0x06, // INPUT (Data,Var,Rel)
247 // ---------------------------- Horizontal wheel
248 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
249 0x0a, 0x38, 0x02, // USAGE (AC Pan)
250 0x15, 0x81, // LOGICAL_MINIMUM (-127)
251 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
252 0x75, 0x08, // REPORT_SIZE (8)
253 0x95, 0x01, // REPORT_COUNT (1)
254 0x81, 0x06, // INPUT (Data,Var,Rel)
255 0xc0, // END_COLLECTION
256 0xc0, // END_COLLECTION
257};
258/* wrapper */
259static const USBDescriptor mouse_hid_report_descriptor = {
260 sizeof mouse_hid_report_desc_data,
261 mouse_hid_report_desc_data
262};
263#endif /* MOUSE_ENABLE */
264
265#ifdef CONSOLE_ENABLE
266static const uint8_t console_hid_report_desc_data[] = {
267 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
268 0x09, 0x74, // Usage 0x74
269 0xA1, 0x53, // Collection 0x53
270 0x75, 0x08, // report size = 8 bits
271 0x15, 0x00, // logical minimum = 0
272 0x26, 0xFF, 0x00, // logical maximum = 255
273 0x95, CONSOLE_EPSIZE, // report count
274 0x09, 0x75, // usage
275 0x81, 0x02, // Input (array)
276 0xC0 // end collection
277};
278/* wrapper */
279static const USBDescriptor console_hid_report_descriptor = {
280 sizeof console_hid_report_desc_data,
281 console_hid_report_desc_data
282};
283#endif /* CONSOLE_ENABLE */
284
285#ifdef EXTRAKEY_ENABLE
286/* audio controls & system controls
287 * http://www.microsoft.com/whdc/archive/w2kbd.mspx */
288static const uint8_t extra_hid_report_desc_data[] = {
289 /* system control */
290 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
291 0x09, 0x80, // USAGE (System Control)
292 0xa1, 0x01, // COLLECTION (Application)
293 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2)
294 0x15, 0x01, // LOGICAL_MINIMUM (0x1)
295 0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7)
296 0x19, 0x01, // USAGE_MINIMUM (0x1)
297 0x29, 0xb7, // USAGE_MAXIMUM (0xb7)
298 0x75, 0x10, // REPORT_SIZE (16)
299 0x95, 0x01, // REPORT_COUNT (1)
300 0x81, 0x00, // INPUT (Data,Array,Abs)
301 0xc0, // END_COLLECTION
302 /* consumer */
303 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
304 0x09, 0x01, // USAGE (Consumer Control)
305 0xa1, 0x01, // COLLECTION (Application)
306 0x85, REPORT_ID_CONSUMER, // REPORT_ID (3)
307 0x15, 0x01, // LOGICAL_MINIMUM (0x1)
308 0x26, 0x9c, 0x02, // LOGICAL_MAXIMUM (0x29c)
309 0x19, 0x01, // USAGE_MINIMUM (0x1)
310 0x2a, 0x9c, 0x02, // USAGE_MAXIMUM (0x29c)
311 0x75, 0x10, // REPORT_SIZE (16)
312 0x95, 0x01, // REPORT_COUNT (1)
313 0x81, 0x00, // INPUT (Data,Array,Abs)
314 0xc0, // END_COLLECTION
315};
316/* wrapper */
317static const USBDescriptor extra_hid_report_descriptor = {
318 sizeof extra_hid_report_desc_data,
319 extra_hid_report_desc_data
320};
321#endif /* EXTRAKEY_ENABLE */
322
323
324/*
325 * Configuration Descriptor tree for a HID device
326 *
327 * The HID Specifications version 1.11 require the following order:
328 * - Configuration Descriptor
329 * - Interface Descriptor
330 * - HID Descriptor
331 * - Endpoints Descriptors
332 */
333#define KBD_HID_DESC_NUM 0
334#define KBD_HID_DESC_OFFSET (9 + (9 + 9 + 7) * KBD_HID_DESC_NUM + 9)
335
336#ifdef MOUSE_ENABLE
337# define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 1)
338# define MOUSE_HID_DESC_OFFSET (9 + (9 + 9 + 7) * MOUSE_HID_DESC_NUM + 9)
339#else /* MOUSE_ENABLE */
340# define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 0)
341#endif /* MOUSE_ENABLE */
342
343#ifdef CONSOLE_ENABLE
344#define CONSOLE_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 1)
345#define CONSOLE_HID_DESC_OFFSET (9 + (9 + 9 + 7) * CONSOLE_HID_DESC_NUM + 9)
346#else /* CONSOLE_ENABLE */
347# define CONSOLE_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 0)
348#endif /* CONSOLE_ENABLE */
349
350#ifdef EXTRAKEY_ENABLE
351# define EXTRA_HID_DESC_NUM (CONSOLE_HID_DESC_NUM + 1)
352# define EXTRA_HID_DESC_OFFSET (9 + (9 + 9 + 7) * EXTRA_HID_DESC_NUM + 9)
353#else /* EXTRAKEY_ENABLE */
354# define EXTRA_HID_DESC_NUM (CONSOLE_HID_DESC_NUM + 0)
355#endif /* EXTRAKEY_ENABLE */
356
357#ifdef NKRO_ENABLE
358# define NKRO_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 1)
359# define NKRO_HID_DESC_OFFSET (9 + (9 + 9 + 7) * EXTRA_HID_DESC_NUM + 9)
360#else /* NKRO_ENABLE */
361# define NKRO_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 0)
362#endif /* NKRO_ENABLE */
363
364#define NUM_INTERFACES (NKRO_HID_DESC_NUM + 1)
365#define CONFIG1_DESC_SIZE (9 + (9 + 9 + 7) * NUM_INTERFACES)
366
367static const uint8_t hid_configuration_descriptor_data[] = {
368 /* Configuration Descriptor (9 bytes) USB spec 9.6.3, page 264-266, Table 9-10 */
369 USB_DESC_CONFIGURATION(CONFIG1_DESC_SIZE, // wTotalLength
370 NUM_INTERFACES, // bNumInterfaces
371 1, // bConfigurationValue
372 0, // iConfiguration
373 0xA0, // bmAttributes (RESERVED|REMOTEWAKEUP)
374 50), // bMaxPower (50mA)
375
376 /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
377 USB_DESC_INTERFACE(KBD_INTERFACE, // bInterfaceNumber
378 0, // bAlternateSetting
379 1, // bNumEndpoints
380 0x03, // bInterfaceClass: HID
381 0x01, // bInterfaceSubClass: Boot
382 0x01, // bInterfaceProtocol: Keyboard
383 0), // iInterface
384
385 /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
386 USB_DESC_BYTE(9), // bLength
387 USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
388 USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
389 USB_DESC_BYTE(0), // bCountryCode
390 USB_DESC_BYTE(1), // bNumDescriptors
391 USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
392 USB_DESC_WORD(sizeof(keyboard_hid_report_desc_data)), // wDescriptorLength
393
394 /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
395 USB_DESC_ENDPOINT(KBD_ENDPOINT | 0x80, // bEndpointAddress
396 0x03, // bmAttributes (Interrupt)
397 KBD_EPSIZE,// wMaxPacketSize
398 10), // bInterval
399
400 #ifdef MOUSE_ENABLE
401 /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
402 USB_DESC_INTERFACE(MOUSE_INTERFACE, // bInterfaceNumber
403 0, // bAlternateSetting
404 1, // bNumEndpoints
405 0x03, // bInterfaceClass (0x03 = HID)
406 // ThinkPad T23 BIOS doesn't work with boot mouse.
407 0x00, // bInterfaceSubClass (0x01 = Boot)
408 0x00, // bInterfaceProtocol (0x02 = Mouse)
409 /*
410 0x01, // bInterfaceSubClass (0x01 = Boot)
411 0x02, // bInterfaceProtocol (0x02 = Mouse)
412 */
413 0), // iInterface
414
415 /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
416 USB_DESC_BYTE(9), // bLength
417 USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
418 USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
419 USB_DESC_BYTE(0), // bCountryCode
420 USB_DESC_BYTE(1), // bNumDescriptors
421 USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
422 USB_DESC_WORD(sizeof(mouse_hid_report_desc_data)), // wDescriptorLength
423
424 /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
425 USB_DESC_ENDPOINT(MOUSE_ENDPOINT | 0x80, // bEndpointAddress
426 0x03, // bmAttributes (Interrupt)
427 MOUSE_EPSIZE, // wMaxPacketSize
428 1), // bInterval
429 #endif /* MOUSE_ENABLE */
430
431 #ifdef CONSOLE_ENABLE
432 /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
433 USB_DESC_INTERFACE(CONSOLE_INTERFACE, // bInterfaceNumber
434 0, // bAlternateSetting
435 1, // bNumEndpoints
436 0x03, // bInterfaceClass: HID
437 0x00, // bInterfaceSubClass: None
438 0x00, // bInterfaceProtocol: None
439 0), // iInterface
440
441 /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
442 USB_DESC_BYTE(9), // bLength
443 USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
444 USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
445 USB_DESC_BYTE(0), // bCountryCode
446 USB_DESC_BYTE(1), // bNumDescriptors
447 USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
448 USB_DESC_WORD(sizeof(console_hid_report_desc_data)), // wDescriptorLength
449
450 /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
451 USB_DESC_ENDPOINT(CONSOLE_ENDPOINT | 0x80, // bEndpointAddress
452 0x03, // bmAttributes (Interrupt)
453 CONSOLE_EPSIZE, // wMaxPacketSize
454 1), // bInterval
455 #endif /* CONSOLE_ENABLE */
456
457 #ifdef EXTRAKEY_ENABLE
458 /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
459 USB_DESC_INTERFACE(EXTRA_INTERFACE, // bInterfaceNumber
460 0, // bAlternateSetting
461 1, // bNumEndpoints
462 0x03, // bInterfaceClass: HID
463 0x00, // bInterfaceSubClass: None
464 0x00, // bInterfaceProtocol: None
465 0), // iInterface
466
467 /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
468 USB_DESC_BYTE(9), // bLength
469 USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
470 USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
471 USB_DESC_BYTE(0), // bCountryCode
472 USB_DESC_BYTE(1), // bNumDescriptors
473 USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
474 USB_DESC_WORD(sizeof(extra_hid_report_desc_data)), // wDescriptorLength
475
476 /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
477 USB_DESC_ENDPOINT(EXTRA_ENDPOINT | 0x80, // bEndpointAddress
478 0x03, // bmAttributes (Interrupt)
479 EXTRA_EPSIZE, // wMaxPacketSize
480 10), // bInterval
481 #endif /* EXTRAKEY_ENABLE */
482
483 #ifdef NKRO_ENABLE
484 /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */
485 USB_DESC_INTERFACE(NKRO_INTERFACE, // bInterfaceNumber
486 0, // bAlternateSetting
487 1, // bNumEndpoints
488 0x03, // bInterfaceClass: HID
489 0x00, // bInterfaceSubClass: None
490 0x00, // bInterfaceProtocol: None
491 0), // iInterface
492
493 /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */
494 USB_DESC_BYTE(9), // bLength
495 USB_DESC_BYTE(0x21), // bDescriptorType (HID class)
496 USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11
497 USB_DESC_BYTE(0), // bCountryCode
498 USB_DESC_BYTE(1), // bNumDescriptors
499 USB_DESC_BYTE(0x22), // bDescriptorType (report desc)
500 USB_DESC_WORD(sizeof(nkro_hid_report_desc_data)), // wDescriptorLength
501
502 /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
503 USB_DESC_ENDPOINT(NKRO_ENDPOINT | 0x80, // bEndpointAddress
504 0x03, // bmAttributes (Interrupt)
505 NKRO_EPSIZE, // wMaxPacketSize
506 1), // bInterval
507 #endif /* NKRO_ENABLE */
508};
509
510/* Configuration Descriptor wrapper */
511static const USBDescriptor hid_configuration_descriptor = {
512 sizeof hid_configuration_descriptor_data,
513 hid_configuration_descriptor_data
514};
515
516/* wrappers */
517#define HID_DESCRIPTOR_SIZE 9
518static const USBDescriptor keyboard_hid_descriptor = {
519 HID_DESCRIPTOR_SIZE,
520 &hid_configuration_descriptor_data[KBD_HID_DESC_OFFSET]
521};
522#ifdef MOUSE_ENABLE
523static const USBDescriptor mouse_hid_descriptor = {
524 HID_DESCRIPTOR_SIZE,
525 &hid_configuration_descriptor_data[MOUSE_HID_DESC_OFFSET]
526};
527#endif /* MOUSE_ENABLE */
528#ifdef CONSOLE_ENABLE
529static const USBDescriptor console_hid_descriptor = {
530 HID_DESCRIPTOR_SIZE,
531 &hid_configuration_descriptor_data[CONSOLE_HID_DESC_OFFSET]
532};
533#endif /* CONSOLE_ENABLE */
534#ifdef EXTRAKEY_ENABLE
535static const USBDescriptor extra_hid_descriptor = {
536 HID_DESCRIPTOR_SIZE,
537 &hid_configuration_descriptor_data[EXTRA_HID_DESC_OFFSET]
538};
539#endif /* EXTRAKEY_ENABLE */
540#ifdef NKRO_ENABLE
541static const USBDescriptor nkro_hid_descriptor = {
542 HID_DESCRIPTOR_SIZE,
543 &hid_configuration_descriptor_data[NKRO_HID_DESC_OFFSET]
544};
545#endif /* NKRO_ENABLE */
546
547
548/* U.S. English language identifier */
549static const uint8_t usb_string_langid[] = {
550 USB_DESC_BYTE(4), // bLength
551 USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType
552 USB_DESC_WORD(0x0409) // wLANGID (U.S. English)
553};
554
555/* ugly ugly hack */
556#define PP_NARG(...) \
557 PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
558#define PP_NARG_(...) \
559 PP_ARG_N(__VA_ARGS__)
560#define PP_ARG_N( \
561 _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
562 _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
563 _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
564 _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
565 _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
566 _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
567 _61,_62,_63,N,...) N
568#define PP_RSEQ_N() \
569 63,62,61,60, \
570 59,58,57,56,55,54,53,52,51,50, \
571 49,48,47,46,45,44,43,42,41,40, \
572 39,38,37,36,35,34,33,32,31,30, \
573 29,28,27,26,25,24,23,22,21,20, \
574 19,18,17,16,15,14,13,12,11,10, \
575 9,8,7,6,5,4,3,2,1,0
576
577/* Vendor string = manufacturer */
578static const uint8_t usb_string_vendor[] = {
579 USB_DESC_BYTE(PP_NARG(USBSTR_MANUFACTURER)+2), // bLength
580 USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType
581 USBSTR_MANUFACTURER
582};
583
584/* Device Description string = product */
585static const uint8_t usb_string_description[] = {
586 USB_DESC_BYTE(PP_NARG(USBSTR_PRODUCT)+2), // bLength
587 USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType
588 USBSTR_PRODUCT
589};
590
591/* Serial Number string (will be filled by the function init_usb_serial_string) */
592static uint8_t usb_string_serial[] = {
593 USB_DESC_BYTE(22), // bLength
594 USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType
595 '0', 0, 'x', 0, 'D', 0, 'E', 0, 'A', 0, 'D', 0, 'B', 0, 'E', 0, 'E', 0, 'F', 0
596};
597
598/* Strings wrappers array */
599static const USBDescriptor usb_strings[] = {
600 { sizeof usb_string_langid, usb_string_langid }
601 ,
602 { sizeof usb_string_vendor, usb_string_vendor }
603 ,
604 { sizeof usb_string_description, usb_string_description }
605 ,
606 { sizeof usb_string_serial, usb_string_serial }
607};
608
609/* 80/*
610 * Handles the GET_DESCRIPTOR callback 81 * Handles the GET_DESCRIPTOR callback
611 * 82 *
612 * Returns the proper descriptor 83 * Returns the proper descriptor
613 */ 84 */
614static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t lang) { 85static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t wIndex) {
615 (void)usbp; 86 (void)usbp;
616 (void)lang; 87 static USBDescriptor desc;
617 switch(dtype) { 88 uint16_t wValue = ((uint16_t)dtype << 8) | dindex;
618 /* Generic descriptors */ 89 desc.ud_string = NULL;
619 case USB_DESCRIPTOR_DEVICE: /* Device Descriptor */ 90 desc.ud_size = get_usb_descriptor(wValue, wIndex, (const void** const)&desc.ud_string);
620 return &usb_device_descriptor; 91 if (desc.ud_string == NULL)
621 92 return NULL;
622 case USB_DESCRIPTOR_CONFIGURATION: /* Configuration Descriptor */ 93 else
623 return &hid_configuration_descriptor; 94 return &desc;
624
625 case USB_DESCRIPTOR_STRING: /* Strings */
626 if(dindex < 4)
627 return &usb_strings[dindex];
628 break;
629
630 /* HID specific descriptors */
631 case USB_DESCRIPTOR_HID: /* HID Descriptors */
632 switch(lang) { /* yea, poor label, it's actually wIndex from the setup packet */
633 case KBD_INTERFACE:
634 return &keyboard_hid_descriptor;
635
636#ifdef MOUSE_ENABLE
637 case MOUSE_INTERFACE:
638 return &mouse_hid_descriptor;
639#endif /* MOUSE_ENABLE */
640#ifdef CONSOLE_ENABLE
641 case CONSOLE_INTERFACE:
642 return &console_hid_descriptor;
643#endif /* CONSOLE_ENABLE */
644#ifdef EXTRAKEY_ENABLE
645 case EXTRA_INTERFACE:
646 return &extra_hid_descriptor;
647#endif /* EXTRAKEY_ENABLE */
648#ifdef NKRO_ENABLE
649 case NKRO_INTERFACE:
650 return &nkro_hid_descriptor;
651#endif /* NKRO_ENABLE */
652 }
653
654 case USB_DESCRIPTOR_HID_REPORT: /* HID Report Descriptor */
655 switch(lang) {
656 case KBD_INTERFACE:
657 return &keyboard_hid_report_descriptor;
658
659#ifdef MOUSE_ENABLE
660 case MOUSE_INTERFACE:
661 return &mouse_hid_report_descriptor;
662#endif /* MOUSE_ENABLE */
663#ifdef CONSOLE_ENABLE
664 case CONSOLE_INTERFACE:
665 return &console_hid_report_descriptor;
666#endif /* CONSOLE_ENABLE */
667#ifdef EXTRAKEY_ENABLE
668 case EXTRA_INTERFACE:
669 return &extra_hid_report_descriptor;
670#endif /* EXTRAKEY_ENABLE */
671#ifdef NKRO_ENABLE
672 case NKRO_INTERFACE:
673 return &nkro_hid_report_descriptor;
674#endif /* NKRO_ENABLE */
675 }
676 }
677 return NULL;
678} 95}
679 96
680/* keyboard endpoint state structure */ 97/* keyboard endpoint state structure */
@@ -685,7 +102,7 @@ static const USBEndpointConfig kbd_ep_config = {
685 NULL, /* SETUP packet notification callback */ 102 NULL, /* SETUP packet notification callback */
686 kbd_in_cb, /* IN notification callback */ 103 kbd_in_cb, /* IN notification callback */
687 NULL, /* OUT notification callback */ 104 NULL, /* OUT notification callback */
688 KBD_EPSIZE, /* IN maximum packet size */ 105 KEYBOARD_EPSIZE, /* IN maximum packet size */
689 0, /* OUT maximum packet size */ 106 0, /* OUT maximum packet size */
690 &kbd_ep_state, /* IN Endpoint state */ 107 &kbd_ep_state, /* IN Endpoint state */
691 NULL, /* OUT endpoint state */ 108 NULL, /* OUT endpoint state */
@@ -712,25 +129,6 @@ static const USBEndpointConfig mouse_ep_config = {
712}; 129};
713#endif /* MOUSE_ENABLE */ 130#endif /* MOUSE_ENABLE */
714 131
715#ifdef CONSOLE_ENABLE
716/* console endpoint state structure */
717static USBInEndpointState console_ep_state;
718
719/* console endpoint initialization structure (IN) */
720static const USBEndpointConfig console_ep_config = {
721 USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
722 NULL, /* SETUP packet notification callback */
723 console_in_cb, /* IN notification callback */
724 NULL, /* OUT notification callback */
725 CONSOLE_EPSIZE, /* IN maximum packet size */
726 0, /* OUT maximum packet size */
727 &console_ep_state, /* IN Endpoint state */
728 NULL, /* OUT endpoint state */
729 2, /* IN multiplier */
730 NULL /* SETUP buffer (not a SETUP endpoint) */
731};
732#endif /* CONSOLE_ENABLE */
733
734#ifdef EXTRAKEY_ENABLE 132#ifdef EXTRAKEY_ENABLE
735/* extrakey endpoint state structure */ 133/* extrakey endpoint state structure */
736static USBInEndpointState extra_ep_state; 134static USBInEndpointState extra_ep_state;
@@ -741,7 +139,7 @@ static const USBEndpointConfig extra_ep_config = {
741 NULL, /* SETUP packet notification callback */ 139 NULL, /* SETUP packet notification callback */
742 extra_in_cb, /* IN notification callback */ 140 extra_in_cb, /* IN notification callback */
743 NULL, /* OUT notification callback */ 141 NULL, /* OUT notification callback */
744 EXTRA_EPSIZE, /* IN maximum packet size */ 142 EXTRAKEY_EPSIZE, /* IN maximum packet size */
745 0, /* OUT maximum packet size */ 143 0, /* OUT maximum packet size */
746 &extra_ep_state, /* IN Endpoint state */ 144 &extra_ep_state, /* IN Endpoint state */
747 NULL, /* OUT endpoint state */ 145 NULL, /* OUT endpoint state */
@@ -769,6 +167,129 @@ static const USBEndpointConfig nkro_ep_config = {
769}; 167};
770#endif /* NKRO_ENABLE */ 168#endif /* NKRO_ENABLE */
771 169
170typedef struct {
171 size_t queue_capacity_in;
172 size_t queue_capacity_out;
173 uint8_t* queue_buffer_in;
174 uint8_t* queue_buffer_out;
175 USBInEndpointState in_ep_state;
176 USBOutEndpointState out_ep_state;
177 USBInEndpointState int_ep_state;
178 USBEndpointConfig in_ep_config;
179 USBEndpointConfig out_ep_config;
180 USBEndpointConfig int_ep_config;
181 const SerialUSBConfig config;
182 SerialUSBDriver driver;
183} stream_driver_t;
184
185#define STREAM_DRIVER(stream, notification) { \
186 .queue_capacity_in = stream##_IN_CAPACITY, \
187 .queue_capacity_out = stream##_OUT_CAPACITY, \
188 .queue_buffer_in = (uint8_t[BQ_BUFFER_SIZE(stream##_IN_CAPACITY, stream##_EPSIZE)]) {}, \
189 .queue_buffer_out = (uint8_t[BQ_BUFFER_SIZE(stream##_OUT_CAPACITY,stream##_EPSIZE)]) {}, \
190 .in_ep_config = { \
191 .ep_mode = stream##_IN_MODE, \
192 .setup_cb = NULL, \
193 .in_cb = sduDataTransmitted, \
194 .out_cb = NULL, \
195 .in_maxsize = stream##_EPSIZE, \
196 .out_maxsize = 0, \
197 /* The pointer to the states will be filled during initialization */ \
198 .in_state = NULL, \
199 .out_state = NULL, \
200 .ep_buffers = 2, \
201 .setup_buf = NULL \
202 }, \
203 .out_ep_config = { \
204 .ep_mode = stream##_OUT_MODE, \
205 .setup_cb = NULL, \
206 .in_cb = NULL, \
207 .out_cb = sduDataReceived, \
208 .in_maxsize = 0, \
209 .out_maxsize = stream##_EPSIZE, \
210 /* The pointer to the states will be filled during initialization */ \
211 .in_state = NULL, \
212 .out_state = NULL, \
213 .ep_buffers = 2, \
214 .setup_buf = NULL, \
215 }, \
216 .int_ep_config = { \
217 .ep_mode = USB_EP_MODE_TYPE_INTR, \
218 .setup_cb = NULL, \
219 .in_cb = sduInterruptTransmitted, \
220 .out_cb = NULL, \
221 .in_maxsize = CDC_NOTIFICATION_EPSIZE, \
222 .out_maxsize = 0, \
223 /* The pointer to the states will be filled during initialization */ \
224 .in_state = NULL, \
225 .out_state = NULL, \
226 .ep_buffers = 2, \
227 .setup_buf = NULL, \
228 }, \
229 .config = { \
230 .usbp = &USB_DRIVER, \
231 .bulk_in = stream##_IN_EPNUM, \
232 .bulk_out = stream##_OUT_EPNUM, \
233 .int_in = notification \
234 } \
235}
236
237typedef struct {
238 union {
239 struct {
240#ifdef CONSOLE_ENABLE
241 stream_driver_t console_driver;
242#endif
243#ifdef RAW_ENABLE
244 stream_driver_t raw_driver;
245#endif
246#ifdef MIDI_ENABLE
247 stream_driver_t midi_driver;
248#endif
249#ifdef VIRTSER_ENABLE
250 stream_driver_t serial_driver;
251#endif
252 };
253 stream_driver_t array[0];
254 };
255} stream_drivers_t;
256
257static stream_drivers_t drivers = {
258#ifdef CONSOLE_ENABLE
259 #define CONSOLE_IN_CAPACITY 4
260 #define CONSOLE_OUT_CAPACITY 4
261 #define CONSOLE_IN_MODE USB_EP_MODE_TYPE_INTR
262 #define CONSOLE_OUT_MODE USB_EP_MODE_TYPE_INTR
263 .console_driver = STREAM_DRIVER(CONSOLE, 0),
264#endif
265#ifdef RAW_ENABLE
266 #define RAW_IN_CAPACITY 4
267 #define RAW_OUT_CAPACITY 4
268 #define RAW_IN_MODE USB_EP_MODE_TYPE_INTR
269 #define RAW_OUT_MODE USB_EP_MODE_TYPE_INTR
270 .raw_driver = STREAM_DRIVER(RAW, 0),
271#endif
272
273#ifdef MIDI_ENABLE
274 #define MIDI_STREAM_IN_CAPACITY 4
275 #define MIDI_STREAM_OUT_CAPACITY 4
276 #define MIDI_STREAM_IN_MODE USB_EP_MODE_TYPE_BULK
277 #define MIDI_STREAM_OUT_MODE USB_EP_MODE_TYPE_BULK
278 .midi_driver = STREAM_DRIVER(MIDI_STREAM, 0),
279#endif
280
281#ifdef VIRTSER_ENABLE
282 #define CDC_IN_CAPACITY 4
283 #define CDC_OUT_CAPACITY 4
284 #define CDC_IN_MODE USB_EP_MODE_TYPE_BULK
285 #define CDC_OUT_MODE USB_EP_MODE_TYPE_BULK
286 .serial_driver = STREAM_DRIVER(CDC, CDC_NOTIFICATION_EPNUM),
287#endif
288};
289
290#define NUM_STREAM_DRIVERS (sizeof(drivers) / sizeof(stream_driver_t))
291
292
772/* --------------------------------------------------------- 293/* ---------------------------------------------------------
773 * USB driver functions 294 * USB driver functions
774 * --------------------------------------------------------- 295 * ---------------------------------------------------------
@@ -784,24 +305,27 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
784 case USB_EVENT_CONFIGURED: 305 case USB_EVENT_CONFIGURED:
785 osalSysLockFromISR(); 306 osalSysLockFromISR();
786 /* Enable the endpoints specified into the configuration. */ 307 /* Enable the endpoints specified into the configuration. */
787 usbInitEndpointI(usbp, KBD_ENDPOINT, &kbd_ep_config); 308 usbInitEndpointI(usbp, KEYBOARD_IN_EPNUM, &kbd_ep_config);
788#ifdef MOUSE_ENABLE 309#ifdef MOUSE_ENABLE
789 usbInitEndpointI(usbp, MOUSE_ENDPOINT, &mouse_ep_config); 310 usbInitEndpointI(usbp, MOUSE_IN_EPNUM, &mouse_ep_config);
790#endif /* MOUSE_ENABLE */ 311#endif /* MOUSE_ENABLE */
791#ifdef CONSOLE_ENABLE
792 usbInitEndpointI(usbp, CONSOLE_ENDPOINT, &console_ep_config);
793 /* don't need to start the flush timer, it starts from console_in_cb automatically */
794#endif /* CONSOLE_ENABLE */
795#ifdef EXTRAKEY_ENABLE 312#ifdef EXTRAKEY_ENABLE
796 usbInitEndpointI(usbp, EXTRA_ENDPOINT, &extra_ep_config); 313 usbInitEndpointI(usbp, EXTRAKEY_IN_EPNUM, &extra_ep_config);
797#endif /* EXTRAKEY_ENABLE */ 314#endif /* EXTRAKEY_ENABLE */
798#ifdef NKRO_ENABLE 315#ifdef NKRO_ENABLE
799 usbInitEndpointI(usbp, NKRO_ENDPOINT, &nkro_ep_config); 316 usbInitEndpointI(usbp, NKRO_IN_EPNUM, &nkro_ep_config);
800#endif /* NKRO_ENABLE */ 317#endif /* NKRO_ENABLE */
318 for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
319 usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].in_ep_config);
320 usbInitEndpointI(usbp, drivers.array[i].config.bulk_out, &drivers.array[i].out_ep_config);
321 if (drivers.array[i].config.int_in) {
322 usbInitEndpointI(usbp, drivers.array[i].config.int_in, &drivers.array[i].int_ep_config);
323 }
324 sduConfigureHookI(&drivers.array[i].driver);
325 }
801 osalSysUnlockFromISR(); 326 osalSysUnlockFromISR();
802 return; 327 return;
803 case USB_EVENT_SUSPEND: 328 case USB_EVENT_SUSPEND:
804 //TODO: from ISR! print("[S]");
805#ifdef SLEEP_LED_ENABLE 329#ifdef SLEEP_LED_ENABLE
806 sleep_led_enable(); 330 sleep_led_enable();
807#endif /* SLEEP_LED_ENABLE */ 331#endif /* SLEEP_LED_ENABLE */
@@ -809,10 +333,22 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
809 case USB_EVENT_UNCONFIGURED: 333 case USB_EVENT_UNCONFIGURED:
810 /* Falls into.*/ 334 /* Falls into.*/
811 case USB_EVENT_RESET: 335 case USB_EVENT_RESET:
336 for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
337 chSysLockFromISR();
338 /* Disconnection event on suspend.*/
339 sduSuspendHookI(&drivers.array[i].driver);
340 chSysUnlockFromISR();
341 }
812 return; 342 return;
813 343
814 case USB_EVENT_WAKEUP: 344 case USB_EVENT_WAKEUP:
815 //TODO: from ISR! print("[W]"); 345 //TODO: from ISR! print("[W]");
346 for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
347 chSysLockFromISR();
348 /* Disconnection event on suspend.*/
349 sduWakeupHookI(&drivers.array[i].driver);
350 chSysUnlockFromISR();
351 }
816 suspend_wakeup_init(); 352 suspend_wakeup_init();
817#ifdef SLEEP_LED_ENABLE 353#ifdef SLEEP_LED_ENABLE
818 sleep_led_disable(); 354 sleep_led_disable();
@@ -868,7 +404,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
868 switch(usbp->setup[1]) { /* bRequest */ 404 switch(usbp->setup[1]) { /* bRequest */
869 case HID_GET_REPORT: 405 case HID_GET_REPORT:
870 switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */ 406 switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */
871 case KBD_INTERFACE: 407 case KEYBOARD_INTERFACE:
872#ifdef NKRO_ENABLE 408#ifdef NKRO_ENABLE
873 case NKRO_INTERFACE: 409 case NKRO_INTERFACE:
874#endif /* NKRO_ENABLE */ 410#endif /* NKRO_ENABLE */
@@ -883,15 +419,8 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
883 break; 419 break;
884#endif /* MOUSE_ENABLE */ 420#endif /* MOUSE_ENABLE */
885 421
886#ifdef CONSOLE_ENABLE
887 case CONSOLE_INTERFACE:
888 usbSetupTransfer(usbp, console_queue_buffer, CONSOLE_EPSIZE, NULL);
889 return TRUE;
890 break;
891#endif /* CONSOLE_ENABLE */
892
893#ifdef EXTRAKEY_ENABLE 422#ifdef EXTRAKEY_ENABLE
894 case EXTRA_INTERFACE: 423 case EXTRAKEY_INTERFACE:
895 if(usbp->setup[3] == 1) { /* MSB(wValue) [Report Type] == 1 [Input Report] */ 424 if(usbp->setup[3] == 1) { /* MSB(wValue) [Report Type] == 1 [Input Report] */
896 switch(usbp->setup[2]) { /* LSB(wValue) [Report ID] */ 425 switch(usbp->setup[2]) { /* LSB(wValue) [Report ID] */
897 case REPORT_ID_SYSTEM: 426 case REPORT_ID_SYSTEM:
@@ -921,7 +450,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
921 break; 450 break;
922 451
923 case HID_GET_PROTOCOL: 452 case HID_GET_PROTOCOL:
924 if((usbp->setup[4] == KBD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */ 453 if((usbp->setup[4] == KEYBOARD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */
925 usbSetupTransfer(usbp, &keyboard_protocol, 1, NULL); 454 usbSetupTransfer(usbp, &keyboard_protocol, 1, NULL);
926 return TRUE; 455 return TRUE;
927 } 456 }
@@ -938,7 +467,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
938 switch(usbp->setup[1]) { /* bRequest */ 467 switch(usbp->setup[1]) { /* bRequest */
939 case HID_SET_REPORT: 468 case HID_SET_REPORT:
940 switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0 and wLength==1?) */ 469 switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0 and wLength==1?) */
941 case KBD_INTERFACE: 470 case KEYBOARD_INTERFACE:
942#ifdef NKRO_ENABLE 471#ifdef NKRO_ENABLE
943 case NKRO_INTERFACE: 472 case NKRO_INTERFACE:
944#endif /* NKRO_ENABLE */ 473#endif /* NKRO_ENABLE */
@@ -951,7 +480,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
951 break; 480 break;
952 481
953 case HID_SET_PROTOCOL: 482 case HID_SET_PROTOCOL:
954 if((usbp->setup[4] == KBD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */ 483 if((usbp->setup[4] == KEYBOARD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */
955 keyboard_protocol = ((usbp->setup[2]) != 0x00); /* LSB(wValue) */ 484 keyboard_protocol = ((usbp->setup[2]) != 0x00); /* LSB(wValue) */
956#ifdef NKRO_ENABLE 485#ifdef NKRO_ENABLE
957 keymap_config.nkro = !!keyboard_protocol; 486 keymap_config.nkro = !!keyboard_protocol;
@@ -998,12 +527,24 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
998 return TRUE; 527 return TRUE;
999 } 528 }
1000 529
530 for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
531 if (drivers.array[i].config.int_in) {
532 // NOTE: Assumes that we only have one serial driver
533 return sduRequestsHook(usbp);
534 }
535 }
536
1001 return FALSE; 537 return FALSE;
1002} 538}
1003 539
1004/* Start-of-frame callback */ 540/* Start-of-frame callback */
1005static void usb_sof_cb(USBDriver *usbp) { 541static void usb_sof_cb(USBDriver *usbp) {
1006 kbd_sof_cb(usbp); 542 kbd_sof_cb(usbp);
543 osalSysLockFromISR();
544 for (int i=0; i<NUM_STREAM_DRIVERS;i++) {
545 sduSOFHookI(&drivers.array[i].driver);
546 }
547 osalSysUnlockFromISR();
1007} 548}
1008 549
1009 550
@@ -1019,6 +560,19 @@ static const USBConfig usbcfg = {
1019 * Initialize the USB driver 560 * Initialize the USB driver
1020 */ 561 */
1021void init_usb_driver(USBDriver *usbp) { 562void init_usb_driver(USBDriver *usbp) {
563 for (int i=0; i<NUM_STREAM_DRIVERS;i++) {
564 SerialUSBDriver* driver = &drivers.array[i].driver;
565 drivers.array[i].in_ep_config.in_state = &drivers.array[i].in_ep_state;
566 drivers.array[i].out_ep_config.out_state = &drivers.array[i].out_ep_state;
567 drivers.array[i].int_ep_config.in_state = &drivers.array[i].int_ep_state;
568 sduObjectInit(driver);
569 bqnotify_t notify = driver->ibqueue.notify;
570 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);
571 notify = driver->obqueue.notify;
572 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);
573 sduStart(driver, &drivers.array[i].config);
574 }
575
1022 /* 576 /*
1023 * Activates the USB driver and then the USB bus pull-up on D+. 577 * Activates the USB driver and then the USB bus pull-up on D+.
1024 * Note, a delay is inserted in order to not have to disconnect the cable 578 * Note, a delay is inserted in order to not have to disconnect the cable
@@ -1030,17 +584,12 @@ void init_usb_driver(USBDriver *usbp) {
1030 usbConnectBus(usbp); 584 usbConnectBus(usbp);
1031 585
1032 chVTObjectInit(&keyboard_idle_timer); 586 chVTObjectInit(&keyboard_idle_timer);
1033#ifdef CONSOLE_ENABLE
1034 obqObjectInit(&console_buf_queue, false, console_queue_buffer, CONSOLE_EPSIZE, CONSOLE_QUEUE_CAPACITY, console_queue_onotify, (void*)usbp);
1035 chVTObjectInit(&console_flush_timer);
1036#endif
1037} 587}
1038 588
1039/* --------------------------------------------------------- 589/* ---------------------------------------------------------
1040 * Keyboard functions 590 * Keyboard functions
1041 * --------------------------------------------------------- 591 * ---------------------------------------------------------
1042 */ 592 */
1043
1044/* keyboard IN callback hander (a kbd report has made it IN) */ 593/* keyboard IN callback hander (a kbd report has made it IN) */
1045void kbd_in_cb(USBDriver *usbp, usbep_t ep) { 594void kbd_in_cb(USBDriver *usbp, usbep_t ep) {
1046 /* STUB */ 595 /* STUB */
@@ -1084,8 +633,8 @@ static void keyboard_idle_timer_cb(void *arg) {
1084 if(keyboard_idle) { 633 if(keyboard_idle) {
1085#endif /* NKRO_ENABLE */ 634#endif /* NKRO_ENABLE */
1086 /* TODO: are we sure we want the KBD_ENDPOINT? */ 635 /* TODO: are we sure we want the KBD_ENDPOINT? */
1087 if(!usbGetTransmitStatusI(usbp, KBD_ENDPOINT)) { 636 if(!usbGetTransmitStatusI(usbp, KEYBOARD_IN_EPNUM)) {
1088 usbStartTransmitI(usbp, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, KBD_EPSIZE); 637 usbStartTransmitI(usbp, KEYBOARD_IN_EPNUM, (uint8_t *)&keyboard_report_sent, KEYBOARD_EPSIZE);
1089 } 638 }
1090 /* rearm the timer */ 639 /* rearm the timer */
1091 chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp); 640 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) {
1119 * this is more efficient */ 668 * this is more efficient */
1120 /* busy wait, should be short and not very common */ 669 /* busy wait, should be short and not very common */
1121 osalSysLock(); 670 osalSysLock();
1122 if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_ENDPOINT)) { 671 if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_IN_EPNUM)) {
1123 /* Need to either suspend, or loop and call unlock/lock during 672 /* Need to either suspend, or loop and call unlock/lock during
1124 * every iteration - otherwise the system will remain locked, 673 * every iteration - otherwise the system will remain locked,
1125 * no interrupts served, so USB not going through as well. 674 * no interrupts served, so USB not going through as well.
1126 * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ 675 * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
1127 osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_ENDPOINT]->in_state->thread); 676 osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_IN_EPNUM]->in_state->thread);
1128 } 677 }
1129 usbStartTransmitI(&USB_DRIVER, NKRO_ENDPOINT, (uint8_t *)report, sizeof(report_keyboard_t)); 678 usbStartTransmitI(&USB_DRIVER, NKRO_IN_EPNUM, (uint8_t *)report, sizeof(report_keyboard_t));
1130 osalSysUnlock(); 679 osalSysUnlock();
1131 } else 680 } else
1132#endif /* NKRO_ENABLE */ 681#endif /* NKRO_ENABLE */
@@ -1134,14 +683,14 @@ void send_keyboard(report_keyboard_t *report) {
1134 /* need to wait until the previous packet has made it through */ 683 /* need to wait until the previous packet has made it through */
1135 /* busy wait, should be short and not very common */ 684 /* busy wait, should be short and not very common */
1136 osalSysLock(); 685 osalSysLock();
1137 if(usbGetTransmitStatusI(&USB_DRIVER, KBD_ENDPOINT)) { 686 if(usbGetTransmitStatusI(&USB_DRIVER, KEYBOARD_IN_EPNUM)) {
1138 /* Need to either suspend, or loop and call unlock/lock during 687 /* Need to either suspend, or loop and call unlock/lock during
1139 * every iteration - otherwise the system will remain locked, 688 * every iteration - otherwise the system will remain locked,
1140 * no interrupts served, so USB not going through as well. 689 * no interrupts served, so USB not going through as well.
1141 * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ 690 * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
1142 osalThreadSuspendS(&(&USB_DRIVER)->epc[KBD_ENDPOINT]->in_state->thread); 691 osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread);
1143 } 692 }
1144 usbStartTransmitI(&USB_DRIVER, KBD_ENDPOINT, (uint8_t *)report, KBD_EPSIZE); 693 usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, (uint8_t *)report, KEYBOARD_EPSIZE);
1145 osalSysUnlock(); 694 osalSysUnlock();
1146 } 695 }
1147 keyboard_report_sent = *report; 696 keyboard_report_sent = *report;
@@ -1174,7 +723,7 @@ void send_mouse(report_mouse_t *report) {
1174 */ 723 */
1175 724
1176 osalSysLock(); 725 osalSysLock();
1177 usbStartTransmitI(&USB_DRIVER, MOUSE_ENDPOINT, (uint8_t *)report, sizeof(report_mouse_t)); 726 usbStartTransmitI(&USB_DRIVER, MOUSE_IN_EPNUM, (uint8_t *)report, sizeof(report_mouse_t));
1178 osalSysUnlock(); 727 osalSysUnlock();
1179} 728}
1180 729
@@ -1210,7 +759,7 @@ static void send_extra_report(uint8_t report_id, uint16_t data) {
1210 .usage = data 759 .usage = data
1211 }; 760 };
1212 761
1213 usbStartTransmitI(&USB_DRIVER, EXTRA_ENDPOINT, (uint8_t *)&report, sizeof(report_extra_t)); 762 usbStartTransmitI(&USB_DRIVER, EXTRAKEY_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t));
1214 osalSysUnlock(); 763 osalSysUnlock();
1215} 764}
1216 765
@@ -1238,125 +787,107 @@ void send_consumer(uint16_t data) {
1238 787
1239#ifdef CONSOLE_ENABLE 788#ifdef CONSOLE_ENABLE
1240 789
1241/* console IN callback hander */ 790int8_t sendchar(uint8_t c) {
1242void console_in_cb(USBDriver *usbp, usbep_t ep) { 791 // The previous implmentation had timeouts, but I think it's better to just slow down
1243 (void)ep; /* should have ep == CONSOLE_ENDPOINT, so use that to save time/space */ 792 // and make sure that everything is transferred, rather than dropping stuff
1244 uint8_t *buf; 793 return chnWrite(&drivers.console_driver.driver, &c, 1);
1245 size_t n; 794}
1246 795
1247 osalSysLockFromISR(); 796// Just a dummy function for now, this could be exposed as a weak function
797// Or connected to the actual QMK console
798static void console_receive( uint8_t *data, uint8_t length ) {
799 (void)data;
800 (void)length;
801}
1248 802
1249 /* rearm the timer */ 803void console_task(void) {
1250 chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp); 804 uint8_t buffer[CONSOLE_EPSIZE];
805 size_t size = 0;
806 do {
807 size_t size = chnReadTimeout(&drivers.console_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
808 if (size > 0) {
809 console_receive(buffer, size);
810 }
811 } while(size > 0);
812}
1251 813
1252 /* Freeing the buffer just transmitted, if it was not a zero size packet.*/ 814#else /* CONSOLE_ENABLE */
1253 if (usbp->epc[CONSOLE_ENDPOINT]->in_state->txsize > 0U) { 815int8_t sendchar(uint8_t c) {
1254 obqReleaseEmptyBufferI(&console_buf_queue); 816 (void)c;
1255 } 817 return 0;
818}
819#endif /* CONSOLE_ENABLE */
1256 820
1257 /* Checking if there is a buffer ready for transmission.*/ 821void sendchar_pf(void *p, char c) {
1258 buf = obqGetFullBufferI(&console_buf_queue, &n); 822 (void)p;
823 sendchar((uint8_t)c);
824}
1259 825
1260 if (buf != NULL) { 826#ifdef RAW_ENABLE
1261 /* The endpoint cannot be busy, we are in the context of the callback, 827void raw_hid_send( uint8_t *data, uint8_t length ) {
1262 so it is safe to transmit without a check.*/ 828 // TODO: implement variable size packet
1263 /* Should have n == CONSOLE_EPSIZE; check it? */ 829 if ( length != RAW_EPSIZE )
1264 usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE); 830 {
1265 } else { 831 return;
1266 /* Nothing to transmit.*/
1267 }
1268 832
1269 osalSysUnlockFromISR(); 833 }
834 chnWrite(&drivers.raw_driver.driver, data, length);
1270} 835}
1271 836
1272/* Callback when data is inserted into the output queue 837__attribute__ ((weak))
1273 * Called from a locked state */ 838void raw_hid_receive( uint8_t *data, uint8_t length ) {
1274void console_queue_onotify(io_buffers_queue_t *bqp) { 839 // Users should #include "raw_hid.h" in their own code
1275 size_t n; 840 // and implement this function there. Leave this as weak linkage
1276 USBDriver *usbp = bqGetLinkX(bqp); 841 // so users can opt to not handle data coming in.
1277 842}
1278 if(usbGetDriverStateI(usbp) != USB_ACTIVE)
1279 return;
1280 843
1281 /* Checking if there is already a transaction ongoing on the endpoint.*/ 844void raw_hid_task(void) {
1282 if (!usbGetTransmitStatusI(usbp, CONSOLE_ENDPOINT)) { 845 uint8_t buffer[RAW_EPSIZE];
1283 /* Trying to get a full buffer.*/ 846 size_t size = 0;
1284 uint8_t *buf = obqGetFullBufferI(&console_buf_queue, &n); 847 do {
1285 if (buf != NULL) { 848 size_t size = chnReadTimeout(&drivers.raw_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
1286 /* Buffer found, starting a new transaction.*/ 849 if (size > 0) {
1287 /* Should have n == CONSOLE_EPSIZE; check this? */ 850 raw_hid_receive(buffer, size);
1288 usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE);
1289 } 851 }
1290 } 852 } while(size > 0);
1291} 853}
1292 854
1293/* Flush timer code 855#endif
1294 * callback (called from ISR, unlocked state) */
1295static void console_flush_cb(void *arg) {
1296 USBDriver *usbp = (USBDriver *)arg;
1297 osalSysLockFromISR();
1298 856
1299 /* check that the states of things are as they're supposed to */ 857#ifdef MIDI_ENABLE
1300 if(usbGetDriverStateI(usbp) != USB_ACTIVE) {
1301 /* rearm the timer */
1302 chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
1303 osalSysUnlockFromISR();
1304 return;
1305 }
1306 858
1307 /* If there is already a transaction ongoing then another one cannot be 859void send_midi_packet(MIDI_EventPacket_t* event) {
1308 started.*/ 860 chnWrite(&drivers.midi_driver.driver, (uint8_t*)event, sizeof(MIDI_EventPacket_t));
1309 if (usbGetTransmitStatusI(usbp, CONSOLE_ENDPOINT)) { 861}
1310 /* rearm the timer */
1311 chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
1312 osalSysUnlockFromISR();
1313 return;
1314 }
1315 862
1316 /* Checking if there only a buffer partially filled, if so then it is 863bool recv_midi_packet(MIDI_EventPacket_t* const event) {
1317 enforced in the queue and transmitted.*/ 864 size_t size = chnReadTimeout(&drivers.midi_driver.driver, (uint8_t*)event, sizeof(MIDI_EventPacket_t), TIME_IMMEDIATE);
1318 if(obqTryFlushI(&console_buf_queue)) { 865 return size == sizeof(MIDI_EventPacket_t);
1319 size_t n,i; 866}
1320 uint8_t *buf = obqGetFullBufferI(&console_buf_queue, &n);
1321 867
1322 osalDbgAssert(buf != NULL, "queue is empty"); 868#endif
1323 869
1324 /* zero the rest of the buffer (buf should point to allocated space) */ 870#ifdef VIRTSER_ENABLE
1325 for(i=n; i<CONSOLE_EPSIZE; i++)
1326 buf[i]=0;
1327 usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE);
1328 }
1329 871
1330 /* rearm the timer */ 872void virtser_send(const uint8_t byte) {
1331 chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp); 873 chnWrite(&drivers.serial_driver.driver, &byte, 1);
1332 osalSysUnlockFromISR();
1333} 874}
1334 875
1335 876__attribute__ ((weak))
1336int8_t sendchar(uint8_t c) { 877void virtser_recv(uint8_t c)
1337 osalSysLock(); 878{
1338 if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { 879 // Ignore by default
1339 osalSysUnlock();
1340 return 0;
1341 }
1342 osalSysUnlock();
1343 /* Timeout after 100us if the queue is full.
1344 * Increase this timeout if too much stuff is getting
1345 * dropped (i.e. the buffer is getting full too fast
1346 * for USB/HIDRAW to dequeue). Another possibility
1347 * for fixing this kind of thing is to increase
1348 * CONSOLE_QUEUE_CAPACITY. */
1349 return(obqPutTimeout(&console_buf_queue, c, US2ST(100)));
1350} 880}
1351 881
1352#else /* CONSOLE_ENABLE */ 882void virtser_task(void) {
1353int8_t sendchar(uint8_t c) { 883 uint8_t numBytesReceived = 0;
1354 (void)c; 884 uint8_t buffer[16];
1355 return 0; 885 do {
886 numBytesReceived = chnReadTimeout(&drivers.serial_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE);
887 for (int i=0;i<numBytesReceived;i++) {
888 virtser_recv(buffer[i]);
889 }
890 } while (numBytesReceived > 0);
1356} 891}
1357#endif /* CONSOLE_ENABLE */
1358 892
1359void sendchar_pf(void *p, char c) { 893#endif
1360 (void)p;
1361 sendchar((uint8_t)c);
1362}
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h
index b4f894f2f..1f7eb12f8 100644
--- a/tmk_core/protocol/chibios/usb_main.h
+++ b/tmk_core/protocol/chibios/usb_main.h
@@ -41,20 +41,6 @@ void init_usb_driver(USBDriver *usbp);
41 * --------------- 41 * ---------------
42 */ 42 */
43 43
44/* main keyboard (6kro) */
45#define KBD_INTERFACE 0
46#define KBD_ENDPOINT 1
47#define KBD_EPSIZE 8
48#define KBD_REPORT_KEYS (KBD_EPSIZE - 2)
49
50/* secondary keyboard */
51#ifdef NKRO_ENABLE
52#define NKRO_INTERFACE 4
53#define NKRO_ENDPOINT 5
54#define NKRO_EPSIZE 16
55#define NKRO_REPORT_KEYS (NKRO_EPSIZE - 1)
56#endif
57
58/* extern report_keyboard_t keyboard_report_sent; */ 44/* extern report_keyboard_t keyboard_report_sent; */
59 45
60/* keyboard IN request callback handler */ 46/* keyboard IN request callback handler */
@@ -75,10 +61,6 @@ void nkro_in_cb(USBDriver *usbp, usbep_t ep);
75 61
76#ifdef MOUSE_ENABLE 62#ifdef MOUSE_ENABLE
77 63
78#define MOUSE_INTERFACE 1
79#define MOUSE_ENDPOINT 2
80#define MOUSE_EPSIZE 8
81
82/* mouse IN request callback handler */ 64/* mouse IN request callback handler */
83void mouse_in_cb(USBDriver *usbp, usbep_t ep); 65void mouse_in_cb(USBDriver *usbp, usbep_t ep);
84#endif /* MOUSE_ENABLE */ 66#endif /* MOUSE_ENABLE */
@@ -90,10 +72,6 @@ void mouse_in_cb(USBDriver *usbp, usbep_t ep);
90 72
91#ifdef EXTRAKEY_ENABLE 73#ifdef EXTRAKEY_ENABLE
92 74
93#define EXTRA_INTERFACE 3
94#define EXTRA_ENDPOINT 4
95#define EXTRA_EPSIZE 8
96
97/* extrakey IN request callback handler */ 75/* extrakey IN request callback handler */
98void extra_in_cb(USBDriver *usbp, usbep_t ep); 76void extra_in_cb(USBDriver *usbp, usbep_t ep);
99 77
@@ -111,24 +89,12 @@ typedef struct {
111 89
112#ifdef CONSOLE_ENABLE 90#ifdef CONSOLE_ENABLE
113 91
114#define CONSOLE_INTERFACE 2
115#define CONSOLE_ENDPOINT 3
116#define CONSOLE_EPSIZE 16
117
118/* Number of IN reports that can be stored inside the output queue */
119#define CONSOLE_QUEUE_CAPACITY 4
120
121/* Console flush time */
122#define CONSOLE_FLUSH_MS 50
123
124/* Putchar over the USB console */ 92/* Putchar over the USB console */
125int8_t sendchar(uint8_t c); 93int8_t sendchar(uint8_t c);
126 94
127/* Flush output (send everything immediately) */ 95/* Flush output (send everything immediately) */
128void console_flush_output(void); 96void console_flush_output(void);
129 97
130/* console IN request callback handler */
131void console_in_cb(USBDriver *usbp, usbep_t ep);
132#endif /* CONSOLE_ENABLE */ 98#endif /* CONSOLE_ENABLE */
133 99
134void sendchar_pf(void *p, char c); 100void sendchar_pf(void *p, char c);
diff --git a/tmk_core/protocol/lufa.mk b/tmk_core/protocol/lufa.mk
index 4d005debc..bb82a31e1 100644
--- a/tmk_core/protocol/lufa.mk
+++ b/tmk_core/protocol/lufa.mk
@@ -15,7 +15,7 @@ else
15endif 15endif
16 16
17LUFA_SRC = lufa.c \ 17LUFA_SRC = lufa.c \
18 descriptor.c \ 18 usb_descriptor.c \
19 outputselect.c \ 19 outputselect.c \
20 $(LUFA_SRC_USB) 20 $(LUFA_SRC_USB)
21 21
@@ -64,7 +64,7 @@ LUFA_OPTS = -DUSB_DEVICE_ONLY
64LUFA_OPTS += -DUSE_FLASH_DESCRIPTORS 64LUFA_OPTS += -DUSE_FLASH_DESCRIPTORS
65LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" 65LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
66#LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT 66#LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT
67LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 67LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
68LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 68LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
69LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1 69LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1
70 70
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index e3f8724e8..a1cab98a6 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -49,7 +49,7 @@
49#endif 49#endif
50#include "suspend.h" 50#include "suspend.h"
51 51
52#include "descriptor.h" 52#include "usb_descriptor.h"
53#include "lufa.h" 53#include "lufa.h"
54#include "quantum.h" 54#include "quantum.h"
55#include <util/atomic.h> 55#include <util/atomic.h>
@@ -83,7 +83,7 @@
83#endif 83#endif
84 84
85#ifdef MIDI_ENABLE 85#ifdef MIDI_ENABLE
86 #include "sysex_tools.h" 86 #include "qmk_midi.h"
87#endif 87#endif
88 88
89#ifdef RAW_ENABLE 89#ifdef RAW_ENABLE
@@ -97,12 +97,6 @@ static uint8_t keyboard_led_stats = 0;
97 97
98static report_keyboard_t keyboard_report_sent; 98static report_keyboard_t keyboard_report_sent;
99 99
100#ifdef MIDI_ENABLE
101static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
102static void usb_get_midi(MidiDevice * device);
103static void midi_usb_init(MidiDevice * device);
104#endif
105
106/* Host driver */ 100/* Host driver */
107static uint8_t keyboard_leds(void); 101static uint8_t keyboard_leds(void);
108static void send_keyboard(report_keyboard_t *report); 102static void send_keyboard(report_keyboard_t *report);
@@ -115,48 +109,8 @@ host_driver_t lufa_driver = {
115 send_mouse, 109 send_mouse,
116 send_system, 110 send_system,
117 send_consumer, 111 send_consumer,
118#ifdef MIDI_ENABLE
119 usb_send_func,
120 usb_get_midi,
121 midi_usb_init
122#endif
123};
124
125/*******************************************************************************
126 * MIDI
127 ******************************************************************************/
128
129#ifdef MIDI_ENABLE
130USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
131{
132 .Config =
133 {
134 .StreamingInterfaceNumber = AS_INTERFACE,
135 .DataINEndpoint =
136 {
137 .Address = MIDI_STREAM_IN_EPADDR,
138 .Size = MIDI_STREAM_EPSIZE,
139 .Banks = 1,
140 },
141 .DataOUTEndpoint =
142 {
143 .Address = MIDI_STREAM_OUT_EPADDR,
144 .Size = MIDI_STREAM_EPSIZE,
145 .Banks = 1,
146 },
147 },
148}; 112};
149 113
150#define SYSEX_START_OR_CONT 0x40
151#define SYSEX_ENDS_IN_1 0x50
152#define SYSEX_ENDS_IN_2 0x60
153#define SYSEX_ENDS_IN_3 0x70
154
155#define SYS_COMMON_1 0x50
156#define SYS_COMMON_2 0x20
157#define SYS_COMMON_3 0x30
158#endif
159
160#ifdef VIRTSER_ENABLE 114#ifdef VIRTSER_ENABLE
161USB_ClassInfo_CDC_Device_t cdc_device = 115USB_ClassInfo_CDC_Device_t cdc_device =
162{ 116{
@@ -853,170 +807,32 @@ int8_t sendchar(uint8_t c)
853 ******************************************************************************/ 807 ******************************************************************************/
854 808
855#ifdef MIDI_ENABLE 809#ifdef MIDI_ENABLE
856static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { 810USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
857 MIDI_EventPacket_t event;
858 event.Data1 = byte0;
859 event.Data2 = byte1;
860 event.Data3 = byte2;
861
862 uint8_t cable = 0;
863
864// Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
865
866 //if the length is undefined we assume it is a SYSEX message
867 if (midi_packet_length(byte0) == UNDEFINED) {
868 switch(cnt) {
869 case 3:
870 if (byte2 == SYSEX_END)
871 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
872 else
873 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
874 break;
875 case 2:
876 if (byte1 == SYSEX_END)
877 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
878 else
879 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
880 break;
881 case 1:
882 if (byte0 == SYSEX_END)
883 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
884 else
885 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
886 break;
887 default:
888 return; //invalid cnt
889 }
890 } else {
891 //deal with 'system common' messages
892 //TODO are there any more?
893 switch(byte0 & 0xF0){
894 case MIDI_SONGPOSITION:
895 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
896 break;
897 case MIDI_SONGSELECT:
898 case MIDI_TC_QUARTERFRAME:
899 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
900 break;
901 default:
902 event.Event = MIDI_EVENT(cable, byte0);
903 break;
904 }
905 }
906
907// Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
908// Endpoint_ClearIN();
909
910 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
911 MIDI_Device_Flush(&USB_MIDI_Interface);
912 MIDI_Device_USBTask(&USB_MIDI_Interface);
913 USB_USBTask();
914}
915
916static void usb_get_midi(MidiDevice * device) {
917 MIDI_EventPacket_t event;
918 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
919
920 midi_packet_length_t length = midi_packet_length(event.Data1);
921 uint8_t input[3];
922 input[0] = event.Data1;
923 input[1] = event.Data2;
924 input[2] = event.Data3;
925 if (length == UNDEFINED) {
926 //sysex
927 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
928 length = 3;
929 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
930 length = 2;
931 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
932 length = 1;
933 } else {
934 //XXX what to do?
935 }
936 }
937
938 //pass the data to the device input function
939 if (length != UNDEFINED)
940 midi_device_input(device, length, input);
941 }
942 MIDI_Device_USBTask(&USB_MIDI_Interface);
943 USB_USBTask();
944}
945
946static void midi_usb_init(MidiDevice * device){
947 midi_device_init(device);
948 midi_device_set_send_func(device, usb_send_func);
949 midi_device_set_pre_input_process_func(device, usb_get_midi);
950
951 // SetupHardware();
952 sei();
953}
954
955void MIDI_Task(void)
956{ 811{
957 812 .Config =
958 /* Device must be connected and configured for the task to run */ 813 {
959 dprint("in MIDI_TASK\n"); 814 .StreamingInterfaceNumber = AS_INTERFACE,
960 if (USB_DeviceState != DEVICE_STATE_Configured) 815 .DataINEndpoint =
961 return;
962 dprint("continuing in MIDI_TASK\n");
963
964 Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
965
966 if (Endpoint_IsINReady())
967 { 816 {
968 817 .Address = MIDI_STREAM_IN_EPADDR,
969 dprint("Endpoint is ready\n"); 818 .Size = MIDI_STREAM_EPSIZE,
970 819 .Banks = 1,
971 uint8_t MIDICommand = 0; 820 },
972 uint8_t MIDIPitch; 821 .DataOUTEndpoint =
973
974 /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
975 uint8_t Channel = MIDI_CHANNEL(1);
976
977 MIDICommand = MIDI_COMMAND_NOTE_ON;
978 MIDIPitch = 0x3E;
979
980 /* Check if a MIDI command is to be sent */
981 if (MIDICommand)
982 {
983 dprint("Command exists\n");
984 MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
985 {
986 .Event = MIDI_EVENT(0, MIDICommand),
987
988 .Data1 = MIDICommand | Channel,
989 .Data2 = MIDIPitch,
990 .Data3 = MIDI_STANDARD_VELOCITY,
991 };
992
993 /* Write the MIDI event packet to the endpoint */
994 Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
995
996 /* Send the data in the endpoint to the host */
997 Endpoint_ClearIN();
998 }
999 }
1000
1001
1002 /* Select the MIDI OUT stream */
1003 Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
1004
1005 /* Check if a MIDI command has been received */
1006 if (Endpoint_IsOUTReceived())
1007 { 822 {
1008 MIDI_EventPacket_t MIDIEvent; 823 .Address = MIDI_STREAM_OUT_EPADDR,
824 .Size = MIDI_STREAM_EPSIZE,
825 .Banks = 1,
826 },
827 },
828};
1009 829
1010 /* Read the MIDI event packet from the endpoint */ 830void send_midi_packet(MIDI_EventPacket_t* event) {
1011 Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL); 831 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event);
832}
1012 833
1013 /* If the endpoint is now empty, clear the bank */ 834bool recv_midi_packet(MIDI_EventPacket_t* const event) {
1014 if (!(Endpoint_BytesInEndpoint())) 835 return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event);
1015 {
1016 /* Clear the endpoint ready for new packet */
1017 Endpoint_ClearOUT();
1018 }
1019 }
1020} 836}
1021 837
1022#endif 838#endif
@@ -1105,26 +921,6 @@ static void setup_usb(void)
1105 print_set_sendchar(sendchar); 921 print_set_sendchar(sendchar);
1106} 922}
1107 923
1108
1109#ifdef MIDI_ENABLE
1110void fallthrough_callback(MidiDevice * device,
1111 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
1112void cc_callback(MidiDevice * device,
1113 uint8_t chan, uint8_t num, uint8_t val);
1114void sysex_callback(MidiDevice * device,
1115 uint16_t start, uint8_t length, uint8_t * data);
1116
1117void setup_midi(void)
1118{
1119#ifdef MIDI_ADVANCED
1120 midi_init();
1121#endif
1122 midi_device_init(&midi_device);
1123 midi_device_set_send_func(&midi_device, usb_send_func);
1124 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
1125}
1126#endif
1127
1128int main(void) __attribute__ ((weak)); 924int main(void) __attribute__ ((weak));
1129int main(void) 925int main(void)
1130{ 926{
@@ -1137,18 +933,6 @@ int main(void)
1137 setup_usb(); 933 setup_usb();
1138 sei(); 934 sei();
1139 935
1140#ifdef MIDI_ENABLE
1141 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
1142 midi_register_cc_callback(&midi_device, cc_callback);
1143 midi_register_sysex_callback(&midi_device, sysex_callback);
1144
1145 // init_notes();
1146 // midi_send_cc(&midi_device, 0, 1, 2);
1147 // midi_send_cc(&midi_device, 15, 1, 0);
1148 // midi_send_noteon(&midi_device, 0, 64, 127);
1149 // midi_send_noteoff(&midi_device, 0, 64, 127);
1150#endif
1151
1152#if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42) 936#if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
1153 serial_init(); 937 serial_init();
1154#endif 938#endif
@@ -1193,10 +977,7 @@ int main(void)
1193 keyboard_task(); 977 keyboard_task();
1194 978
1195#ifdef MIDI_ENABLE 979#ifdef MIDI_ENABLE
1196 midi_device_process(&midi_device); 980 MIDI_Device_USBTask(&USB_MIDI_Interface);
1197#ifdef MIDI_ADVANCED
1198 midi_task();
1199#endif
1200#endif 981#endif
1201 982
1202#if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE) 983#if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
@@ -1223,71 +1004,10 @@ int main(void)
1223 } 1004 }
1224} 1005}
1225 1006
1226#ifdef MIDI_ENABLE 1007uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
1227void fallthrough_callback(MidiDevice * device, 1008 const uint16_t wIndex,
1228 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){ 1009 const void** const DescriptorAddress)
1229 1010{
1230#ifdef AUDIO_ENABLE 1011 return get_usb_descriptor(wValue, wIndex, DescriptorAddress);
1231 if (cnt == 3) {
1232 switch (byte0 & 0xF0) {
1233 case MIDI_NOTEON:
1234 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
1235 break;
1236 case MIDI_NOTEOFF:
1237 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
1238 break;
1239 }
1240 }
1241 if (byte0 == MIDI_STOP) {
1242 stop_all_notes();
1243 }
1244#endif
1245}
1246
1247
1248void cc_callback(MidiDevice * device,
1249 uint8_t chan, uint8_t num, uint8_t val) {
1250 //sending it back on the next channel
1251 // midi_send_cc(device, (chan + 1) % 16, num, val);
1252}
1253
1254#ifdef API_SYSEX_ENABLE
1255uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
1256#endif
1257
1258void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
1259 #ifdef API_SYSEX_ENABLE
1260 // SEND_STRING("\n");
1261 // send_word(start);
1262 // SEND_STRING(": ");
1263 // Don't store the header
1264 int16_t pos = start - 4;
1265 for (uint8_t place = 0; place < length; place++) {
1266 // send_byte(*data);
1267 if (pos >= 0) {
1268 if (*data == 0xF7) {
1269 // SEND_STRING("\nRD: ");
1270 // for (uint8_t i = 0; i < start + place + 1; i++){
1271 // send_byte(midi_buffer[i]);
1272 // SEND_STRING(" ");
1273 // }
1274 const unsigned decoded_length = sysex_decoded_length(pos);
1275 uint8_t decoded[API_SYSEX_MAX_SIZE];
1276 sysex_decode(decoded, midi_buffer, pos);
1277 process_api(decoded_length, decoded);
1278 return;
1279 }
1280 else if (pos >= MIDI_SYSEX_BUFFER) {
1281 return;
1282 }
1283 midi_buffer[pos] = *data;
1284 }
1285 // SEND_STRING(" ");
1286 data++;
1287 pos++;
1288 }
1289 #endif
1290} 1012}
1291 1013
1292
1293#endif
diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h
index a51573786..7364cdf7c 100644
--- a/tmk_core/protocol/lufa/lufa.h
+++ b/tmk_core/protocol/lufa/lufa.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright 2012 Jun Wako <wakojun@gmail.com> 2 * Copyright 2012 Jun Wako <wakojun@gmail.com>
3 * This file is based on: 3 * This file is based on:
4 * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse 4 * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
@@ -48,9 +48,6 @@
48#include <LUFA/Version.h> 48#include <LUFA/Version.h>
49#include <LUFA/Drivers/USB/USB.h> 49#include <LUFA/Drivers/USB/USB.h>
50#include "host.h" 50#include "host.h"
51#ifdef MIDI_ENABLE
52 #include "process_midi.h"
53#endif
54#ifdef __cplusplus 51#ifdef __cplusplus
55extern "C" { 52extern "C" {
56#endif 53#endif
@@ -67,11 +64,6 @@ typedef struct {
67 uint16_t usage; 64 uint16_t usage;
68} __attribute__ ((packed)) report_extra_t; 65} __attribute__ ((packed)) report_extra_t;
69 66
70#ifdef MIDI_ENABLE
71 void MIDI_Task(void);
72 MidiDevice midi_device;
73#endif
74
75#ifdef API_ENABLE 67#ifdef API_ENABLE
76 #include "api.h" 68 #include "api.h"
77#endif 69#endif
diff --git a/tmk_core/protocol/midi.mk b/tmk_core/protocol/midi.mk
index 4855b23d3..a5f76b2d3 100644
--- a/tmk_core/protocol/midi.mk
+++ b/tmk_core/protocol/midi.mk
@@ -5,6 +5,7 @@ SRC += midi.c \
5 bytequeue/bytequeue.c \ 5 bytequeue/bytequeue.c \
6 bytequeue/interrupt_setting.c \ 6 bytequeue/interrupt_setting.c \
7 sysex_tools.c \ 7 sysex_tools.c \
8 qmk_midi.c \
8 $(LUFA_SRC_USBCLASS) 9 $(LUFA_SRC_USBCLASS)
9 10
10VPATH += $(TMK_PATH)/$(MIDI_DIR) \ No newline at end of file 11VPATH += $(TMK_PATH)/$(MIDI_DIR)
diff --git a/tmk_core/protocol/midi/bytequeue/interrupt_setting.c b/tmk_core/protocol/midi/bytequeue/interrupt_setting.c
index eafef527c..0ab8b5462 100755
--- a/tmk_core/protocol/midi/bytequeue/interrupt_setting.c
+++ b/tmk_core/protocol/midi/bytequeue/interrupt_setting.c
@@ -1,5 +1,5 @@
1//Copyright 20010 Alex Norman 1//Copyright 20010 Alex Norman
2//writen by Alex Norman 2//writen by Alex Norman
3// 3//
4//This file is part of avr-bytequeue. 4//This file is part of avr-bytequeue.
5// 5//
@@ -22,6 +22,7 @@
22//implementations of the typedef and these functions 22//implementations of the typedef and these functions
23 23
24#include "interrupt_setting.h" 24#include "interrupt_setting.h"
25#if defined(__AVR__)
25#include <avr/interrupt.h> 26#include <avr/interrupt.h>
26 27
27interrupt_setting_t store_and_clear_interrupt(void) { 28interrupt_setting_t store_and_clear_interrupt(void) {
@@ -33,4 +34,16 @@ interrupt_setting_t store_and_clear_interrupt(void) {
33void restore_interrupt_setting(interrupt_setting_t setting) { 34void restore_interrupt_setting(interrupt_setting_t setting) {
34 SREG = setting; 35 SREG = setting;
35} 36}
37#elif defined(__arm__)
38#include "ch.h"
39
40interrupt_setting_t store_and_clear_interrupt(void) {
41 chSysLock();
42 return 0;
43}
44
45void restore_interrupt_setting(interrupt_setting_t setting) {
46 chSysUnlock();
47}
48#endif
36 49
diff --git a/tmk_core/protocol/midi/qmk_midi.c b/tmk_core/protocol/midi/qmk_midi.c
new file mode 100644
index 000000000..d4de6caa7
--- /dev/null
+++ b/tmk_core/protocol/midi/qmk_midi.c
@@ -0,0 +1,184 @@
1#include <LUFA/Drivers/USB/USB.h>
2#include "qmk_midi.h"
3#include "sysex_tools.h"
4#include "midi.h"
5#include "usb_descriptor.h"
6#include "process_midi.h"
7#if API_SYSEX_ENABLE
8#include "api.h"
9#endif
10
11/*******************************************************************************
12 * MIDI
13 ******************************************************************************/
14
15MidiDevice midi_device;
16
17#define SYSEX_START_OR_CONT 0x40
18#define SYSEX_ENDS_IN_1 0x50
19#define SYSEX_ENDS_IN_2 0x60
20#define SYSEX_ENDS_IN_3 0x70
21
22#define SYS_COMMON_1 0x50
23#define SYS_COMMON_2 0x20
24#define SYS_COMMON_3 0x30
25
26static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
27 MIDI_EventPacket_t event;
28 event.Data1 = byte0;
29 event.Data2 = byte1;
30 event.Data3 = byte2;
31
32 uint8_t cable = 0;
33
34 //if the length is undefined we assume it is a SYSEX message
35 if (midi_packet_length(byte0) == UNDEFINED) {
36 switch(cnt) {
37 case 3:
38 if (byte2 == SYSEX_END)
39 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
40 else
41 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
42 break;
43 case 2:
44 if (byte1 == SYSEX_END)
45 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
46 else
47 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
48 break;
49 case 1:
50 if (byte0 == SYSEX_END)
51 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
52 else
53 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
54 break;
55 default:
56 return; //invalid cnt
57 }
58 } else {
59 //deal with 'system common' messages
60 //TODO are there any more?
61 switch(byte0 & 0xF0){
62 case MIDI_SONGPOSITION:
63 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
64 break;
65 case MIDI_SONGSELECT:
66 case MIDI_TC_QUARTERFRAME:
67 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
68 break;
69 default:
70 event.Event = MIDI_EVENT(cable, byte0);
71 break;
72 }
73 }
74
75 send_midi_packet(&event);
76}
77
78static void usb_get_midi(MidiDevice * device) {
79 MIDI_EventPacket_t event;
80 while (recv_midi_packet(&event)) {
81
82 midi_packet_length_t length = midi_packet_length(event.Data1);
83 uint8_t input[3];
84 input[0] = event.Data1;
85 input[1] = event.Data2;
86 input[2] = event.Data3;
87 if (length == UNDEFINED) {
88 //sysex
89 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
90 length = 3;
91 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
92 length = 2;
93 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
94 length = 1;
95 } else {
96 //XXX what to do?
97 }
98 }
99
100 //pass the data to the device input function
101 if (length != UNDEFINED)
102 midi_device_input(device, length, input);
103 }
104}
105
106static void fallthrough_callback(MidiDevice * device,
107 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
108
109#ifdef AUDIO_ENABLE
110 if (cnt == 3) {
111 switch (byte0 & 0xF0) {
112 case MIDI_NOTEON:
113 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
114 break;
115 case MIDI_NOTEOFF:
116 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
117 break;
118 }
119 }
120 if (byte0 == MIDI_STOP) {
121 stop_all_notes();
122 }
123#endif
124}
125
126
127static void cc_callback(MidiDevice * device,
128 uint8_t chan, uint8_t num, uint8_t val) {
129 //sending it back on the next channel
130 // midi_send_cc(device, (chan + 1) % 16, num, val);
131}
132
133#ifdef API_SYSEX_ENABLE
134uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
135
136static void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
137 // SEND_STRING("\n");
138 // send_word(start);
139 // SEND_STRING(": ");
140 // Don't store the header
141 int16_t pos = start - 4;
142 for (uint8_t place = 0; place < length; place++) {
143 // send_byte(*data);
144 if (pos >= 0) {
145 if (*data == 0xF7) {
146 // SEND_STRING("\nRD: ");
147 // for (uint8_t i = 0; i < start + place + 1; i++){
148 // send_byte(midi_buffer[i]);
149 // SEND_STRING(" ");
150 // }
151 const unsigned decoded_length = sysex_decoded_length(pos);
152 uint8_t decoded[API_SYSEX_MAX_SIZE];
153 sysex_decode(decoded, midi_buffer, pos);
154 process_api(decoded_length, decoded);
155 return;
156 }
157 else if (pos >= MIDI_SYSEX_BUFFER) {
158 return;
159 }
160 midi_buffer[pos] = *data;
161 }
162 // SEND_STRING(" ");
163 data++;
164 pos++;
165 }
166}
167#endif
168
169void midi_init(void);
170
171void setup_midi(void)
172{
173#ifdef MIDI_ADVANCED
174 midi_init();
175#endif
176 midi_device_init(&midi_device);
177 midi_device_set_send_func(&midi_device, usb_send_func);
178 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
179 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
180 midi_register_cc_callback(&midi_device, cc_callback);
181#ifdef API_SYSEX_ENABLE
182 midi_register_sysex_callback(&midi_device, sysex_callback);
183#endif
184}
diff --git a/tmk_core/protocol/midi/qmk_midi.h b/tmk_core/protocol/midi/qmk_midi.h
new file mode 100644
index 000000000..7282a19d4
--- /dev/null
+++ b/tmk_core/protocol/midi/qmk_midi.h
@@ -0,0 +1,9 @@
1#pragma once
2
3#ifdef MIDI_ENABLE
4 #include "midi.h"
5 extern MidiDevice midi_device;
6 void setup_midi(void);
7 void send_midi_packet(MIDI_EventPacket_t* event);
8 bool recv_midi_packet(MIDI_EventPacket_t* const event);
9#endif
diff --git a/tmk_core/protocol/lufa/descriptor.c b/tmk_core/protocol/usb_descriptor.c
index bfa91f255..cab344675 100644
--- a/tmk_core/protocol/lufa/descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -38,7 +38,7 @@
38 38
39#include "util.h" 39#include "util.h"
40#include "report.h" 40#include "report.h"
41#include "descriptor.h" 41#include "usb_descriptor.h"
42 42
43#ifndef USB_MAX_POWER_CONSUMPTION 43#ifndef USB_MAX_POWER_CONSUMPTION
44#define USB_MAX_POWER_CONSUMPTION 500 44#define USB_MAX_POWER_CONSUMPTION 500
@@ -571,6 +571,19 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
571#endif 571#endif
572 572
573#ifdef MIDI_ENABLE 573#ifdef MIDI_ENABLE
574 .Audio_Interface_Association =
575 {
576 .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
577
578 .FirstInterfaceIndex = AC_INTERFACE,
579 .TotalInterfaces = 2,
580
581 .Class = AUDIO_CSCP_AudioClass,
582 .SubClass = AUDIO_CSCP_ControlSubclass,
583 .Protocol = AUDIO_CSCP_ControlProtocol,
584
585 .IADStrIndex = NO_DESCRIPTOR,
586 },
574 .Audio_ControlInterface = 587 .Audio_ControlInterface =
575 { 588 {
576 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, 589 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@@ -622,8 +635,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
622 635
623 .AudioSpecification = VERSION_BCD(1,0,0), 636 .AudioSpecification = VERSION_BCD(1,0,0),
624 637
625 .TotalLength = (sizeof(USB_Descriptor_Configuration_t) - 638 .TotalLength = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC)
626 offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)) 639 + sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t)
640 - offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)
627 }, 641 },
628 642
629 .MIDI_In_Jack_Emb = 643 .MIDI_In_Jack_Emb =
@@ -879,9 +893,9 @@ const USB_Descriptor_String_t PROGMEM SerialNumberString =
879 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the 893 * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
880 * USB host. 894 * USB host.
881 */ 895 */
882uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, 896uint16_t get_usb_descriptor(const uint16_t wValue,
883 const uint16_t wIndex, 897 const uint16_t wIndex,
884 const void** const DescriptorAddress) 898 const void** const DescriptorAddress)
885{ 899{
886 const uint8_t DescriptorType = (wValue >> 8); 900 const uint8_t DescriptorType = (wValue >> 8);
887 const uint8_t DescriptorIndex = (wValue & 0xFF); 901 const uint8_t DescriptorIndex = (wValue & 0xFF);
diff --git a/tmk_core/protocol/lufa/descriptor.h b/tmk_core/protocol/usb_descriptor.h
index 61c42c9df..1eedfe5a5 100644
--- a/tmk_core/protocol/lufa/descriptor.h
+++ b/tmk_core/protocol/usb_descriptor.h
@@ -45,8 +45,9 @@
45#define _DESCRIPTORS_H_ 45#define _DESCRIPTORS_H_
46 46
47#include <LUFA/Drivers/USB/USB.h> 47#include <LUFA/Drivers/USB/USB.h>
48#include <avr/pgmspace.h> 48#ifdef PROTOCOL_CHIBIOS
49 49#include "hal.h"
50#endif
50 51
51typedef struct 52typedef struct
52{ 53{
@@ -95,25 +96,26 @@ typedef struct
95#endif 96#endif
96 97
97#ifdef MIDI_ENABLE 98#ifdef MIDI_ENABLE
98 // MIDI Audio Control Interface 99 USB_Descriptor_Interface_Association_t Audio_Interface_Association;
99 USB_Descriptor_Interface_t Audio_ControlInterface; 100 // MIDI Audio Control Interface
100 USB_Audio_Descriptor_Interface_AC_t Audio_ControlInterface_SPC; 101 USB_Descriptor_Interface_t Audio_ControlInterface;
101 102 USB_Audio_Descriptor_Interface_AC_t Audio_ControlInterface_SPC;
102 // MIDI Audio Streaming Interface 103
103 USB_Descriptor_Interface_t Audio_StreamInterface; 104 // MIDI Audio Streaming Interface
104 USB_MIDI_Descriptor_AudioInterface_AS_t Audio_StreamInterface_SPC; 105 USB_Descriptor_Interface_t Audio_StreamInterface;
105 USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Emb; 106 USB_MIDI_Descriptor_AudioInterface_AS_t Audio_StreamInterface_SPC;
106 USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Ext; 107 USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Emb;
107 USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Emb; 108 USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Ext;
108 USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Ext; 109 USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Emb;
109 USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint; 110 USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Ext;
110 USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC; 111 USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
111 USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint; 112 USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC;
112 USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC; 113 USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
114 USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC;
113#endif 115#endif
114 116
115#ifdef VIRTSER_ENABLE 117#ifdef VIRTSER_ENABLE
116 USB_Descriptor_Interface_Association_t CDC_Interface_Association; 118 USB_Descriptor_Interface_Association_t CDC_Interface_Association;
117 119
118 // CDC Control Interface 120 // CDC Control Interface
119 USB_Descriptor_Interface_t CDC_CCI_Interface; 121 USB_Descriptor_Interface_t CDC_CCI_Interface;
@@ -208,8 +210,14 @@ typedef struct
208 210
209#ifdef CONSOLE_ENABLE 211#ifdef CONSOLE_ENABLE
210# define CONSOLE_IN_EPNUM (RAW_OUT_EPNUM + 1) 212# define CONSOLE_IN_EPNUM (RAW_OUT_EPNUM + 1)
211//# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 2) 213#ifdef PROTOCOL_CHIBIOS
214// ChibiOS has enough memory and descriptor to actually enable the endpoint
215// It could use the same endpoint numbers, as that's supported by ChibiOS
216// But the QMK code currently assumes that the endpoint numbers are different
217# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 2)
218#else
212# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 1) 219# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 1)
220#endif
213#else 221#else
214# define CONSOLE_OUT_EPNUM RAW_OUT_EPNUM 222# define CONSOLE_OUT_EPNUM RAW_OUT_EPNUM
215#endif 223#endif
@@ -241,27 +249,24 @@ typedef struct
241# define CDC_OUT_EPNUM MIDI_STREAM_OUT_EPNUM 249# define CDC_OUT_EPNUM MIDI_STREAM_OUT_EPNUM
242#endif 250#endif
243 251
244#if (defined(__AVR_ATmega32U2__) && CDC_OUT_EPNUM > 4) || \ 252#if (defined(PROTOCOL_LUFA) && CDC_OUT_EPNUM > (ENDPOINT_TOTAL_ENDPOINTS - 1)) || \
245 (defined(__AVR_ATmega32U4__) && CDC_OUT_EPNUM > 6) 253 (defined(PROTOCOL_CHIBIOS) && CDC_OUT_EPNUM > USB_MAX_ENDPOINTS)
246# error "Endpoints are not available enough to support all functions. Remove some in Makefile.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL)" 254# 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)"
247#endif 255#endif
248 256
249#define KEYBOARD_EPSIZE 8 257#define KEYBOARD_EPSIZE 8
250#define MOUSE_EPSIZE 8 258#define MOUSE_EPSIZE 8
251#define EXTRAKEY_EPSIZE 8 259#define EXTRAKEY_EPSIZE 8
252#define RAW_EPSIZE 32 260#define RAW_EPSIZE 32
253#define CONSOLE_EPSIZE 32 261#define CONSOLE_EPSIZE 32
254#define NKRO_EPSIZE 32 262#define NKRO_EPSIZE 32
255#define MIDI_STREAM_EPSIZE 64 263#define MIDI_STREAM_EPSIZE 64
256#define CDC_NOTIFICATION_EPSIZE 8 264#define CDC_NOTIFICATION_EPSIZE 32
257#define CDC_EPSIZE 16 265#define CDC_EPSIZE 16
258 266
259 267uint16_t get_usb_descriptor(const uint16_t wValue,
260uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, 268 const uint16_t wIndex,
261 const uint16_t wIndex, 269 const void** const DescriptorAddress);
262 const void** const DescriptorAddress)
263 ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
264
265 270
266/* new API */ 271/* new API */
267#if LUFA_VERSION_INTEGER < 0x140302 272#if LUFA_VERSION_INTEGER < 0x140302