From e9d32b60b7f103cda42a19c5216e65b7b64ce9eb Mon Sep 17 00:00:00 2001 From: fredizzimo Date: Mon, 16 Apr 2018 03:42:53 +0300 Subject: 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 --- tmk_core/protocol/chibios/usb_driver.h | 184 +++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 tmk_core/protocol/chibios/usb_driver.h (limited to 'tmk_core/protocol/chibios/usb_driver.h') 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 @@ +/* + 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 */ + +/** @} */ -- cgit v1.2.3-24-g4f1b