mirror of
https://github.com/qmk/qmk_firmware.git
synced 2026-09-24 06:15:49 +08:00
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
This commit is contained in:
@@ -139,7 +139,7 @@
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB TRUE
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB TRUE
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB TRUE
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB TRUE
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB TRUE
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB TRUE
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB TRUE
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB TRUE
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB TRUE
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ CHIBIOS_DIR = $(PROTOCOL_DIR)/chibios
|
||||
SRC += $(CHIBIOS_DIR)/usb_main.c
|
||||
SRC += $(CHIBIOS_DIR)/main.c
|
||||
SRC += usb_descriptor.c
|
||||
SRC += $(CHIBIOS_DIR)/usb_driver.c
|
||||
|
||||
VPATH += $(TMK_PATH)/$(PROTOCOL_DIR)
|
||||
VPATH += $(TMK_PATH)/$(CHIBIOS_DIR)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file usb_driver.h
|
||||
* @brief Usb driver suitable for both packet and serial formats
|
||||
*
|
||||
* @addtogroup SERIAL_USB
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef USB_DRIVER_H
|
||||
#define USB_DRIVER_H
|
||||
|
||||
#include "hal_usb_cdc.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if HAL_USE_USB == FALSE
|
||||
#error "The USB Driver requires HAL_USE_USB"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
QMKUSB_UNINIT = 0, /**< Not initialized. */
|
||||
QMKUSB_STOP = 1, /**< Stopped. */
|
||||
QMKUSB_READY = 2 /**< Ready. */
|
||||
} qmkusbstate_t;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a serial over USB driver.
|
||||
*/
|
||||
typedef struct QMKUSBDriver QMKUSBDriver;
|
||||
|
||||
/**
|
||||
* @brief Serial over USB Driver configuration structure.
|
||||
* @details An instance of this structure must be passed to @p sduStart()
|
||||
* in order to configure and start the driver operations.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief USB driver to use.
|
||||
*/
|
||||
USBDriver *usbp;
|
||||
/**
|
||||
* @brief Bulk IN endpoint used for outgoing data transfer.
|
||||
*/
|
||||
usbep_t bulk_in;
|
||||
/**
|
||||
* @brief Bulk OUT endpoint used for incoming data transfer.
|
||||
*/
|
||||
usbep_t bulk_out;
|
||||
/**
|
||||
* @brief Interrupt IN endpoint used for notifications.
|
||||
* @note If set to zero then the INT endpoint is assumed to be not
|
||||
* present, USB descriptors must be changed accordingly.
|
||||
*/
|
||||
usbep_t int_in;
|
||||
|
||||
/**
|
||||
* @brief The number of buffers in the queues
|
||||
*/
|
||||
size_t in_buffers;
|
||||
size_t out_buffers;
|
||||
|
||||
/**
|
||||
* @brief The size of each buffer in the queue, typically the same as the endpoint size
|
||||
*/
|
||||
size_t in_size;
|
||||
size_t out_size;
|
||||
|
||||
/**
|
||||
* @brief Always send full buffers in_size (the rest is filled with zeroes)
|
||||
*/
|
||||
bool fixed_size;
|
||||
|
||||
/* Input buffer
|
||||
* @note needs to be initialized with a memory buffer of the right size
|
||||
*/
|
||||
uint8_t* ib;
|
||||
/* Output buffer
|
||||
* @note needs to be initialized with a memory buffer of the right size
|
||||
*/
|
||||
uint8_t* ob;
|
||||
} QMKUSBConfig;
|
||||
|
||||
/**
|
||||
* @brief @p SerialDriver specific data.
|
||||
*/
|
||||
#define _qmk_usb_driver_data \
|
||||
_base_asynchronous_channel_data \
|
||||
/* Driver state.*/ \
|
||||
qmkusbstate_t state; \
|
||||
/* Input buffers queue.*/ \
|
||||
input_buffers_queue_t ibqueue; \
|
||||
/* Output queue.*/ \
|
||||
output_buffers_queue_t obqueue; \
|
||||
/* End of the mandatory fields.*/ \
|
||||
/* Current configuration data.*/ \
|
||||
const QMKUSBConfig *config;
|
||||
|
||||
/**
|
||||
* @brief @p SerialUSBDriver specific methods.
|
||||
*/
|
||||
#define _qmk_usb_driver_methods \
|
||||
_base_asynchronous_channel_methods
|
||||
|
||||
/**
|
||||
* @extends BaseAsynchronousChannelVMT
|
||||
*
|
||||
* @brief @p SerialDriver virtual methods table.
|
||||
*/
|
||||
struct QMKUSBDriverVMT {
|
||||
_qmk_usb_driver_methods
|
||||
};
|
||||
|
||||
/**
|
||||
* @extends BaseAsynchronousChannel
|
||||
*
|
||||
* @brief Full duplex serial driver class.
|
||||
* @details This class extends @p BaseAsynchronousChannel by adding physical
|
||||
* I/O queues.
|
||||
*/
|
||||
struct QMKUSBDriver {
|
||||
/** @brief Virtual Methods Table.*/
|
||||
const struct QMKUSBDriverVMT *vmt;
|
||||
_qmk_usb_driver_data
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void qmkusbInit(void);
|
||||
void qmkusbObjectInit(QMKUSBDriver *qmkusbp, const QMKUSBConfig * config);
|
||||
void qmkusbStart(QMKUSBDriver *qmkusbp, const QMKUSBConfig *config);
|
||||
void qmkusbStop(QMKUSBDriver *qmkusbp);
|
||||
void qmkusbSuspendHookI(QMKUSBDriver *qmkusbp);
|
||||
void qmkusbWakeupHookI(QMKUSBDriver *qmkusbp);
|
||||
void qmkusbConfigureHookI(QMKUSBDriver *qmkusbp);
|
||||
bool qmkusbRequestsHook(USBDriver *usbp);
|
||||
void qmkusbSOFHookI(QMKUSBDriver *qmkusbp);
|
||||
void qmkusbDataTransmitted(USBDriver *usbp, usbep_t ep);
|
||||
void qmkusbDataReceived(USBDriver *usbp, usbep_t ep);
|
||||
void qmkusbInterruptTransmitted(USBDriver *usbp, usbep_t ep);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USB_DRIVER_H */
|
||||
|
||||
/** @} */
|
||||
@@ -29,6 +29,7 @@
|
||||
#endif
|
||||
#include "wait.h"
|
||||
#include "usb_descriptor.h"
|
||||
#include "usb_driver.h"
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#include "keycode_config.h"
|
||||
@@ -170,27 +171,23 @@ static const USBEndpointConfig nkro_ep_config = {
|
||||
typedef struct {
|
||||
size_t queue_capacity_in;
|
||||
size_t queue_capacity_out;
|
||||
uint8_t* queue_buffer_in;
|
||||
uint8_t* queue_buffer_out;
|
||||
USBInEndpointState in_ep_state;
|
||||
USBOutEndpointState out_ep_state;
|
||||
USBInEndpointState int_ep_state;
|
||||
USBEndpointConfig in_ep_config;
|
||||
USBEndpointConfig out_ep_config;
|
||||
USBEndpointConfig int_ep_config;
|
||||
const SerialUSBConfig config;
|
||||
SerialUSBDriver driver;
|
||||
} stream_driver_t;
|
||||
const QMKUSBConfig config;
|
||||
QMKUSBDriver driver;
|
||||
} usb_driver_config_t;
|
||||
|
||||
#define STREAM_DRIVER(stream, notification) { \
|
||||
#define QMK_USB_DRIVER_CONFIG(stream, notification, fixedsize) { \
|
||||
.queue_capacity_in = stream##_IN_CAPACITY, \
|
||||
.queue_capacity_out = stream##_OUT_CAPACITY, \
|
||||
.queue_buffer_in = (uint8_t[BQ_BUFFER_SIZE(stream##_IN_CAPACITY, stream##_EPSIZE)]) {}, \
|
||||
.queue_buffer_out = (uint8_t[BQ_BUFFER_SIZE(stream##_OUT_CAPACITY,stream##_EPSIZE)]) {}, \
|
||||
.in_ep_config = { \
|
||||
.ep_mode = stream##_IN_MODE, \
|
||||
.setup_cb = NULL, \
|
||||
.in_cb = sduDataTransmitted, \
|
||||
.in_cb = qmkusbDataTransmitted, \
|
||||
.out_cb = NULL, \
|
||||
.in_maxsize = stream##_EPSIZE, \
|
||||
.out_maxsize = 0, \
|
||||
@@ -204,7 +201,7 @@ typedef struct {
|
||||
.ep_mode = stream##_OUT_MODE, \
|
||||
.setup_cb = NULL, \
|
||||
.in_cb = NULL, \
|
||||
.out_cb = sduDataReceived, \
|
||||
.out_cb = qmkusbDataReceived, \
|
||||
.in_maxsize = 0, \
|
||||
.out_maxsize = stream##_EPSIZE, \
|
||||
/* The pointer to the states will be filled during initialization */ \
|
||||
@@ -216,7 +213,7 @@ typedef struct {
|
||||
.int_ep_config = { \
|
||||
.ep_mode = USB_EP_MODE_TYPE_INTR, \
|
||||
.setup_cb = NULL, \
|
||||
.in_cb = sduInterruptTransmitted, \
|
||||
.in_cb = qmkusbInterruptTransmitted, \
|
||||
.out_cb = NULL, \
|
||||
.in_maxsize = CDC_NOTIFICATION_EPSIZE, \
|
||||
.out_maxsize = 0, \
|
||||
@@ -230,7 +227,14 @@ typedef struct {
|
||||
.usbp = &USB_DRIVER, \
|
||||
.bulk_in = stream##_IN_EPNUM, \
|
||||
.bulk_out = stream##_OUT_EPNUM, \
|
||||
.int_in = notification \
|
||||
.int_in = notification, \
|
||||
.in_buffers = stream##_IN_CAPACITY, \
|
||||
.out_buffers = stream##_OUT_CAPACITY, \
|
||||
.in_size = stream##_EPSIZE, \
|
||||
.out_size = stream##_EPSIZE, \
|
||||
.fixed_size = fixedsize, \
|
||||
.ib = (uint8_t[BQ_BUFFER_SIZE(stream##_IN_CAPACITY, stream##_EPSIZE)]) {}, \
|
||||
.ob = (uint8_t[BQ_BUFFER_SIZE(stream##_OUT_CAPACITY,stream##_EPSIZE)]) {}, \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -238,36 +242,36 @@ typedef struct {
|
||||
union {
|
||||
struct {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
stream_driver_t console_driver;
|
||||
usb_driver_config_t console_driver;
|
||||
#endif
|
||||
#ifdef RAW_ENABLE
|
||||
stream_driver_t raw_driver;
|
||||
usb_driver_config_t raw_driver;
|
||||
#endif
|
||||
#ifdef MIDI_ENABLE
|
||||
stream_driver_t midi_driver;
|
||||
usb_driver_config_t midi_driver;
|
||||
#endif
|
||||
#ifdef VIRTSER_ENABLE
|
||||
stream_driver_t serial_driver;
|
||||
usb_driver_config_t serial_driver;
|
||||
#endif
|
||||
};
|
||||
stream_driver_t array[0];
|
||||
usb_driver_config_t array[0];
|
||||
};
|
||||
} stream_drivers_t;
|
||||
} usb_driver_configs_t;
|
||||
|
||||
static stream_drivers_t drivers = {
|
||||
static usb_driver_configs_t drivers = {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
#define CONSOLE_IN_CAPACITY 4
|
||||
#define CONSOLE_OUT_CAPACITY 4
|
||||
#define CONSOLE_IN_MODE USB_EP_MODE_TYPE_INTR
|
||||
#define CONSOLE_OUT_MODE USB_EP_MODE_TYPE_INTR
|
||||
.console_driver = STREAM_DRIVER(CONSOLE, 0),
|
||||
.console_driver = QMK_USB_DRIVER_CONFIG(CONSOLE, 0, true),
|
||||
#endif
|
||||
#ifdef RAW_ENABLE
|
||||
#define RAW_IN_CAPACITY 4
|
||||
#define RAW_OUT_CAPACITY 4
|
||||
#define RAW_IN_MODE USB_EP_MODE_TYPE_INTR
|
||||
#define RAW_OUT_MODE USB_EP_MODE_TYPE_INTR
|
||||
.raw_driver = STREAM_DRIVER(RAW, 0),
|
||||
.raw_driver = QMK_USB_DRIVER_CONFIG(RAW, 0, false),
|
||||
#endif
|
||||
|
||||
#ifdef MIDI_ENABLE
|
||||
@@ -275,7 +279,7 @@ static stream_drivers_t drivers = {
|
||||
#define MIDI_STREAM_OUT_CAPACITY 4
|
||||
#define MIDI_STREAM_IN_MODE USB_EP_MODE_TYPE_BULK
|
||||
#define MIDI_STREAM_OUT_MODE USB_EP_MODE_TYPE_BULK
|
||||
.midi_driver = STREAM_DRIVER(MIDI_STREAM, 0),
|
||||
.midi_driver = QMK_USB_DRIVER_CONFIG(MIDI_STREAM, 0, false),
|
||||
#endif
|
||||
|
||||
#ifdef VIRTSER_ENABLE
|
||||
@@ -283,11 +287,11 @@ static stream_drivers_t drivers = {
|
||||
#define CDC_OUT_CAPACITY 4
|
||||
#define CDC_IN_MODE USB_EP_MODE_TYPE_BULK
|
||||
#define CDC_OUT_MODE USB_EP_MODE_TYPE_BULK
|
||||
.serial_driver = STREAM_DRIVER(CDC, CDC_NOTIFICATION_EPNUM),
|
||||
.serial_driver = QMK_USB_DRIVER_CONFIG(CDC, CDC_NOTIFICATION_EPNUM, false),
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NUM_STREAM_DRIVERS (sizeof(drivers) / sizeof(stream_driver_t))
|
||||
#define NUM_USB_DRIVERS (sizeof(drivers) / sizeof(usb_driver_config_t))
|
||||
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
@@ -315,13 +319,13 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
||||
#ifdef NKRO_ENABLE
|
||||
usbInitEndpointI(usbp, NKRO_IN_EPNUM, &nkro_ep_config);
|
||||
#endif /* NKRO_ENABLE */
|
||||
for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
|
||||
for (int i=0;i<NUM_USB_DRIVERS;i++) {
|
||||
usbInitEndpointI(usbp, drivers.array[i].config.bulk_in, &drivers.array[i].in_ep_config);
|
||||
usbInitEndpointI(usbp, drivers.array[i].config.bulk_out, &drivers.array[i].out_ep_config);
|
||||
if (drivers.array[i].config.int_in) {
|
||||
usbInitEndpointI(usbp, drivers.array[i].config.int_in, &drivers.array[i].int_ep_config);
|
||||
}
|
||||
sduConfigureHookI(&drivers.array[i].driver);
|
||||
qmkusbConfigureHookI(&drivers.array[i].driver);
|
||||
}
|
||||
osalSysUnlockFromISR();
|
||||
return;
|
||||
@@ -333,20 +337,20 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
||||
case USB_EVENT_UNCONFIGURED:
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_RESET:
|
||||
for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
|
||||
for (int i=0;i<NUM_USB_DRIVERS;i++) {
|
||||
chSysLockFromISR();
|
||||
/* Disconnection event on suspend.*/
|
||||
sduSuspendHookI(&drivers.array[i].driver);
|
||||
qmkusbSuspendHookI(&drivers.array[i].driver);
|
||||
chSysUnlockFromISR();
|
||||
}
|
||||
return;
|
||||
|
||||
case USB_EVENT_WAKEUP:
|
||||
//TODO: from ISR! print("[W]");
|
||||
for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
|
||||
for (int i=0;i<NUM_USB_DRIVERS;i++) {
|
||||
chSysLockFromISR();
|
||||
/* Disconnection event on suspend.*/
|
||||
sduWakeupHookI(&drivers.array[i].driver);
|
||||
qmkusbWakeupHookI(&drivers.array[i].driver);
|
||||
chSysUnlockFromISR();
|
||||
}
|
||||
suspend_wakeup_init();
|
||||
@@ -527,10 +531,10 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (int i=0;i<NUM_STREAM_DRIVERS;i++) {
|
||||
for (int i=0;i<NUM_USB_DRIVERS;i++) {
|
||||
if (drivers.array[i].config.int_in) {
|
||||
// NOTE: Assumes that we only have one serial driver
|
||||
return sduRequestsHook(usbp);
|
||||
return qmkusbRequestsHook(usbp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,8 +545,8 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
|
||||
static void usb_sof_cb(USBDriver *usbp) {
|
||||
kbd_sof_cb(usbp);
|
||||
osalSysLockFromISR();
|
||||
for (int i=0; i<NUM_STREAM_DRIVERS;i++) {
|
||||
sduSOFHookI(&drivers.array[i].driver);
|
||||
for (int i=0; i<NUM_USB_DRIVERS;i++) {
|
||||
qmkusbSOFHookI(&drivers.array[i].driver);
|
||||
}
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
@@ -560,17 +564,13 @@ static const USBConfig usbcfg = {
|
||||
* Initialize the USB driver
|
||||
*/
|
||||
void init_usb_driver(USBDriver *usbp) {
|
||||
for (int i=0; i<NUM_STREAM_DRIVERS;i++) {
|
||||
SerialUSBDriver* driver = &drivers.array[i].driver;
|
||||
for (int i=0; i<NUM_USB_DRIVERS;i++) {
|
||||
QMKUSBDriver* driver = &drivers.array[i].driver;
|
||||
drivers.array[i].in_ep_config.in_state = &drivers.array[i].in_ep_state;
|
||||
drivers.array[i].out_ep_config.out_state = &drivers.array[i].out_ep_state;
|
||||
drivers.array[i].int_ep_config.in_state = &drivers.array[i].int_ep_state;
|
||||
sduObjectInit(driver);
|
||||
bqnotify_t notify = driver->ibqueue.notify;
|
||||
ibqObjectInit(&driver->ibqueue, false, drivers.array[i].queue_buffer_in, drivers.array[i].in_ep_config.in_maxsize, drivers.array[i].queue_capacity_in, notify, driver);
|
||||
notify = driver->obqueue.notify;
|
||||
ibqObjectInit(&driver->ibqueue, false, drivers.array[i].queue_buffer_out, drivers.array[i].out_ep_config.out_maxsize, drivers.array[i].queue_capacity_out, notify, driver);
|
||||
sduStart(driver, &drivers.array[i].config);
|
||||
qmkusbObjectInit(driver, &drivers.array[i].config);
|
||||
qmkusbStart(driver, &drivers.array[i].config);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user