aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfredizzimo <fsundvik@gmail.com>2018-04-16 03:42:53 +0300
committerJack Humbert <jack.humb@gmail.com>2018-04-15 20:42:53 -0400
commite9d32b60b7f103cda42a19c5216e65b7b64ce9eb (patch)
treea954db818d58a86ee5bb4189568de82a453b11e8
parente2fb3079c7168ba109dfeeec20931ad75870186a (diff)
downloadqmk_firmware-e9d32b60b7f103cda42a19c5216e65b7b64ce9eb.tar.gz
qmk_firmware-e9d32b60b7f103cda42a19c5216e65b7b64ce9eb.zip
Add a custom USB driver for ARM (#2750)
* Copy Chibios serial_usb_driver into the chibios/protocol It's renamed to usb_driver to avoid name conflicts * Make the usb driver compile * Disable ChibiOS serial usb driver for all keyboards * Change usb_main to use QMKUSBDriver * Initialize the usb driver buffers * Add support for fixed size queues * Fix USB driver initialization * Don't transfer an empty packet for fixed size streams
-rw-r--r--keyboards/chibios_test/stm32_f072_onekey/halconf.h2
-rw-r--r--keyboards/chibios_test/stm32_f103_onekey/halconf.h2
-rw-r--r--keyboards/chibios_test/teensy_lc_onekey/halconf.h2
-rw-r--r--keyboards/clueboard/60/halconf.h2
-rw-r--r--keyboards/ergodox_infinity/halconf.h2
-rw-r--r--keyboards/infinity60/halconf.h2
-rw-r--r--keyboards/jm60/halconf.h2
-rw-r--r--keyboards/k_type/halconf.h2
-rw-r--r--keyboards/whitefox/halconf.h2
-rw-r--r--tmk_core/protocol/chibios.mk1
-rw-r--r--tmk_core/protocol/chibios/usb_driver.c502
-rw-r--r--tmk_core/protocol/chibios/usb_driver.h184
-rw-r--r--tmk_core/protocol/chibios/usb_main.c84
13 files changed, 738 insertions, 51 deletions
diff --git a/keyboards/chibios_test/stm32_f072_onekey/halconf.h b/keyboards/chibios_test/stm32_f072_onekey/halconf.h
index 762572558..8b9724b1a 100644
--- a/keyboards/chibios_test/stm32_f072_onekey/halconf.h
+++ b/keyboards/chibios_test/stm32_f072_onekey/halconf.h
@@ -139,7 +139,7 @@
139 * @brief Enables the SERIAL over USB subsystem. 139 * @brief Enables the SERIAL over USB subsystem.
140 */ 140 */
141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142#define HAL_USE_SERIAL_USB TRUE 142#define HAL_USE_SERIAL_USB FALSE
143#endif 143#endif
144 144
145/** 145/**
diff --git a/keyboards/chibios_test/stm32_f103_onekey/halconf.h b/keyboards/chibios_test/stm32_f103_onekey/halconf.h
index 762572558..8b9724b1a 100644
--- a/keyboards/chibios_test/stm32_f103_onekey/halconf.h
+++ b/keyboards/chibios_test/stm32_f103_onekey/halconf.h
@@ -139,7 +139,7 @@
139 * @brief Enables the SERIAL over USB subsystem. 139 * @brief Enables the SERIAL over USB subsystem.
140 */ 140 */
141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142#define HAL_USE_SERIAL_USB TRUE 142#define HAL_USE_SERIAL_USB FALSE
143#endif 143#endif
144 144
145/** 145/**
diff --git a/keyboards/chibios_test/teensy_lc_onekey/halconf.h b/keyboards/chibios_test/teensy_lc_onekey/halconf.h
index 5e1f6a8a1..1b6f2adc2 100644
--- a/keyboards/chibios_test/teensy_lc_onekey/halconf.h
+++ b/keyboards/chibios_test/teensy_lc_onekey/halconf.h
@@ -139,7 +139,7 @@
139 * @brief Enables the SERIAL over USB subsystem. 139 * @brief Enables the SERIAL over USB subsystem.
140 */ 140 */
141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142#define HAL_USE_SERIAL_USB TRUE 142#define HAL_USE_SERIAL_USB FALSE
143#endif 143#endif
144 144
145/** 145/**
diff --git a/keyboards/clueboard/60/halconf.h b/keyboards/clueboard/60/halconf.h
index 8fe8e0c6f..e617fdffc 100644
--- a/keyboards/clueboard/60/halconf.h
+++ b/keyboards/clueboard/60/halconf.h
@@ -146,7 +146,7 @@
146 * @brief Enables the SERIAL over USB subsystem. 146 * @brief Enables the SERIAL over USB subsystem.
147 */ 147 */
148#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 148#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
149#define HAL_USE_SERIAL_USB TRUE 149#define HAL_USE_SERIAL_USB FALSE
150#endif 150#endif
151 151
152/** 152/**
diff --git a/keyboards/ergodox_infinity/halconf.h b/keyboards/ergodox_infinity/halconf.h
index 3f4ffb7be..ade55ae72 100644
--- a/keyboards/ergodox_infinity/halconf.h
+++ b/keyboards/ergodox_infinity/halconf.h
@@ -139,7 +139,7 @@
139 * @brief Enables the SERIAL over USB subsystem. 139 * @brief Enables the SERIAL over USB subsystem.
140 */ 140 */
141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142#define HAL_USE_SERIAL_USB TRUE 142#define HAL_USE_SERIAL_USB FALSE
143#endif 143#endif
144 144
145/** 145/**
diff --git a/keyboards/infinity60/halconf.h b/keyboards/infinity60/halconf.h
index f48413c6d..b87b0635c 100644
--- a/keyboards/infinity60/halconf.h
+++ b/keyboards/infinity60/halconf.h
@@ -139,7 +139,7 @@
139 * @brief Enables the SERIAL over USB subsystem. 139 * @brief Enables the SERIAL over USB subsystem.
140 */ 140 */
141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142#define HAL_USE_SERIAL_USB TRUE 142#define HAL_USE_SERIAL_USB FALSE
143#endif 143#endif
144 144
145/** 145/**
diff --git a/keyboards/jm60/halconf.h b/keyboards/jm60/halconf.h
index 762572558..8b9724b1a 100644
--- a/keyboards/jm60/halconf.h
+++ b/keyboards/jm60/halconf.h
@@ -139,7 +139,7 @@
139 * @brief Enables the SERIAL over USB subsystem. 139 * @brief Enables the SERIAL over USB subsystem.
140 */ 140 */
141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142#define HAL_USE_SERIAL_USB TRUE 142#define HAL_USE_SERIAL_USB FALSE
143#endif 143#endif
144 144
145/** 145/**
diff --git a/keyboards/k_type/halconf.h b/keyboards/k_type/halconf.h
index f48413c6d..b87b0635c 100644
--- a/keyboards/k_type/halconf.h
+++ b/keyboards/k_type/halconf.h
@@ -139,7 +139,7 @@
139 * @brief Enables the SERIAL over USB subsystem. 139 * @brief Enables the SERIAL over USB subsystem.
140 */ 140 */
141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142#define HAL_USE_SERIAL_USB TRUE 142#define HAL_USE_SERIAL_USB FALSE
143#endif 143#endif
144 144
145/** 145/**
diff --git a/keyboards/whitefox/halconf.h b/keyboards/whitefox/halconf.h
index f48413c6d..b87b0635c 100644
--- a/keyboards/whitefox/halconf.h
+++ b/keyboards/whitefox/halconf.h
@@ -139,7 +139,7 @@
139 * @brief Enables the SERIAL over USB subsystem. 139 * @brief Enables the SERIAL over USB subsystem.
140 */ 140 */
141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142#define HAL_USE_SERIAL_USB TRUE 142#define HAL_USE_SERIAL_USB FALSE
143#endif 143#endif
144 144
145/** 145/**
diff --git a/tmk_core/protocol/chibios.mk b/tmk_core/protocol/chibios.mk
index 6e7cfbd83..222fb4dad 100644
--- a/tmk_core/protocol/chibios.mk
+++ b/tmk_core/protocol/chibios.mk
@@ -5,6 +5,7 @@ CHIBIOS_DIR = $(PROTOCOL_DIR)/chibios
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 7SRC += usb_descriptor.c
8SRC += $(CHIBIOS_DIR)/usb_driver.c
8 9
9VPATH += $(TMK_PATH)/$(PROTOCOL_DIR) 10VPATH += $(TMK_PATH)/$(PROTOCOL_DIR)
10VPATH += $(TMK_PATH)/$(CHIBIOS_DIR) 11VPATH += $(TMK_PATH)/$(CHIBIOS_DIR)
diff --git a/tmk_core/protocol/chibios/usb_driver.c b/tmk_core/protocol/chibios/usb_driver.c
new file mode 100644
index 000000000..fe535eeb3
--- /dev/null
+++ b/tmk_core/protocol/chibios/usb_driver.c
@@ -0,0 +1,502 @@
1/*
2 ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file hal_serial_usb.c
19 * @brief Serial over USB Driver code.
20 *
21 * @addtogroup SERIAL_USB
22 * @{
23 */
24
25#include "hal.h"
26#include "usb_driver.h"
27#include <string.h>
28
29/*===========================================================================*/
30/* Driver local definitions. */
31/*===========================================================================*/
32
33/*===========================================================================*/
34/* Driver exported variables. */
35/*===========================================================================*/
36
37/*===========================================================================*/
38/* Driver local variables and types. */
39/*===========================================================================*/
40
41/*
42 * Current Line Coding.
43 */
44static cdc_linecoding_t linecoding = {
45 {0x00, 0x96, 0x00, 0x00}, /* 38400. */
46 LC_STOP_1, LC_PARITY_NONE, 8
47};
48
49/*===========================================================================*/
50/* Driver local functions. */
51/*===========================================================================*/
52
53static bool qmkusb_start_receive(QMKUSBDriver *qmkusbp) {
54 uint8_t *buf;
55
56 /* If the USB driver is not in the appropriate state then transactions
57 must not be started.*/
58 if ((usbGetDriverStateI(qmkusbp->config->usbp) != USB_ACTIVE) ||
59 (qmkusbp->state != QMKUSB_READY)) {
60 return true;
61 }
62
63 /* Checking if there is already a transaction ongoing on the endpoint.*/
64 if (usbGetReceiveStatusI(qmkusbp->config->usbp, qmkusbp->config->bulk_in)) {
65 return true;
66 }
67
68 /* Checking if there is a buffer ready for incoming data.*/
69 buf = ibqGetEmptyBufferI(&qmkusbp->ibqueue);
70 if (buf == NULL) {
71 return true;
72 }
73
74 /* Buffer found, starting a new transaction.*/
75 usbStartReceiveI(qmkusbp->config->usbp, qmkusbp->config->bulk_out,
76 buf, qmkusbp->ibqueue.bsize - sizeof(size_t));
77
78 return false;
79}
80
81/*
82 * Interface implementation.
83 */
84
85static size_t _write(void *ip, const uint8_t *bp, size_t n) {
86
87 return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp,
88 n, TIME_INFINITE);
89}
90
91static size_t _read(void *ip, uint8_t *bp, size_t n) {
92
93 return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp,
94 n, TIME_INFINITE);
95}
96
97static msg_t _put(void *ip, uint8_t b) {
98
99 return obqPutTimeout(&((QMKUSBDriver *)ip)->obqueue, b, TIME_INFINITE);
100}
101
102static msg_t _get(void *ip) {
103
104 return ibqGetTimeout(&((QMKUSBDriver *)ip)->ibqueue, TIME_INFINITE);
105}
106
107static msg_t _putt(void *ip, uint8_t b, systime_t timeout) {
108
109 return obqPutTimeout(&((QMKUSBDriver *)ip)->obqueue, b, timeout);
110}
111
112static msg_t _gett(void *ip, systime_t timeout) {
113
114 return ibqGetTimeout(&((QMKUSBDriver *)ip)->ibqueue, timeout);
115}
116
117static size_t _writet(void *ip, const uint8_t *bp, size_t n, systime_t timeout) {
118
119 return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp, n, timeout);
120}
121
122static size_t _readt(void *ip, uint8_t *bp, size_t n, systime_t timeout) {
123
124 return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, timeout);
125}
126
127static const struct QMKUSBDriverVMT vmt = {
128 _write, _read, _put, _get,
129 _putt, _gett, _writet, _readt
130};
131
132/**
133 * @brief Notification of empty buffer released into the input buffers queue.
134 *
135 * @param[in] bqp the buffers queue pointer.
136 */
137static void ibnotify(io_buffers_queue_t *bqp) {
138 QMKUSBDriver *qmkusbp = bqGetLinkX(bqp);
139 (void) qmkusb_start_receive(qmkusbp);
140}
141
142/**
143 * @brief Notification of filled buffer inserted into the output buffers queue.
144 *
145 * @param[in] bqp the buffers queue pointer.
146 */
147static void obnotify(io_buffers_queue_t *bqp) {
148 size_t n;
149 QMKUSBDriver *qmkusbp = bqGetLinkX(bqp);
150
151 /* If the USB driver is not in the appropriate state then transactions
152 must not be started.*/
153 if ((usbGetDriverStateI(qmkusbp->config->usbp) != USB_ACTIVE) ||
154 (qmkusbp->state != QMKUSB_READY)) {
155 return;
156 }
157
158 /* Checking if there is already a transaction ongoing on the endpoint.*/
159 if (!usbGetTransmitStatusI(qmkusbp->config->usbp, qmkusbp->config->bulk_in)) {
160 /* Trying to get a full buffer.*/
161 uint8_t *buf = obqGetFullBufferI(&qmkusbp->obqueue, &n);
162 if (buf != NULL) {
163 /* Buffer found, starting a new transaction.*/
164 usbStartTransmitI(qmkusbp->config->usbp, qmkusbp->config->bulk_in, buf, n);
165 }
166 }
167}
168
169/*===========================================================================*/
170/* Driver exported functions. */
171/*===========================================================================*/
172
173/**
174 * @brief Serial Driver initialization.
175 * @note This function is implicitly invoked by @p halInit(), there is
176 * no need to explicitly initialize the driver.
177 *
178 * @init
179 */
180void qmkusbInit(void) {
181}
182
183/**
184 * @brief Initializes a generic full duplex driver object.
185 * @details The HW dependent part of the initialization has to be performed
186 * outside, usually in the hardware initialization code.
187 *
188 * @param[out] qmkusbp pointer to a @p QMKUSBDriver structure
189 *
190 * @init
191 */
192void qmkusbObjectInit(QMKUSBDriver *qmkusbp, const QMKUSBConfig *config) {
193
194 qmkusbp->vmt = &vmt;
195 osalEventObjectInit(&qmkusbp->event);
196 qmkusbp->state = QMKUSB_STOP;
197 // Note that the config uses the USB direction naming
198 ibqObjectInit(&qmkusbp->ibqueue, true, config->ob,
199 config->out_size, config->out_buffers,
200 ibnotify, qmkusbp);
201 obqObjectInit(&qmkusbp->obqueue, true, config->ib,
202 config->in_size, config->in_buffers,
203 obnotify, qmkusbp);
204}
205
206/**
207 * @brief Configures and starts the driver.
208 *
209 * @param[in] qmkusbp pointer to a @p QMKUSBDriver object
210 * @param[in] config the serial over USB driver configuration
211 *
212 * @api
213 */
214void qmkusbStart(QMKUSBDriver *qmkusbp, const QMKUSBConfig *config) {
215 USBDriver *usbp = config->usbp;
216
217 osalDbgCheck(qmkusbp != NULL);
218
219 osalSysLock();
220 osalDbgAssert((qmkusbp->state == QMKUSB_STOP) || (qmkusbp->state == QMKUSB_READY),
221 "invalid state");
222 usbp->in_params[config->bulk_in - 1U] = qmkusbp;
223 usbp->out_params[config->bulk_out - 1U] = qmkusbp;
224 if (config->int_in > 0U) {
225 usbp->in_params[config->int_in - 1U] = qmkusbp;
226 }
227 qmkusbp->config = config;
228 qmkusbp->state = QMKUSB_READY;
229 osalSysUnlock();
230}
231
232/**
233 * @brief Stops the driver.
234 * @details Any thread waiting on the driver's queues will be awakened with
235 * the message @p MSG_RESET.
236 *
237 * @param[in] qmkusbp pointer to a @p QMKUSBDriver object
238 *
239 * @api
240 */
241void qmkusbStop(QMKUSBDriver *qmkusbp) {
242 USBDriver *usbp = qmkusbp->config->usbp;
243
244 osalDbgCheck(qmkusbp != NULL);
245
246 osalSysLock();
247
248 osalDbgAssert((qmkusbp->state == QMKUSB_STOP) || (qmkusbp->state == QMKUSB_READY),
249 "invalid state");
250
251 /* Driver in stopped state.*/
252 usbp->in_params[qmkusbp->config->bulk_in - 1U] = NULL;
253 usbp->out_params[qmkusbp->config->bulk_out - 1U] = NULL;
254 if (qmkusbp->config->int_in > 0U) {
255 usbp->in_params[qmkusbp->config->int_in - 1U] = NULL;
256 }
257 qmkusbp->config = NULL;
258 qmkusbp->state = QMKUSB_STOP;
259
260 /* Enforces a disconnection.*/
261 chnAddFlagsI(qmkusbp, CHN_DISCONNECTED);
262 ibqResetI(&qmkusbp->ibqueue);
263 obqResetI(&qmkusbp->obqueue);
264 osalOsRescheduleS();
265
266 osalSysUnlock();
267}
268
269/**
270 * @brief USB device suspend handler.
271 * @details Generates a @p CHN_DISCONNECT event and puts queues in
272 * non-blocking mode, this way the application cannot get stuck
273 * in the middle of an I/O operations.
274 * @note If this function is not called from an ISR then an explicit call
275 * to @p osalOsRescheduleS() in necessary afterward.
276 *
277 * @param[in] qmkusbp pointer to a @p QMKUSBDriver object
278 *
279 * @iclass
280 */
281void qmkusbSuspendHookI(QMKUSBDriver *qmkusbp) {
282
283 chnAddFlagsI(qmkusbp, CHN_DISCONNECTED);
284 bqSuspendI(&qmkusbp->ibqueue);
285 bqSuspendI(&qmkusbp->obqueue);
286}
287
288/**
289 * @brief USB device wakeup handler.
290 * @details Generates a @p CHN_CONNECT event and resumes normal queues
291 * operations.
292 *
293 * @note If this function is not called from an ISR then an explicit call
294 * to @p osalOsRescheduleS() in necessary afterward.
295 *
296 * @param[in] qmkusbp pointer to a @p QMKUSBDriver object
297 *
298 * @iclass
299 */
300void qmkusbWakeupHookI(QMKUSBDriver *qmkusbp) {
301
302 chnAddFlagsI(qmkusbp, CHN_CONNECTED);
303 bqResumeX(&qmkusbp->ibqueue);
304 bqResumeX(&qmkusbp->obqueue);
305}
306
307/**
308 * @brief USB device configured handler.
309 *
310 * @param[in] qmkusbp pointer to a @p QMKUSBDriver object
311 *
312 * @iclass
313 */
314void qmkusbConfigureHookI(QMKUSBDriver *qmkusbp) {
315
316 ibqResetI(&qmkusbp->ibqueue);
317 bqResumeX(&qmkusbp->ibqueue);
318 obqResetI(&qmkusbp->obqueue);
319 bqResumeX(&qmkusbp->obqueue);
320 chnAddFlagsI(qmkusbp, CHN_CONNECTED);
321 (void) qmkusb_start_receive(qmkusbp);
322}
323
324/**
325 * @brief Default requests hook.
326 * @details Applications wanting to use the Serial over USB driver can use
327 * this function as requests hook in the USB configuration.
328 * The following requests are emulated:
329 * - CDC_GET_LINE_CODING.
330 * - CDC_SET_LINE_CODING.
331 * - CDC_SET_CONTROL_LINE_STATE.
332 * .
333 *
334 * @param[in] usbp pointer to the @p USBDriver object
335 * @return The hook status.
336 * @retval true Message handled internally.
337 * @retval false Message not handled.
338 */
339bool qmkusbRequestsHook(USBDriver *usbp) {
340
341 if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
342 switch (usbp->setup[1]) {
343 case CDC_GET_LINE_CODING:
344 usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
345 return true;
346 case CDC_SET_LINE_CODING:
347 usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
348 return true;
349 case CDC_SET_CONTROL_LINE_STATE:
350 /* Nothing to do, there are no control lines.*/
351 usbSetupTransfer(usbp, NULL, 0, NULL);
352 return true;
353 default:
354 return false;
355 }
356 }
357 return false;
358}
359
360/**
361 * @brief SOF handler.
362 * @details The SOF interrupt is used for automatic flushing of incomplete
363 * buffers pending in the output queue.
364 *
365 * @param[in] qmkusbp pointer to a @p QMKUSBDriver object
366 *
367 * @iclass
368 */
369void qmkusbSOFHookI(QMKUSBDriver *qmkusbp) {
370
371 /* If the USB driver is not in the appropriate state then transactions
372 must not be started.*/
373 if ((usbGetDriverStateI(qmkusbp->config->usbp) != USB_ACTIVE) ||
374 (qmkusbp->state != QMKUSB_READY)) {
375 return;
376 }
377
378 /* If there is already a transaction ongoing then another one cannot be
379 started.*/
380 if (usbGetTransmitStatusI(qmkusbp->config->usbp, qmkusbp->config->bulk_in)) {
381 return;
382 }
383
384 /* Checking if there only a buffer partially filled, if so then it is
385 enforced in the queue and transmitted.*/
386 if (obqTryFlushI(&qmkusbp->obqueue)) {
387 size_t n;
388 uint8_t *buf = obqGetFullBufferI(&qmkusbp->obqueue, &n);
389
390 /* For fixed size drivers, fill the end with zeros */
391 if (qmkusbp->config->fixed_size) {
392 memset(buf + n, 0, qmkusbp->config->in_size - n);
393 n = qmkusbp->config->in_size;
394 }
395
396 osalDbgAssert(buf != NULL, "queue is empty");
397
398 usbStartTransmitI(qmkusbp->config->usbp, qmkusbp->config->bulk_in, buf, n);
399 }
400}
401
402/**
403 * @brief Default data transmitted callback.
404 * @details The application must use this function as callback for the IN
405 * data endpoint.
406 *
407 * @param[in] usbp pointer to the @p USBDriver object
408 * @param[in] ep IN endpoint number
409 */
410void qmkusbDataTransmitted(USBDriver *usbp, usbep_t ep) {
411 uint8_t *buf;
412 size_t n;
413 QMKUSBDriver *qmkusbp = usbp->in_params[ep - 1U];
414
415 if (qmkusbp == NULL) {
416 return;
417 }
418
419 osalSysLockFromISR();
420
421 /* Signaling that space is available in the output queue.*/
422 chnAddFlagsI(qmkusbp, CHN_OUTPUT_EMPTY);
423
424 /* Freeing the buffer just transmitted, if it was not a zero size packet.*/
425 if (usbp->epc[ep]->in_state->txsize > 0U) {
426 obqReleaseEmptyBufferI(&qmkusbp->obqueue);
427 }
428
429 /* Checking if there is a buffer ready for transmission.*/
430 buf = obqGetFullBufferI(&qmkusbp->obqueue, &n);
431
432 if (buf != NULL) {
433 /* The endpoint cannot be busy, we are in the context of the callback,
434 so it is safe to transmit without a check.*/
435 usbStartTransmitI(usbp, ep, buf, n);
436 }
437 else if ((usbp->epc[ep]->in_state->txsize > 0U) &&
438 ((usbp->epc[ep]->in_state->txsize &
439 ((size_t)usbp->epc[ep]->in_maxsize - 1U)) == 0U)) {
440 /* Transmit zero sized packet in case the last one has maximum allowed
441 size. Otherwise the recipient may expect more data coming soon and
442 not return buffered data to app. See section 5.8.3 Bulk Transfer
443 Packet Size Constraints of the USB Specification document.*/
444 if (!qmkusbp->config->fixed_size) {
445 usbStartTransmitI(usbp, ep, usbp->setup, 0);
446 }
447
448 }
449 else {
450 /* Nothing to transmit.*/
451 }
452
453 osalSysUnlockFromISR();
454}
455
456/**
457 * @brief Default data received callback.
458 * @details The application must use this function as callback for the OUT
459 * data endpoint.
460 *
461 * @param[in] usbp pointer to the @p USBDriver object
462 * @param[in] ep OUT endpoint number
463 */
464void qmkusbDataReceived(USBDriver *usbp, usbep_t ep) {
465 QMKUSBDriver *qmkusbp = usbp->out_params[ep - 1U];
466 if (qmkusbp == NULL) {
467 return;
468 }
469
470 osalSysLockFromISR();
471
472 /* Signaling that data is available in the input queue.*/
473 chnAddFlagsI(qmkusbp, CHN_INPUT_AVAILABLE);
474
475 /* Posting the filled buffer in the queue.*/
476 ibqPostFullBufferI(&qmkusbp->ibqueue,
477 usbGetReceiveTransactionSizeX(qmkusbp->config->usbp,
478 qmkusbp->config->bulk_out));
479
480 /* The endpoint cannot be busy, we are in the context of the callback,
481 so a packet is in the buffer for sure. Trying to get a free buffer
482 for the next transaction.*/
483 (void) qmkusb_start_receive(qmkusbp);
484
485 osalSysUnlockFromISR();
486}
487
488/**
489 * @brief Default data received callback.
490 * @details The application must use this function as callback for the IN
491 * interrupt endpoint.
492 *
493 * @param[in] usbp pointer to the @p USBDriver object
494 * @param[in] ep endpoint number
495 */
496void qmkusbInterruptTransmitted(USBDriver *usbp, usbep_t ep) {
497
498 (void)usbp;
499 (void)ep;
500}
501
502/** @} */
diff --git a/tmk_core/protocol/chibios/usb_driver.h b/tmk_core/protocol/chibios/usb_driver.h
new file mode 100644
index 000000000..558479e19
--- /dev/null
+++ b/tmk_core/protocol/chibios/usb_driver.h
@@ -0,0 +1,184 @@
1/*
2 ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file usb_driver.h
19 * @brief Usb driver suitable for both packet and serial formats
20 *
21 * @addtogroup SERIAL_USB
22 * @{
23 */
24
25#ifndef USB_DRIVER_H
26#define USB_DRIVER_H
27
28#include "hal_usb_cdc.h"
29
30/*===========================================================================*/
31/* Driver constants. */
32/*===========================================================================*/
33
34/*===========================================================================*/
35/* Derived constants and error checks. */
36/*===========================================================================*/
37
38#if HAL_USE_USB == FALSE
39#error "The USB Driver requires HAL_USE_USB"
40#endif
41
42/*===========================================================================*/
43/* Driver data structures and types. */
44/*===========================================================================*/
45
46/**
47 * @brief Driver state machine possible states.
48 */
49typedef enum {
50 QMKUSB_UNINIT = 0, /**< Not initialized. */
51 QMKUSB_STOP = 1, /**< Stopped. */
52 QMKUSB_READY = 2 /**< Ready. */
53} qmkusbstate_t;
54
55/**
56 * @brief Structure representing a serial over USB driver.
57 */
58typedef struct QMKUSBDriver QMKUSBDriver;
59
60/**
61 * @brief Serial over USB Driver configuration structure.
62 * @details An instance of this structure must be passed to @p sduStart()
63 * in order to configure and start the driver operations.
64 */
65typedef struct {
66 /**
67 * @brief USB driver to use.
68 */
69 USBDriver *usbp;
70 /**
71 * @brief Bulk IN endpoint used for outgoing data transfer.
72 */
73 usbep_t bulk_in;
74 /**
75 * @brief Bulk OUT endpoint used for incoming data transfer.
76 */
77 usbep_t bulk_out;
78 /**
79 * @brief Interrupt IN endpoint used for notifications.
80 * @note If set to zero then the INT endpoint is assumed to be not
81 * present, USB descriptors must be changed accordingly.
82 */
83 usbep_t int_in;
84
85 /**
86 * @brief The number of buffers in the queues
87 */
88 size_t in_buffers;
89 size_t out_buffers;
90
91 /**
92 * @brief The size of each buffer in the queue, typically the same as the endpoint size
93 */
94 size_t in_size;
95 size_t out_size;
96
97 /**
98 * @brief Always send full buffers in_size (the rest is filled with zeroes)
99 */
100 bool fixed_size;
101
102 /* Input buffer
103 * @note needs to be initialized with a memory buffer of the right size
104 */
105 uint8_t* ib;
106 /* Output buffer
107 * @note needs to be initialized with a memory buffer of the right size
108 */
109 uint8_t* ob;
110} QMKUSBConfig;
111
112/**
113 * @brief @p SerialDriver specific data.
114 */
115#define _qmk_usb_driver_data \
116 _base_asynchronous_channel_data \
117 /* Driver state.*/ \
118 qmkusbstate_t state; \
119 /* Input buffers queue.*/ \
120 input_buffers_queue_t ibqueue; \
121 /* Output queue.*/ \
122 output_buffers_queue_t obqueue; \
123 /* End of the mandatory fields.*/ \
124 /* Current configuration data.*/ \
125 const QMKUSBConfig *config;
126
127/**
128 * @brief @p SerialUSBDriver specific methods.
129 */
130#define _qmk_usb_driver_methods \
131 _base_asynchronous_channel_methods
132
133/**
134 * @extends BaseAsynchronousChannelVMT
135 *
136 * @brief @p SerialDriver virtual methods table.
137 */
138struct QMKUSBDriverVMT {
139 _qmk_usb_driver_methods
140};
141
142/**
143 * @extends BaseAsynchronousChannel
144 *
145 * @brief Full duplex serial driver class.
146 * @details This class extends @p BaseAsynchronousChannel by adding physical
147 * I/O queues.
148 */
149struct QMKUSBDriver {
150 /** @brief Virtual Methods Table.*/
151 const struct QMKUSBDriverVMT *vmt;
152 _qmk_usb_driver_data
153};
154
155/*===========================================================================*/
156/* Driver macros. */
157/*===========================================================================*/
158
159/*===========================================================================*/
160/* External declarations. */
161/*===========================================================================*/
162
163#ifdef __cplusplus
164extern "C" {
165#endif
166 void qmkusbInit(void);
167 void qmkusbObjectInit(QMKUSBDriver *qmkusbp, const QMKUSBConfig * config);
168 void qmkusbStart(QMKUSBDriver *qmkusbp, const QMKUSBConfig *config);
169 void qmkusbStop(QMKUSBDriver *qmkusbp);
170 void qmkusbSuspendHookI(QMKUSBDriver *qmkusbp);
171 void qmkusbWakeupHookI(QMKUSBDriver *qmkusbp);
172 void qmkusbConfigureHookI(QMKUSBDriver *qmkusbp);
173 bool qmkusbRequestsHook(USBDriver *usbp);
174 void qmkusbSOFHookI(QMKUSBDriver *qmkusbp);
175 void qmkusbDataTransmitted(USBDriver *usbp, usbep_t ep);
176 void qmkusbDataReceived(USBDriver *usbp, usbep_t ep);
177 void qmkusbInterruptTransmitted(USBDriver *usbp, usbep_t ep);
178#ifdef __cplusplus
179}
180#endif
181
182#endif /* USB_DRIVER_H */
183
184/** @} */
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index f980024ab..cbe257194 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -29,6 +29,7 @@
29#endif 29#endif
30#include "wait.h" 30#include "wait.h"
31#include "usb_descriptor.h" 31#include "usb_descriptor.h"
32#include "usb_driver.h"
32 33
33#ifdef NKRO_ENABLE 34#ifdef NKRO_ENABLE
34 #include "keycode_config.h" 35 #include "keycode_config.h"
@@ -170,27 +171,23 @@ static const USBEndpointConfig nkro_ep_config = {
170typedef struct { 171typedef struct {
171 size_t queue_capacity_in; 172 size_t queue_capacity_in;
172 size_t queue_capacity_out; 173 size_t queue_capacity_out;
173 uint8_t* queue_buffer_in;
174 uint8_t* queue_buffer_out;
175 USBInEndpointState in_ep_state; 174 USBInEndpointState in_ep_state;
176 USBOutEndpointState out_ep_state; 175 USBOutEndpointState out_ep_state;
177 USBInEndpointState int_ep_state; 176 USBInEndpointState int_ep_state;
178 USBEndpointConfig in_ep_config; 177 USBEndpointConfig in_ep_config;
179 USBEndpointConfig out_ep_config; 178 USBEndpointConfig out_ep_config;
180 USBEndpointConfig int_ep_config; 179 USBEndpointConfig int_ep_config;
181 const SerialUSBConfig config; 180 const QMKUSBConfig config;
182 SerialUSBDriver driver; 181 QMKUSBDriver driver;
183} stream_driver_t; 182} usb_driver_config_t;
184 183
185#define STREAM_DRIVER(stream, notification) { \ 184#define QMK_USB_DRIVER_CONFIG(stream, notification, fixedsize) { \
186 .queue_capacity_in = stream##_IN_CAPACITY, \ 185 .queue_capacity_in = stream##_IN_CAPACITY, \
187 .queue_capacity_out = stream##_OUT_CAPACITY, \ 186 .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 = { \ 187 .in_ep_config = { \
191 .ep_mode = stream##_IN_MODE, \ 188 .ep_mode = stream##_IN_MODE, \
192 .setup_cb = NULL, \ 189 .setup_cb = NULL, \
193 .in_cb = sduDataTransmitted, \ 190 .in_cb = qmkusbDataTransmitted, \
194 .out_cb = NULL, \ 191 .out_cb = NULL, \
195 .in_maxsize = stream##_EPSIZE, \ 192 .in_maxsize = stream##_EPSIZE, \
196 .out_maxsize = 0, \ 193 .out_maxsize = 0, \
@@ -204,7 +201,7 @@ typedef struct {
204 .ep_mode = stream##_OUT_MODE, \ 201 .ep_mode = stream##_OUT_MODE, \
205 .setup_cb = NULL, \ 202 .setup_cb = NULL, \
206 .in_cb = NULL, \ 203 .in_cb = NULL, \
207 .out_cb = sduDataReceived, \ 204 .out_cb = qmkusbDataReceived, \
208 .in_maxsize = 0, \ 205 .in_maxsize = 0, \
209 .out_maxsize = stream##_EPSIZE, \ 206 .out_maxsize = stream##_EPSIZE, \
210 /* The pointer to the states will be filled during initialization */ \ 207 /* The pointer to the states will be filled during initialization */ \
@@ -216,7 +213,7 @@ typedef struct {
216 .int_ep_config = { \ 213 .int_ep_config = { \
217 .ep_mode = USB_EP_MODE_TYPE_INTR, \ 214 .ep_mode = USB_EP_MODE_TYPE_INTR, \
218 .setup_cb = NULL, \ 215 .setup_cb = NULL, \
219 .in_cb = sduInterruptTransmitted, \ 216 .in_cb = qmkusbInterruptTransmitted, \
220 .out_cb = NULL, \ 217 .out_cb = NULL, \
221 .in_maxsize = CDC_NOTIFICATION_EPSIZE, \ 218 .in_maxsize = CDC_NOTIFICATION_EPSIZE, \
222 .out_maxsize = 0, \ 219 .out_maxsize = 0, \
@@ -230,7 +227,14 @@ typedef struct {
230 .usbp = &USB_DRIVER, \ 227 .usbp = &USB_DRIVER, \
231 .bulk_in = stream##_IN_EPNUM, \ 228 .bulk_in = stream##_IN_EPNUM, \
232 .bulk_out = stream##_OUT_EPNUM, \ 229 .bulk_out = stream##_OUT_EPNUM, \
233 .int_in = notification \ 230 .int_in = notification, \
231 .in_buffers = stream##_IN_CAPACITY, \
232 .out_buffers = stream##_OUT_CAPACITY, \
233 .in_size = stream##_EPSIZE, \
234 .out_size = stream##_EPSIZE, \
235 .fixed_size = fixedsize, \
236 .ib = (uint8_t[BQ_BUFFER_SIZE(stream##_IN_CAPACITY, stream##_EPSIZE)]) {}, \
237 .ob = (uint8_t[BQ_BUFFER_SIZE(stream##_OUT_CAPACITY,stream##_EPSIZE)]) {}, \
234 } \ 238 } \
235} 239}
236 240
@@ -238,36 +242,36 @@ typedef struct {
238 union { 242 union {
239 struct { 243 struct {
240#ifdef CONSOLE_ENABLE 244#ifdef CONSOLE_ENABLE
241 stream_driver_t console_driver; 245 usb_driver_config_t console_driver;
242#endif 246#endif
243#ifdef RAW_ENABLE 247#ifdef RAW_ENABLE
244 stream_driver_t raw_driver; 248 usb_driver_config_t raw_driver;
245#endif 249#endif
246#ifdef MIDI_ENABLE 250#ifdef MIDI_ENABLE
247 stream_driver_t midi_driver; 251 usb_driver_config_t midi_driver;
248#endif 252#endif
249#ifdef VIRTSER_ENABLE 253#ifdef VIRTSER_ENABLE
250 stream_driver_t serial_driver; 254 usb_driver_config_t serial_driver;
251#endif 255#endif
252 }; 256 };
253 stream_driver_t array[0]; 257 usb_driver_config_t array[0];
254 }; 258 };
255} stream_drivers_t; 259} usb_driver_configs_t;
256 260
257static stream_drivers_t drivers = { 261static usb_driver_configs_t drivers = {
258#ifdef CONSOLE_ENABLE 262#ifdef CONSOLE_ENABLE
259 #define CONSOLE_IN_CAPACITY 4 263 #define CONSOLE_IN_CAPACITY 4
260 #define CONSOLE_OUT_CAPACITY 4 264 #define CONSOLE_OUT_CAPACITY 4
261 #define CONSOLE_IN_MODE USB_EP_MODE_TYPE_INTR 265 #define CONSOLE_IN_MODE USB_EP_MODE_TYPE_INTR
262 #define CONSOLE_OUT_MODE USB_EP_MODE_TYPE_INTR 266 #define CONSOLE_OUT_MODE USB_EP_MODE_TYPE_INTR
263 .console_driver = STREAM_DRIVER(CONSOLE, 0), 267 .console_driver = QMK_USB_DRIVER_CONFIG(CONSOLE, 0, true),
264#endif 268#endif
265#ifdef RAW_ENABLE 269#ifdef RAW_ENABLE
266 #define RAW_IN_CAPACITY 4 270 #define RAW_IN_CAPACITY 4
267 #define RAW_OUT_CAPACITY 4 271 #define RAW_OUT_CAPACITY 4
268 #define RAW_IN_MODE USB_EP_MODE_TYPE_INTR 272 #define RAW_IN_MODE USB_EP_MODE_TYPE_INTR
269 #define RAW_OUT_MODE USB_EP_MODE_TYPE_INTR 273 #define RAW_OUT_MODE USB_EP_MODE_TYPE_INTR
270 .raw_driver = STREAM_DRIVER(RAW, 0), 274 .raw_driver = QMK_USB_DRIVER_CONFIG(RAW, 0, false),
271#endif 275#endif
272 276
273#ifdef MIDI_ENABLE 277#ifdef MIDI_ENABLE
@@ -275,7 +279,7 @@ static stream_drivers_t drivers = {
275 #define MIDI_STREAM_OUT_CAPACITY 4 279 #define MIDI_STREAM_OUT_CAPACITY 4
276 #define MIDI_STREAM_IN_MODE USB_EP_MODE_TYPE_BULK 280 #define MIDI_STREAM_IN_MODE USB_EP_MODE_TYPE_BULK
277 #define MIDI_STREAM_OUT_MODE USB_EP_MODE_TYPE_BULK 281 #define MIDI_STREAM_OUT_MODE USB_EP_MODE_TYPE_BULK
278 .midi_driver = STREAM_DRIVER(MIDI_STREAM, 0), 282 .midi_driver = QMK_USB_DRIVER_CONFIG(MIDI_STREAM, 0, false),
279#endif 283#endif
280 284
281#ifdef VIRTSER_ENABLE 285#ifdef VIRTSER_ENABLE
@@ -283,11 +287,11 @@ static stream_drivers_t drivers = {
283 #define CDC_OUT_CAPACITY 4 287 #define CDC_OUT_CAPACITY 4
284 #define CDC_IN_MODE USB_EP_MODE_TYPE_BULK 288 #define CDC_IN_MODE USB_EP_MODE_TYPE_BULK
285 #define CDC_OUT_MODE USB_EP_MODE_TYPE_BULK 289 #define CDC_OUT_MODE USB_EP_MODE_TYPE_BULK
286 .serial_driver = STREAM_DRIVER(CDC, CDC_NOTIFICATION_EPNUM), 290 .serial_driver = QMK_USB_DRIVER_CONFIG(CDC, CDC_NOTIFICATION_EPNUM, false),
287#endif 291#endif
288}; 292};
289 293
290#define NUM_STREAM_DRIVERS (sizeof(drivers) / sizeof(stream_driver_t)) 294#define NUM_USB_DRIVERS (sizeof(drivers) / sizeof(usb_driver_config_t))
291 295
292 296
293/* --------------------------------------------------------- 297/* ---------------------------------------------------------
@@ -315,13 +319,13 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
315#ifdef NKRO_ENABLE 319#ifdef NKRO_ENABLE
316 usbInitEndpointI(usbp, NKRO_IN_EPNUM, &nkro_ep_config); 320 usbInitEndpointI(usbp, NKRO_IN_EPNUM, &nkro_ep_config);
317#endif /* NKRO_ENABLE */ 321#endif /* NKRO_ENABLE */
318 for (int i=0;i<NUM_STREAM_DRIVERS;i++) { 322 for (int i=0;i<NUM_USB_DRIVERS;i++) {
319 usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].in_ep_config); 323 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); 324 usbInitEndpointI(usbp, drivers.array[i].config.bulk_out, &drivers.array[i].out_ep_config);
321 if (drivers.array[i].config.int_in) { 325 if (drivers.array[i].config.int_in) {
322 usbInitEndpointI(usbp, drivers.array[i].config.int_in, &drivers.array[i].int_ep_config); 326 usbInitEndpointI(usbp, drivers.array[i].config.int_in, &drivers.array[i].int_ep_config);
323 } 327 }
324 sduConfigureHookI(&drivers.array[i].driver); 328 qmkusbConfigureHookI(&drivers.array[i].driver);
325 } 329 }
326 osalSysUnlockFromISR(); 330 osalSysUnlockFromISR();
327 return; 331 return;
@@ -333,20 +337,20 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
333 case USB_EVENT_UNCONFIGURED: 337 case USB_EVENT_UNCONFIGURED:
334 /* Falls into.*/ 338 /* Falls into.*/
335 case USB_EVENT_RESET: 339 case USB_EVENT_RESET:
336 for (int i=0;i<NUM_STREAM_DRIVERS;i++) { 340 for (int i=0;i<NUM_USB_DRIVERS;i++) {
337 chSysLockFromISR(); 341 chSysLockFromISR();
338 /* Disconnection event on suspend.*/ 342 /* Disconnection event on suspend.*/
339 sduSuspendHookI(&drivers.array[i].driver); 343 qmkusbSuspendHookI(&drivers.array[i].driver);
340 chSysUnlockFromISR(); 344 chSysUnlockFromISR();
341 } 345 }
342 return; 346 return;
343 347
344 case USB_EVENT_WAKEUP: 348 case USB_EVENT_WAKEUP:
345 //TODO: from ISR! print("[W]"); 349 //TODO: from ISR! print("[W]");
346 for (int i=0;i<NUM_STREAM_DRIVERS;i++) { 350 for (int i=0;i<NUM_USB_DRIVERS;i++) {
347 chSysLockFromISR(); 351 chSysLockFromISR();
348 /* Disconnection event on suspend.*/ 352 /* Disconnection event on suspend.*/
349 sduWakeupHookI(&drivers.array[i].driver); 353 qmkusbWakeupHookI(&drivers.array[i].driver);
350 chSysUnlockFromISR(); 354 chSysUnlockFromISR();
351 } 355 }
352 suspend_wakeup_init(); 356 suspend_wakeup_init();
@@ -527,10 +531,10 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
527 return TRUE; 531 return TRUE;
528 } 532 }
529 533
530 for (int i=0;i<NUM_STREAM_DRIVERS;i++) { 534 for (int i=0;i<NUM_USB_DRIVERS;i++) {
531 if (drivers.array[i].config.int_in) { 535 if (drivers.array[i].config.int_in) {
532 // NOTE: Assumes that we only have one serial driver 536 // NOTE: Assumes that we only have one serial driver
533 return sduRequestsHook(usbp); 537 return qmkusbRequestsHook(usbp);
534 } 538 }
535 } 539 }
536 540
@@ -541,8 +545,8 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
541static void usb_sof_cb(USBDriver *usbp) { 545static void usb_sof_cb(USBDriver *usbp) {
542 kbd_sof_cb(usbp); 546 kbd_sof_cb(usbp);
543 osalSysLockFromISR(); 547 osalSysLockFromISR();
544 for (int i=0; i<NUM_STREAM_DRIVERS;i++) { 548 for (int i=0; i<NUM_USB_DRIVERS;i++) {
545 sduSOFHookI(&drivers.array[i].driver); 549 qmkusbSOFHookI(&drivers.array[i].driver);
546 } 550 }
547 osalSysUnlockFromISR(); 551 osalSysUnlockFromISR();
548} 552}
@@ -560,17 +564,13 @@ static const USBConfig usbcfg = {
560 * Initialize the USB driver 564 * Initialize the USB driver
561 */ 565 */
562void init_usb_driver(USBDriver *usbp) { 566void init_usb_driver(USBDriver *usbp) {
563 for (int i=0; i<NUM_STREAM_DRIVERS;i++) { 567 for (int i=0; i<NUM_USB_DRIVERS;i++) {
564 SerialUSBDriver* driver = &drivers.array[i].driver; 568 QMKUSBDriver* driver = &drivers.array[i].driver;
565 drivers.array[i].in_ep_config.in_state = &drivers.array[i].in_ep_state; 569 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; 570 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; 571 drivers.array[i].int_ep_config.in_state = &drivers.array[i].int_ep_state;
568 sduObjectInit(driver); 572 qmkusbObjectInit(driver, &drivers.array[i].config);
569 bqnotify_t notify = driver->ibqueue.notify; 573 qmkusbStart(driver, &drivers.array[i].config);
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 } 574 }
575 575
576 /* 576 /*