aboutsummaryrefslogtreecommitdiffstats
path: root/ChibiOS_16.1.5/community/os/hal/include
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2016-11-11 15:02:17 -0500
committerClyne Sullivan <tullivan99@gmail.com>2016-11-11 15:02:17 -0500
commit7772ea4579a45bcf63ebd5e68be66ba1a9c72dfa (patch)
tree9e1ce52ea97102d3513e519a77d999eac228820b /ChibiOS_16.1.5/community/os/hal/include
parent02b3ff42cccf32617c88c0ca65436b8c9d4f61eb (diff)
chibios!
Diffstat (limited to 'ChibiOS_16.1.5/community/os/hal/include')
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_community.h122
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_crc.h158
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_ee24xx.h64
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_ee25xx.h63
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_eeprom.h143
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_eicu.h191
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_nand.h137
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_onewire.h366
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_qei.h130
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_rng.h136
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_timcap.h206
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_usb_hid.h510
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/hal_usbh.h436
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/usbh/debug.h44
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/usbh/defs.h160
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/usbh/desciter.h63
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/usbh/dev/ftdi.h154
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/usbh/dev/hub.h138
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/usbh/dev/msd.h125
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/usbh/internal.h148
-rw-r--r--ChibiOS_16.1.5/community/os/hal/include/usbh/list.h598
21 files changed, 4092 insertions, 0 deletions
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_community.h b/ChibiOS_16.1.5/community/os/hal/include/hal_community.h
new file mode 100644
index 0000000..1518c7e
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_community.h
@@ -0,0 +1,122 @@
+/*
+ ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
+
+ 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 hal_community.h
+ * @brief HAL subsystem header (community part).
+ *
+ * @addtogroup HAL_COMMUNITY
+ * @{
+ */
+
+#ifndef HAL_COMMUNITY_H
+#define HAL_COMMUNITY_H
+
+
+/* Error checks on the configuration header file.*/
+#if !defined(HAL_USE_CRC)
+#define HAL_USE_CRC FALSE
+#endif
+
+#if !defined(HAL_USE_EEPROM)
+#define HAL_USE_EEPROM FALSE
+#endif
+
+#if !defined(HAL_USE_EICU)
+#define HAL_USE_EICU FALSE
+#endif
+
+#if !defined(HAL_USE_NAND)
+#define HAL_USE_NAND FALSE
+#endif
+
+#if !defined(HAL_USE_ONEWIRE)
+#define HAL_USE_ONEWIRE FALSE
+#endif
+
+#if !defined(HAL_USE_QEI)
+#define HAL_USE_QEI FALSE
+#endif
+
+#if !defined(HAL_USE_RNG)
+#define HAL_USE_RNG FALSE
+#endif
+
+#if !defined(HAL_USE_TIMCAP)
+#define HAL_USE_TIMCAP FALSE
+#endif
+
+#if !defined(HAL_USE_USBH)
+#define HAL_USE_USBH FALSE
+#endif
+
+#if !defined(HAL_USE_USB_HID)
+#define HAL_USE_USB_HID FALSE
+#endif
+
+/* Abstract interfaces.*/
+
+/* Shared headers.*/
+
+/* Normal drivers.*/
+#include "hal_nand.h"
+#include "hal_eicu.h"
+#include "hal_rng.h"
+#include "hal_usbh.h"
+#include "hal_timcap.h"
+#include "hal_qei.h"
+
+/* Complex drivers.*/
+#include "hal_onewire.h"
+#include "hal_crc.h"
+#include "hal_eeprom.h"
+#include "hal_usb_hid.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void halCommunityInit(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_COMMUNITY_H */
+
+/** @} */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_crc.h b/ChibiOS_16.1.5/community/os/hal/include/hal_crc.h
new file mode 100644
index 0000000..8c4c895
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_crc.h
@@ -0,0 +1,158 @@
+/*
+ ChibiOS - Copyright (C) 2015 Michael D. Spradling
+
+ 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.
+*/
+
+#ifndef _CRC_H_
+#define _CRC_H_
+
+#if (HAL_USE_CRC == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+
+/**
+ * @brief Enable DMA CRC
+ * @note Enables DMA when doing CRC calculations. This may be less
+ * efficient with smaller CRC calculations.
+ */
+#if !defined(CRC_USE_DMA) || defined(__DOXYGEN__)
+#define CRC_USE_DMA FALSE
+#endif
+
+/**
+ * @brief Enables the @p crcAcquireBus() and @p crcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(CRC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define CRC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_CRC_USE_CRC1 != TRUE && CRCSW_USE_CRC1 != TRUE
+#error "CRC requires at least one LLD driver."
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ CRC_UNINIT, /* Not initialized. */
+ CRC_STOP, /* Stopped. */
+ CRC_READY, /* Ready. */
+ CRC_ACTIVE, /* Calculating CRC. */
+ CRC_COMPLETE /* Asynchronous operation complete. */
+} crcstate_t;
+
+#include "hal_crc_lld.h"
+#include "crcsw.h" /* Include software LL driver */
+
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Low level driver helper macros
+ * @{
+ */
+
+/**
+ * @brief Wakes up the waiting thread.
+ *
+ * @param[in] crcp pointer to the @p CRCDriver object
+ *
+ * @notapi
+ */
+#define _crc_wakeup_isr(crcp) { \
+ osalSysLockFromISR(); \
+ osalThreadResumeI(&(crcp)->thread, MSG_OK); \
+ osalSysUnlockFromISR(); \
+}
+
+/**
+ * @brief Common ISR code.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] crcp pointer to the @p CRCDriver object
+ *
+ * @notapi
+ */
+#define _crc_isr_code(crcp, crc) { \
+ if ((crcp)->config->end_cb) { \
+ (crcp)->state = CRC_COMPLETE; \
+ (crcp)->config->end_cb(crcp, crc); \
+ if ((crcp)->state == CRC_COMPLETE) \
+ (crcp)->state = CRC_READY; \
+ } \
+ else \
+ (crcp)->state = CRC_READY; \
+ _crc_wakeup_isr(crcp); \
+}
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void crcInit(void);
+ void crcObjectInit(CRCDriver *crcp);
+ void crcStart(CRCDriver *crcp, const CRCConfig *config);
+ void crcStop(CRCDriver *crcp);
+ void crcReset(CRCDriver *crcp);
+ void crcResetI(CRCDriver *crcp);
+ uint32_t crcCalc(CRCDriver *crcp, size_t n, const void *buf);
+ uint32_t crcCalcI(CRCDriver *crcp, size_t n, const void *buf);
+#if CRC_USE_DMA == TRUE
+ void crcStartCalc(CRCDriver *crcp, size_t n, const void *buf);
+ void crcStartCalcI(CRCDriver *crcp, size_t n, const void *buf);
+#endif
+#if CRC_USE_MUTUAL_EXCLUSION == TRUE
+ void crcAcquireUnit(CRCDriver *crcp);
+ void crcReleaseUnit(CRCDriver *crcp);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_CRC */
+
+#endif /* _CRC_H_ */
+
+/** @} */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_ee24xx.h b/ChibiOS_16.1.5/community/os/hal/include/hal_ee24xx.h
new file mode 100644
index 0000000..ab12fd1
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_ee24xx.h
@@ -0,0 +1,64 @@
+/*
+ Copyright 2012 Uladzimir Pylinski aka barthess.
+ You may use this work without restrictions, as long as this notice is included.
+ The work is provided "as is" without warranty of any kind, neither express nor implied.
+*/
+
+#ifndef EE24XX_H
+#define EE24XX_H
+
+#include "hal.h"
+
+#if defined(HAL_USE_EEPROM) && HAL_USE_EEPROM && EEPROM_USE_EE24XX
+
+#define EEPROM_DEV_24XX 24
+
+/**
+ * @extends EepromFileConfig
+ */
+typedef struct {
+ _eeprom_file_config_data
+ /**
+ * Driver connected to IC.
+ */
+ I2CDriver *i2cp;
+ /**
+ * Address of IC on I2C bus.
+ */
+ i2caddr_t addr;
+ /**
+ * Pointer to write buffer. The safest size is (pagesize + 2)
+ */
+ uint8_t *write_buf;
+} I2CEepromFileConfig;
+
+/**
+ * @brief @p I2CEepromFileStream specific data.
+ */
+#define _eeprom_file_stream_data_i2c \
+ _eeprom_file_stream_data
+
+/**
+ * @extends EepromFileStream
+ *
+ * @brief EEPROM file stream driver class for I2C device.
+ */
+typedef struct {
+ const struct EepromFileStreamVMT *vmt;
+ _eeprom_file_stream_data_i2c
+ /* Overwritten parent data member. */
+ const I2CEepromFileConfig *cfg;
+} I2CEepromFileStream;
+
+
+/**
+ * Open I2C EEPROM IC as file and return pointer to the file stream object
+ * @note Fucntion allways successfully open file. All checking makes
+ * in read/write functions.
+ */
+#define I2CEepromFileOpen(efs, eepcfg, eepdev) \
+ EepromFileOpen((EepromFileStream *)efs, (EepromFileConfig *)eepcfg, eepdev);
+
+#endif /* #if defined(EEPROM_USE_EE24XX) && EEPROM_USE_EE24XX */
+
+#endif // EE24XX_H
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_ee25xx.h b/ChibiOS_16.1.5/community/os/hal/include/hal_ee25xx.h
new file mode 100644
index 0000000..fc2ad6f
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_ee25xx.h
@@ -0,0 +1,63 @@
+/*
+ Copyright 2012 Uladzimir Pylinski aka barthess.
+ You may use this work without restrictions, as long as this notice is included.
+ The work is provided "as is" without warranty of any kind, neither express nor implied.
+*/
+
+#ifndef EE25XX_H
+#define EE25XX_H
+
+#include "hal.h"
+
+#if defined(HAL_USE_EEPROM) && HAL_USE_EEPROM && EEPROM_USE_EE25XX
+
+#define EEPROM_DEV_25XX 25
+
+/**
+ * @extends EepromFileConfig
+ */
+typedef struct {
+ _eeprom_file_config_data
+ /**
+ * Driver connected to IC.
+ */
+ SPIDriver *spip;
+ /**
+ * Config associated with SPI driver.
+ */
+ const SPIConfig *spicfg;
+} SPIEepromFileConfig;
+
+/**
+ * @brief @p SPIEepromFileStream specific data.
+ */
+#define _eeprom_file_stream_data_spi \
+ _eeprom_file_stream_data
+
+/**
+ * @extends EepromFileStream
+ *
+ * @brief EEPROM file stream driver class for SPI device.
+ */
+typedef struct {
+ const struct EepromFileStreamVMT *vmt;
+ _eeprom_file_stream_data_spi
+ /* Overwritten parent data member. */
+ const SPIEepromFileConfig *cfg;
+} SPIEepromFileStream;
+
+/**
+ * Open SPI EEPROM IC as file and return pointer to the file stream object
+ * @note Fucntion allways successfully open file. All checking makes
+ * in read/write functions.
+ */
+EepromFileStream *SPIEepromFileOpen(SPIEepromFileStream *efs,
+ const SPIEepromFileConfig *eepcfg,
+ const EepromDevice *eepdev);
+
+#define SPIEepromFileOpen(efs, eepcfg, eepdev) \
+ EepromFileOpen((EepromFileStream *)efs, (EepromFileConfig *)eepcfg, eepdev);
+
+#endif /* #if defined(EEPROM_USE_EE25XX) && EEPROM_USE_EE25XX */
+
+#endif // EE25XX_H
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_eeprom.h b/ChibiOS_16.1.5/community/os/hal/include/hal_eeprom.h
new file mode 100644
index 0000000..cd05e14
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_eeprom.h
@@ -0,0 +1,143 @@
+/*
+ Copyright (c) 2013 Timon Wong
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+/*
+ Copyright 2012 Uladzimir Pylinski aka barthess.
+ You may use this work without restrictions, as long as this notice is included.
+ The work is provided "as is" without warranty of any kind, neither express nor implied.
+*/
+
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+#include "ch.h"
+#include "hal.h"
+
+#ifndef EEPROM_USE_EE25XX
+#define EEPROM_USE_EE25XX FALSE
+#endif
+
+#ifndef EEPROM_USE_EE24XX
+#define EEPROM_USE_EE24XX FALSE
+#endif
+
+#if (HAL_USE_EEPROM == TRUE) || defined(__DOXYGEN__)
+
+#if EEPROM_USE_EE25XX && EEPROM_USE_EE24XX
+#define EEPROM_TABLE_SIZE 2
+#elif EEPROM_USE_EE25XX || EEPROM_USE_EE24XX
+#define EEPROM_TABLE_SIZE 1
+#else
+#error "No EEPROM device selected!"
+#endif
+
+#if EEPROM_USE_EE25XX && !HAL_USE_SPI
+#error "25xx enabled but SPI driver is disabled!"
+#endif
+
+#if EEPROM_USE_EE24XX && !HAL_USE_I2C
+#error "24xx enabled but I2C driver is disabled!"
+#endif
+
+#define _eeprom_file_config_data \
+ /* Lower barrier of file in EEPROM memory array. */ \
+ uint32_t barrier_low; \
+ /* Higher barrier of file in EEPROM memory array. */ \
+ uint32_t barrier_hi; \
+ /* Size of memory array in bytes. */ \
+ uint32_t size; \
+ /* Size of single page in bytes. */ \
+ uint16_t pagesize; \
+ /* Time needed by IC for single byte/page writing. */ \
+ systime_t write_time;
+
+typedef uint32_t fileoffset_t;
+
+typedef struct {
+ _eeprom_file_config_data
+} EepromFileConfig;
+
+/**
+ * @brief @p EepromFileStream specific data.
+ */
+#define _eeprom_file_stream_data \
+ _base_sequential_stream_data \
+ uint32_t errors; \
+ uint32_t position; \
+
+/**
+ * @extends BaseFileStreamVMT
+ *
+ * @brief @p EepromFileStream virtual methods table.
+ */
+struct EepromFileStreamVMT {
+ _file_stream_methods
+};
+
+/**
+ * @extends BaseFileStream
+ *
+ * @brief EEPROM file stream driver class.
+ * @details This class extends @p BaseFileStream by adding some fields.
+ */
+typedef struct {
+ /** @brief Virtual Methods Table.*/
+ const struct EepromFileStreamVMT *vmt;
+ _eeprom_file_stream_data
+ /** pointer to config object, must be overwritten by all derived classes.*/
+ const EepromFileConfig *cfg;
+} EepromFileStream;
+
+/**
+ * @brief Low level device descriptor.
+ */
+typedef struct {
+ const uint8_t id;
+ const struct EepromFileStreamVMT *efsvmt;
+} EepromDevice;
+
+const EepromDevice *EepromFindDevice(uint8_t id);
+
+EepromFileStream *EepromFileOpen(EepromFileStream *efs,
+ const EepromFileConfig *eepcfg,
+ const EepromDevice *eepdev);
+
+uint8_t EepromReadByte(EepromFileStream *efs);
+uint16_t EepromReadHalfword(EepromFileStream *efs);
+uint32_t EepromReadWord(EepromFileStream *efs);
+size_t EepromWriteByte(EepromFileStream *efs, uint8_t data);
+size_t EepromWriteHalfword(EepromFileStream *efs, uint16_t data);
+size_t EepromWriteWord(EepromFileStream *efs, uint32_t data);
+
+msg_t eepfs_getsize(void *ip);
+msg_t eepfs_getposition(void *ip);
+msg_t eepfs_lseek(void *ip, fileoffset_t offset);
+msg_t eepfs_close(void *ip);
+msg_t eepfs_geterror(void *ip);
+msg_t eepfs_put(void *ip, uint8_t b);
+msg_t eepfs_get(void *ip);
+
+#include "hal_ee24xx.h"
+#include "hal_ee25xx.h"
+
+#endif /* #if defined(HAL_USE_EEPROM) && HAL_USE_EEPROM */
+#endif /* __EEPROM_H__ */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_eicu.h b/ChibiOS_16.1.5/community/os/hal/include/hal_eicu.h
new file mode 100644
index 0000000..d4b0ed2
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_eicu.h
@@ -0,0 +1,191 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 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.
+*/
+/*
+ Rewritten by Emil Fresk (1/5 - 2014) for extended input capture
+ functionality. And fix for spurious callbacks in the interrupt handler.
+*/
+/*
+ Improved by Uladzimir Pylinsky aka barthess (1/3 - 2015) for support of
+ 32-bit timers and timers with single capture/compare channels.
+*/
+
+#ifndef _EICU_H_
+#define _EICU_H_
+
+#if (HAL_USE_EICU == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ EICU_UNINIT, /* Not initialized. */
+ EICU_STOP, /* Stopped. */
+ EICU_READY, /* Ready. */
+ EICU_WAITING, /* Waiting for first edge. */
+ EICU_ACTIVE, /* Active cycle phase. */
+ EICU_IDLE /* Idle cycle phase. */
+} eicustate_t;
+
+/**
+ * @brief Channel state machine possible states.
+ */
+typedef enum {
+ EICU_CH_IDLE, /* Idle cycle phase. */
+ EICU_CH_ACTIVE /* Active cycle phase. */
+} eicuchannelstate_t;
+
+/**
+ * @brief EICU channel selection definition
+ */
+typedef enum {
+ EICU_CHANNEL_1,
+ EICU_CHANNEL_2,
+ EICU_CHANNEL_3,
+ EICU_CHANNEL_4,
+ EICU_CHANNEL_ENUM_END
+} eicuchannel_t;
+
+/**
+ * @brief Type of a structure representing an EICU driver.
+ */
+typedef struct EICUDriver EICUDriver;
+
+/**
+ * @brief EICU notification callback type.
+ *
+ * @param[in] eicup Pointer to a EICUDriver object
+ * @param[in] channel EICU channel that fired the interrupt
+ * @param[in] width Pulse width
+ * @param[in] period Pulse period
+ */
+typedef void (*eicucallback_t)(EICUDriver *eicup, eicuchannel_t channel,
+ uint32_t width, uint32_t period);
+
+#include "hal_eicu_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Enables the extended input capture.
+ *
+ * @param[in] eicup Pointer to the @p EICUDriver object
+ *
+ * @iclass
+ */
+#define eicuEnableI(eicup) eicu_lld_enable(eicup)
+
+/**
+ * @brief Disables the extended input capture.
+ *
+ * @param[in] eicup Pointer to the @p EICUDriver object
+ *
+ * @iclass
+ */
+#define eicuDisableI(eicup) eicu_lld_disable(eicup)
+/** @} */
+
+/**
+ * @name Low Level driver helper macros
+ * @{
+ */
+/**
+ * @brief Common ISR code, EICU PWM width event.
+ *
+ * @param[in] eicup Pointer to the @p EICUDriver object
+ * @param[in] channel The timer channel that fired the interrupt.
+ *
+ * @notapi
+ */
+static inline void _eicu_isr_invoke_pwm_width_cb(EICUDriver *eicup,
+ eicuchannel_t channel) {
+ if (eicup->state != EICU_WAITING) {
+ eicup->state = EICU_IDLE;
+ eicup->config->iccfgp[channel]->capture_cb(eicup, channel, 0, 0);
+ }
+}
+
+/**
+ * @brief Common ISR code, EICU PWM period event.
+ *
+ * @param[in] eicup Pointer to the @p EICUDriver object
+ * @param[in] channel The timer channel that fired the interrupt.
+ *
+ * @notapi
+ */
+static inline void _eicu_isr_invoke_pwm_period_cb(EICUDriver *eicup,
+ eicuchannel_t channel) {
+ eicustate_t previous_state = eicup->state;
+ eicup->state = EICU_ACTIVE;
+ if (previous_state != EICU_WAITING)
+ eicup->channel[channel].config->capture_cb(eicup, channel, 0, 0);
+}
+
+/**
+ * @brief Common ISR code, EICU timer overflow event.
+ *
+ * @param[in] eicup Pointer to the @p EICUDriver object
+ *
+ * @notapi
+ */
+#define _eicu_isr_invoke_overflow_cb(icup) do { \
+ (eicup)->config->overflow_cb(eicup, 0, 0, 0); \
+} while (0)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void eicuInit(void);
+ void eicuObjectInit(EICUDriver *eicup);
+ void eicuStart(EICUDriver *eicup, const EICUConfig *config);
+ void eicuStop(EICUDriver *eicup);
+ void eicuEnable(EICUDriver *eicup);
+ void eicuDisable(EICUDriver *eicup);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_EICU */
+
+#endif /* _EICU_H_ */
+
+/** @} */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_nand.h b/ChibiOS_16.1.5/community/os/hal/include/hal_nand.h
new file mode 100644
index 0000000..d5a1c04
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_nand.h
@@ -0,0 +1,137 @@
+/*
+ ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
+
+ 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 nand.h
+ * @brief NAND Driver macros and structures.
+ *
+ * @addtogroup NAND
+ * @{
+ */
+
+#ifndef _NAND_H_
+#define _NAND_H_
+
+#if (HAL_USE_NAND == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*
+ * Standard NAND flash commands
+ */
+#define NAND_CMD_READ0 0x00
+#define NAND_CMD_RNDOUT 0x05
+#define NAND_CMD_PAGEPROG 0x10
+#define NAND_CMD_READ0_CONFIRM 0x30
+#define NAND_CMD_READOOB 0x50
+#define NAND_CMD_ERASE 0x60
+#define NAND_CMD_STATUS 0x70
+#define NAND_CMD_STATUS_MULTI 0x71
+#define NAND_CMD_WRITE 0x80
+#define NAND_CMD_RNDIN 0x85
+#define NAND_CMD_READID 0x90
+#define NAND_CMD_ERASE_CONFIRM 0xD0
+#define NAND_CMD_RESET 0xFF
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+/**
+ * @brief Enables the mutual exclusion APIs on the NAND.
+ */
+#if !defined(NAND_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define NAND_USE_MUTUAL_EXCLUSION FALSE
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+#if NAND_USE_MUTUAL_EXCLUSION && !CH_CFG_USE_MUTEXES && !CH_CFG_USE_SEMAPHORES
+#error "NAND_USE_MUTUAL_EXCLUSION requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ NAND_UNINIT = 0, /**< Not initialized. */
+ NAND_STOP = 1, /**< Stopped. */
+ NAND_READY = 2, /**< Ready. */
+ NAND_PROGRAM = 3, /**< Programming in progress. */
+ NAND_ERASE = 4, /**< Erasing in progress. */
+ NAND_WRITE = 5, /**< Writing to NAND buffer. */
+ NAND_READ = 6, /**< Reading from NAND. */
+ NAND_DMA_TX = 7, /**< DMA transmitting. */
+ NAND_DMA_RX = 8, /**< DMA receiving. */
+} nandstate_t;
+
+/**
+ * @brief Type of a structure representing a NAND driver.
+ */
+typedef struct NANDDriver NANDDriver;
+
+#include "hal_nand_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void nandInit(void);
+ void nandObjectInit(NANDDriver *nandp);
+ void nandStart(NANDDriver *nandp, const NANDConfig *config, bitmap_t *bb_map);
+ void nandStop(NANDDriver *nandp);
+ void nandReadPageWhole(NANDDriver *nandp, uint32_t block, uint32_t page,
+ uint8_t *data, size_t datalen);
+ void nandMarkBad(NANDDriver *nandp, uint32_t block);
+ void nandReadPageData(NANDDriver *nandp, uint32_t block, uint32_t page,
+ uint8_t *data, size_t datalen, uint32_t *ecc);
+ void nandReadPageSpare(NANDDriver *nandp, uint32_t block, uint32_t page,
+ uint8_t *spare, size_t sparelen);
+ uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block, uint32_t page,
+ const uint8_t *data, size_t datalen);
+ uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block, uint32_t page,
+ const uint8_t *data, size_t datalen, uint32_t *ecc);
+ uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block, uint32_t page,
+ const uint8_t *spare, size_t sparelen);
+ uint8_t nandReadBadMark(NANDDriver *nandp, uint32_t block, uint32_t page);
+ uint8_t nandErase(NANDDriver *nandp, uint32_t block);
+ bool nandIsBad(NANDDriver *nandp, uint32_t block);
+#if NAND_USE_MUTUAL_EXCLUSION
+ void nandAcquireBus(NANDDriver *nandp);
+ void nandReleaseBus(NANDDriver *nandp);
+#endif /* NAND_USE_MUTUAL_EXCLUSION */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_NAND */
+
+#endif /* _NAND_H_ */
+
+/** @} */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_onewire.h b/ChibiOS_16.1.5/community/os/hal/include/hal_onewire.h
new file mode 100644
index 0000000..9fb5be2
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_onewire.h
@@ -0,0 +1,366 @@
+/*
+ ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
+
+ 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 onewire.h
+ * @brief 1-wire Driver macros and structures.
+ *
+ * @addtogroup onewire
+ * @{
+ */
+
+#ifndef _ONEWIRE_H_
+#define _ONEWIRE_H_
+
+#if (HAL_USE_ONEWIRE == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+/**
+ * @brief Enable synthetic test for 'search ROM' procedure.
+ * @note Only for debugging/testing!
+ */
+#define ONEWIRE_SYNTH_SEARCH_TEST FALSE
+
+/**
+ * @brief Aliases for 1-wire protocol.
+ */
+#define ONEWIRE_CMD_READ_ROM 0x33
+#define ONEWIRE_CMD_SEARCH_ROM 0xF0
+#define ONEWIRE_CMD_MATCH_ROM 0x55
+#define ONEWIRE_CMD_SKIP_ROM 0xCC
+#define ONEWIRE_CMD_CONVERT_TEMP 0x44
+#define ONEWIRE_CMD_READ_SCRATCHPAD 0xBE
+
+/**
+ * @brief How many bits will be used for transaction length storage.
+ */
+#define ONEWIRE_REG_BYTES_WIDTH 16U
+
+/**
+ * @brief Precalculated maximum transaction length.
+ */
+#define ONEWIRE_MAX_TRANSACTION_LEN ((1U << ONEWIRE_REG_BYTES_WIDTH) - 1U)
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !HAL_USE_PWM
+#error "1-wire Driver requires HAL_USE_PWM"
+#endif
+
+#if !HAL_USE_PAL
+#error "1-wire Driver requires HAL_USE_PAL"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+#if ONEWIRE_USE_STRONG_PULLUP
+/**
+ * @brief 1-wire strong pull up assert callback type.
+ */
+typedef void (*onewire_pullup_assert_t)(void);
+
+/**
+ * @brief 1-wire strong pull up release callback type.
+ */
+typedef void (*onewire_pullup_release_t)(void);
+#endif /* ONEWIRE_USE_STRONG_PULLUP */
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ ONEWIRE_UNINIT = 0, /**< Not initialized. */
+ ONEWIRE_STOP = 1, /**< Stopped. */
+ ONEWIRE_READY = 2, /**< Ready. */
+#if ONEWIRE_USE_STRONG_PULLUP
+ ONEWIRE_PULL_UP /**< Pull up asserted. */
+#endif
+} onewire_state_t;
+
+#if ONEWIRE_USE_SEARCH_ROM
+/**
+ * @brief Search ROM procedure possible state.
+ */
+typedef enum {
+ ONEWIRE_SEARCH_ROM_SUCCESS = 0, /**< ROM successfully discovered. */
+ ONEWIRE_SEARCH_ROM_LAST = 1, /**< Last ROM successfully discovered. */
+ ONEWIRE_SEARCH_ROM_ERROR = 2 /**< Error happened during search. */
+} search_rom_result_t;
+
+/**
+ * @brief Search ROM procedure iteration enum.
+ */
+typedef enum {
+ ONEWIRE_SEARCH_ROM_FIRST = 0, /**< First search run. */
+ ONEWIRE_SEARCH_ROM_NEXT = 1 /**< Next search run. */
+} search_iteration_t;
+#endif /* ONEWIRE_USE_SEARCH_ROM */
+
+/**
+ * @brief Driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief Pointer to @p PWM driver used for communication.
+ */
+ PWMDriver *pwmd;
+ /**
+ * @brief Pointer to configuration structure for underlying PWM driver.
+ * @note It is NOT constant because 1-wire driver needs to change them
+ * during normal functioning.
+ */
+ PWMConfig *pwmcfg;
+ /**
+ * @brief Active logic level for master channel.
+ * @details Just set it to @p PWM_OUTPUT_ACTIVE_LOW when 1-wire bus
+ * connected to direct (not complementary) output of the timer.
+ * In opposite case you need to check documentation to choose
+ * correct value.
+ */
+ pwmmode_t pwmmode;
+ /**
+ * @brief Number of PWM channel used as master pulse generator.
+ */
+ size_t master_channel;
+ /**
+ * @brief Number of PWM channel used as sample interrupt generator.
+ */
+ size_t sample_channel;
+ /**
+ * @brief Port Identifier.
+ * @details This type can be a scalar or some kind of pointer, do not make
+ * any assumption about it, use the provided macros when populating
+ * variables of this type.
+ */
+ ioportid_t port;
+ /**
+ * @brief Digital I/O port pad.
+ */
+ ioportmask_t pad;
+#if defined(STM32F1XX)
+ /**
+ * @brief Digital I/O mode for idle bus.
+ * @details This is a kind of workaround against F1x realization of alternate
+ * function. Alternate function mode will be activated only
+ * when you starts appropriate peripheral.
+ */
+ iomode_t pad_mode_idle;
+#endif
+ /**
+ * @brief Digital I/O mode for active bus.
+ */
+ iomode_t pad_mode_active;
+#if ONEWIRE_USE_STRONG_PULLUP
+ /**
+ * @brief Pointer to function asserting of strong pull up.
+ */
+ onewire_pullup_assert_t pullup_assert;
+ /**
+ * @brief Pointer to function releasing of strong pull up.
+ */
+ onewire_pullup_release_t pullup_release;
+#endif
+} onewireConfig;
+
+#if ONEWIRE_USE_SEARCH_ROM
+/**
+ * @brief Search ROM registry. Contains small variables used
+ * in 'search ROM' procedure.
+ */
+typedef struct {
+ /**
+ * @brief Bool flag. True when bus has single slave device.
+ */
+ uint32_t single_device: 1;
+ /**
+ * @brief Search iteration (@p search_iteration_t enum).
+ */
+ uint32_t search_iter: 1;
+ /**
+ * @brief Result of discovery procedure (@p search_rom_result_t enum).
+ */
+ uint32_t result: 2;
+ /**
+ * @brief One of 3 steps of bit discovery.
+ * @details 0 - direct, 1 - complemented, 2 - generated by master.
+ */
+ uint32_t bit_step: 2;
+ /**
+ * @brief Values acquired during bit discovery.
+ */
+ uint32_t bit_buf: 2;
+ /**
+ * @brief Currently processing ROM bit.
+ * @note Must be big enough to store number 64.
+ */
+ uint32_t rombit: 7;
+ /**
+ * @brief Total device count discovered on bus.
+ * @note Maximum 256.
+ */
+ uint32_t devices_found: 8;
+} search_rom_reg_t;
+
+/**
+ * @brief Helper structure for 'search ROM' procedure
+ */
+typedef struct {
+ /**
+ * @brief Search ROM registry.
+ */
+ search_rom_reg_t reg;
+ /**
+ * @brief Pointer to buffer with currently discovering ROM
+ */
+ uint8_t *retbuf;
+ /**
+ * @brief Previously discovered ROM.
+ */
+ uint8_t prev_path[8];
+ /**
+ * @brief Last zero turn branch.
+ * @note Negative values use to point out of device tree's root.
+ */
+ int8_t last_zero_branch;
+ /**
+ * @brief Previous zero turn branch.
+ * @note Negative values use to point out of device tree's root.
+ */
+ int8_t prev_zero_branch;
+} onewire_search_rom_t;
+#endif /* ONEWIRE_USE_SEARCH_ROM */
+
+/**
+ * @brief Onewire registry. Some small variables combined
+ * in single machine word to save RAM.
+ */
+typedef struct {
+#if ONEWIRE_USE_STRONG_PULLUP
+ /**
+ * @brief This flag will be asserted by driver to signalizes
+ * ISR part when strong pull up needed.
+ */
+ uint32_t need_pullup: 1;
+#endif
+ /**
+ * @brief Bool flag. If @p true than at least one device presence on bus.
+ */
+ uint32_t slave_present: 1;
+ /**
+ * @brief Driver internal state (@p onewire_state_t enum).
+ */
+ uint32_t state: 2;
+ /**
+ * @brief Bit number in currently receiving/sending byte.
+ * @note Must be big enough to store 8.
+ */
+ uint32_t bit: 4;
+ /**
+ * @brief Bool flag for premature timer stop prevention.
+ */
+ uint32_t final_timeslot: 1;
+ /**
+ * @brief Bytes number to be processing in current transaction.
+ */
+ uint32_t bytes: ONEWIRE_REG_BYTES_WIDTH;
+} onewire_reg_t;
+
+/**
+ * @brief Structure representing an 1-wire driver.
+ */
+typedef struct {
+ /**
+ * @brief Onewire registry.
+ */
+ onewire_reg_t reg;
+ /**
+ * @brief Onewire config.
+ */
+ const onewireConfig *config;
+ /**
+ * @brief Pointer to I/O data buffer.
+ */
+ uint8_t *buf;
+#if ONEWIRE_USE_SEARCH_ROM
+ /**
+ * @brief Search ROM helper structure.
+ */
+ onewire_search_rom_t search_rom;
+#endif /* ONEWIRE_USE_SEARCH_ROM */
+ /**
+ * @brief Thread waiting for I/O completion.
+ */
+ thread_reference_t thread;
+} onewireDriver;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+extern onewireDriver OWD1;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void onewireInit(void);
+ void onewireObjectInit(onewireDriver *owp);
+ void onewireStart(onewireDriver *owp, const onewireConfig *config);
+ void onewireStop(onewireDriver *owp);
+ bool onewireReset(onewireDriver *owp);
+ void onewireRead(onewireDriver *owp, uint8_t *rxbuf, size_t rxbytes);
+ uint8_t onewireCRC(const uint8_t *buf, size_t len);
+ void onewireWrite(onewireDriver *owp, uint8_t *txbuf,
+ size_t txbytes, systime_t pullup_time);
+#if ONEWIRE_USE_SEARCH_ROM
+ size_t onewireSearchRom(onewireDriver *owp,
+ uint8_t *result, size_t max_rom_cnt);
+#endif /* ONEWIRE_USE_SEARCH_ROM */
+#if ONEWIRE_SYNTH_SEARCH_TEST
+ void _synth_ow_write_bit(onewireDriver *owp, ioline_t bit);
+ ioline_t _synth_ow_read_bit(void);
+ void synthSearchRomTest(onewireDriver *owp);
+#endif /* ONEWIRE_SYNTH_SEARCH_TEST */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ONEWIRE */
+
+#endif /* _ONEWIRE_H_ */
+
+/** @} */
+
+
+
+
+
+
+
+
+
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_qei.h b/ChibiOS_16.1.5/community/os/hal/include/hal_qei.h
new file mode 100644
index 0000000..92f03fc
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_qei.h
@@ -0,0 +1,130 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 Martino Migliavacca
+
+ 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 hal_qei.h
+ * @brief QEI Driver macros and structures.
+ *
+ * @addtogroup QEI
+ * @{
+ */
+
+#ifndef HAL_QEI_H
+#define HAL_QEI_H
+
+#if (HAL_USE_QEI == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ QEI_UNINIT = 0, /**< Not initialized. */
+ QEI_STOP = 1, /**< Stopped. */
+ QEI_READY = 2, /**< Ready. */
+ QEI_ACTIVE = 3, /**< Active. */
+} qeistate_t;
+
+/**
+ * @brief Type of a structure representing an QEI driver.
+ */
+typedef struct QEIDriver QEIDriver;
+
+/**
+ * @brief QEI notification callback type.
+ *
+ * @param[in] qeip pointer to a @p QEIDriver object
+ */
+typedef void (*qeicallback_t)(QEIDriver *qeip);
+
+#include "hal_qei_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] qeip pointer to the @p QEIDriver object
+ *
+ * @iclass
+ */
+#define qeiEnableI(qeip) qei_lld_enable(qeip)
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] qeip pointer to the @p QEIDriver object
+ *
+ * @iclass
+ */
+#define qeiDisableI(qeip) qei_lld_disable(qeip)
+
+/**
+ * @brief Returns the counter value.
+ *
+ * @param[in] qeip pointer to the @p QEIDriver object
+ * @return The current counter value.
+ *
+ * @iclass
+ */
+#define qeiGetCountI(qeip) qei_lld_get_count(qeip)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void qeiInit(void);
+ void qeiObjectInit(QEIDriver *qeip);
+ void qeiStart(QEIDriver *qeip, const QEIConfig *config);
+ void qeiStop(QEIDriver *qeip);
+ void qeiEnable(QEIDriver *qeip);
+ void qeiDisable(QEIDriver *qeip);
+ qeicnt_t qeiGetCount(QEIDriver *qeip);
+ qeidelta_t qeiUpdate(QEIDriver *qeip);
+ qeidelta_t qeiUpdateI(QEIDriver *qeip);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_QEI == TRUE */
+
+#endif /* HAL_QEI_H */
+
+/** @} */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_rng.h b/ChibiOS_16.1.5/community/os/hal/include/hal_rng.h
new file mode 100644
index 0000000..0e3c484
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_rng.h
@@ -0,0 +1,136 @@
+/*
+ RNG for ChibiOS - Copyright (C) 2016 Stephane D'Alu
+
+ 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.
+*/
+
+#ifndef _RNG_H_
+#define _RNG_H_
+
+#if (HAL_USE_RNG == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+
+/**
+ * @brief Enables the @p rngAcquireBus() and @p rngReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(RNG_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define RNG_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ RNG_UNINIT, /* Not initialized. */
+ RNG_STOP, /* Stopped. */
+ RNG_READY, /* Ready. */
+} rngstate_t;
+
+#include "hal_rng_lld.h"
+
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Low level driver helper macros
+ * @{
+ */
+
+/**
+ * @brief Wakes up the waiting thread.
+ *
+ * @param[in] rngp pointer to the @p RNGDriver object
+ *
+ * @notapi
+ */
+#define _rng_wakeup_isr(rngp) { \
+ osalSysLockFromISR(); \
+ osalThreadResumeI(&(rngp)->thread, MSG_OK); \
+ osalSysUnlockFromISR(); \
+}
+
+/**
+ * @brief Common ISR code.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] rngp pointer to the @p RNGDriver object
+ *
+ * @notapi
+ */
+#define _rng_isr_code(rngp, rng) { \
+ if ((rngp)->config->end_cb) { \
+ (rngp)->state = RNG_COMPLETE; \
+ (rngp)->config->end_cb(rngp, rng); \
+ if ((rngp)->state == RNG_COMPLETE) \
+ (rngp)->state = RNG_READY; \
+ } \
+ else \
+ (rngp)->state = RNG_READY; \
+ _rng_wakeup_isr(rngp); \
+}
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void rngInit(void);
+ void rngObjectInit(RNGDriver *rngp);
+ void rngStart(RNGDriver *rngp, const RNGConfig *config);
+ void rngStop(RNGDriver *rngp);
+ msg_t rngWriteI(RNGDriver *rngp, uint8_t *buf, size_t n, systime_t timeout);
+ msg_t rngWrite(RNGDriver *rngp, uint8_t *buf, size_t n, systime_t timeout);
+#if RNG_USE_MUTUAL_EXCLUSION == TRUE
+ void rngAcquireUnit(RNGDriver *rngp);
+ void rngReleaseUnit(RNGDriver *rngp);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_RNG */
+
+#endif /* _RNG_H_ */
+
+/** @} */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_timcap.h b/ChibiOS_16.1.5/community/os/hal/include/hal_timcap.h
new file mode 100644
index 0000000..bd43dd1
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_timcap.h
@@ -0,0 +1,206 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file timcap.h
+ * @brief TIMCAP Driver macros and structures.
+ *
+ * @addtogroup TIMCAP
+ * @{
+ */
+
+#ifndef _TIMCAP_H_
+#define _TIMCAP_H_
+
+#include "ch.h"
+#include "hal.h"
+
+#if (HAL_USE_TIMCAP == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ TIMCAP_UNINIT = 0, /**< Not initialized. */
+ TIMCAP_STOP = 1, /**< Stopped. */
+ TIMCAP_READY = 2, /**< Ready. */
+ TIMCAP_WAITING = 3, /**< Waiting first edge. */
+ TIMCAP_ACTIVE = 4, /**< Active cycle phase. */
+ TIMCAP_IDLE = 5, /**< Idle cycle phase. */
+} timcapstate_t;
+
+/**
+ * @brief Type of a structure representing an TIMCAP driver.
+ */
+typedef struct TIMCAPDriver TIMCAPDriver;
+
+
+/**
+ * @brief TIMCAP notification callback type.
+ *
+ * @param[in] timcapp pointer to a @p TIMCAPDriver object
+ */
+typedef void (*timcapcallback_t)(TIMCAPDriver *timcapp);
+
+#include "hal_timcap_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] timcapp pointer to the @p TIMCAPDriver object
+ *
+ * @iclass
+ */
+#define timcapEnableI(timcapp) timcap_lld_enable(timcapp)
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] timcapp pointer to the @p TIMCAPDriver object
+ *
+ * @iclass
+ */
+#define timcapDisableI(timcapp) timcap_lld_disable(timcapp)
+
+
+
+
+/** @} */
+
+/**
+ * @name Low Level driver helper macros
+ * @{
+ */
+
+
+/**
+ * @brief Common ISR code, TIMCAP channel 1 event.
+ *
+ * @param[in] timcapp pointer to the @p TIMCAPDriver object
+ *
+ * @notapi
+ */
+#define _timcap_isr_invoke_channel1_cb(timcapp) { \
+ timcapstate_t previous_state = (timcapp)->state; \
+ (timcapp)->state = TIMCAP_ACTIVE; \
+ if (previous_state != TIMCAP_WAITING) \
+ (timcapp)->config->capture_cb_array[0](timcapp); \
+}
+
+/**
+ * @brief Common ISR code, TIMCAP channel 2 event.
+ *
+ * @param[in] timcapp pointer to the @p TIMCAPDriver object
+ *
+ * @notapi
+ */
+#define _timcap_isr_invoke_channel2_cb(timcapp) { \
+ timcapstate_t previous_state = (timcapp)->state; \
+ (timcapp)->state = TIMCAP_ACTIVE; \
+ if (previous_state != TIMCAP_WAITING) \
+ (timcapp)->config->capture_cb_array[1](timcapp); \
+}
+
+/**
+ * @brief Common ISR code, TIMCAP channel 3 event.
+ *
+ * @param[in] timcapp pointer to the @p TIMCAPDriver object
+ *
+ * @notapi
+ */
+#define _timcap_isr_invoke_channel3_cb(timcapp) { \
+ timcapstate_t previous_state = (timcapp)->state; \
+ (timcapp)->state = TIMCAP_ACTIVE; \
+ if (previous_state != TIMCAP_WAITING) \
+ (timcapp)->config->capture_cb_array[2](timcapp); \
+}
+
+/**
+ * @brief Common ISR code, TIMCAP channel 4 event.
+ *
+ * @param[in] timcapp pointer to the @p TIMCAPDriver object
+ *
+ * @notapi
+ */
+#define _timcap_isr_invoke_channel4_cb(timcapp) { \
+ timcapstate_t previous_state = (timcapp)->state; \
+ (timcapp)->state = TIMCAP_ACTIVE; \
+ if (previous_state != TIMCAP_WAITING) \
+ (timcapp)->config->capture_cb_array[3](timcapp); \
+}
+
+/**
+ * @brief Common ISR code, TIMCAP timer overflow event.
+ *
+ * @param[in] timcapp pointer to the @p TIMCAPDriver object
+ *
+ * @notapi
+ */
+#define _timcap_isr_invoke_overflow_cb(timcapp) { \
+ (timcapp)->config->overflow_cb(timcapp); \
+}
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void timcapInit(void);
+ void timcapObjectInit(TIMCAPDriver *timcapp);
+ void timcapStart(TIMCAPDriver *timcapp, const TIMCAPConfig *config);
+ void timcapStop(TIMCAPDriver *timcapp);
+ void timcapEnable(TIMCAPDriver *timcapp);
+ void timcapDisable(TIMCAPDriver *timcapp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_TIMCAP */
+
+#endif /* _TIMCAP_H_ */
+
+/** @} */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_usb_hid.h b/ChibiOS_16.1.5/community/os/hal/include/hal_usb_hid.h
new file mode 100644
index 0000000..2a2d73a
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_usb_hid.h
@@ -0,0 +1,510 @@
+/*
+ ChibiOS - Copyright (C) 2016 Jonathan Struebel
+
+ 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 hal_usb_hid.h
+ * @brief USB HID macros and structures.
+ *
+ * @addtogroup USB_HID
+ * @{
+ */
+
+#ifndef HAL_USB_HID_H
+#define HAL_USB_HID_H
+
+#if (HAL_USE_USB_HID == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name HID specific messages.
+ * @{
+ */
+#define HID_GET_REPORT 0x01U
+#define HID_GET_IDLE 0x02U
+#define HID_GET_PROTOCOL 0x03U
+#define HID_SET_REPORT 0x09U
+#define HID_SET_IDLE 0x0AU
+#define HID_SET_PROTOCOL 0x0BU
+/** @} */
+
+/**
+ * @name HID classes
+ * @{
+ */
+#define HID_INTERFACE_CLASS 0x03U
+/** @} */
+
+/**
+ * @name HID subclasses
+ * @{
+ */
+#define HID_BOOT_INTERFACE 0x01U
+/** @} */
+
+/**
+ * @name HID descriptors
+ * @{
+ */
+#define USB_DESCRIPTOR_HID 0x21U
+#define HID_REPORT 0x22U
+#define HID_PHYSICAL 0x23U
+/** @} */
+
+/**
+ * @name HID Report items
+ * @{
+ */
+#define HID_REPORT_USAGE_PAGE 0x04
+#define HID_REPORT_USAGE 0x08
+#define HID_REPORT_LOGICAL_MINIMUM 0x14
+#define HID_REPORT_USAGE_MINIMUM 0x18
+#define HID_REPORT_LOGICAL_MAXIMUM 0x24
+#define HID_REPORT_USAGE_MAXIMUM 0x28
+#define HID_REPORT_REPORT_SIZE 0x74
+#define HID_REPORT_INPUT 0x80
+#define HID_REPORT_REPORT_COUNT 0x94
+#define HID_REPORT_COLLECTION 0xA0
+#define HID_REPORT_END_COLLECTION 0xC0
+/** @} */
+
+/**
+ * @name HID Collection item definitions
+ * @{
+ */
+#define HID_COLLECTION_PHYSICAL 0x00
+#define HID_COLLECTION_APPLICATION 0x01
+#define HID_COLLECTION_LOGICAL 0x02
+#define HID_COLLECTION_REPORT 0x03
+#define HID_COLLECTION_NAMED_ARRAY 0x04
+#define HID_COLLECTION_USAGE_SWITCH 0x05
+#define HID_COLLECTION_USAGE_MODIFIER 0x06
+/** @} */
+
+/**
+ * @name HID Usage Page item definitions
+ * @{
+ */
+#define HID_USAGE_PAGE_GENERIC_DESKTOP 0x01
+#define HID_USAGE_PAGE_SIMULATION 0x02
+#define HID_USAGE_PAGE_VR 0x03
+#define HID_USAGE_PAGE_SPORT 0x04
+#define HID_USAGE_PAGE_GAME 0x05
+#define HID_USAGE_PAGE_GENERIC_DEVICE 0x06
+#define HID_USAGE_PAGE_KEYBOARD_KEYPAD 0x07
+#define HID_USAGE_PAGE_LEDS 0x08
+#define HID_USAGE_PAGE_BUTTON 0x09
+#define HID_USAGE_PAGE_ORDINAL 0x0A
+#define HID_USAGE_PAGE_TELEPHONY 0x0B
+#define HID_USAGE_PAGE_CONSUMER 0x0C
+#define HID_USAGE_PAGE_DIGITIZER 0x0D
+#define HID_USAGE_PAGE_PID 0x0F
+#define HID_USAGE_PAGE_UNICODE 0x10
+/** @} */
+
+/**
+ * @name HID Usage item definitions
+ * @{
+ */
+#define HID_USAGE_ALPHANUMERIC_DISPLAY 0x14
+#define HID_USAGE_MEDICAL_INSTRUMENTS 0x40
+#define HID_USAGE_MONITOR_PAGE1 0x80
+#define HID_USAGE_MONITOR_PAGE2 0x81
+#define HID_USAGE_MONITOR_PAGE3 0x82
+#define HID_USAGE_MONITOR_PAGE4 0x83
+#define HID_USAGE_POWER_PAGE1 0x84
+#define HID_USAGE_POWER_PAGE2 0x85
+#define HID_USAGE_POWER_PAGE3 0x86
+#define HID_USAGE_POWER_PAGE4 0x87
+#define HID_USAGE_BAR_CODE_SCANNER_PAGE 0x8C
+#define HID_USAGE_SCALE_PAGE 0x8D
+#define HID_USAGE_MSR_PAGE 0x8E
+#define HID_USAGE_CAMERA_PAGE 0x90
+#define HID_USAGE_ARCADE_PAGE 0x91
+
+#define HID_USAGE_POINTER 0x01
+#define HID_USAGE_MOUSE 0x02
+#define HID_USAGE_JOYSTICK 0x04
+#define HID_USAGE_GAMEPAD 0x05
+#define HID_USAGE_KEYBOARD 0x06
+#define HID_USAGE_KEYPAD 0x07
+#define HID_USAGE_MULTIAXIS_CONTROLLER 0x08
+
+#define HID_USAGE_BUTTON1 0x01
+#define HID_USAGE_BUTTON2 0x02
+#define HID_USAGE_BUTTON3 0x03
+#define HID_USAGE_BUTTON4 0x04
+#define HID_USAGE_BUTTON5 0x05
+#define HID_USAGE_BUTTON6 0x06
+#define HID_USAGE_BUTTON7 0x07
+#define HID_USAGE_BUTTON8 0x08
+
+#define HID_USAGE_X 0x30
+#define HID_USAGE_Y 0x31
+#define HID_USAGE_Z 0x32
+#define HID_USAGE_RX 0x33
+#define HID_USAGE_RY 0x34
+#define HID_USAGE_RZ 0x35
+#define HID_USAGE_VX 0x40
+#define HID_USAGE_VY 0x41
+#define HID_USAGE_VZ 0x42
+#define HID_USAGE_VBRX 0x43
+#define HID_USAGE_VBRY 0x44
+#define HID_USAGE_VBRZ 0x45
+#define HID_USAGE_VNO 0x46
+/** @} */
+
+/**
+ * @name HID Input item definitions.
+ * @{
+ */
+#define HID_INPUT_DATA_VAR_ABS 0x02
+#define HID_INPUT_CNST_VAR_ABS 0x03
+#define HID_INPUT_DATA_VAR_REL 0x06
+/** @} */
+
+/**
+ * @name Helper macros for USB HID descriptors
+ * @{
+ */
+/*
+ * @define HID Descriptor size.
+ */
+#define USB_DESC_HID_SIZE 9U
+
+/**
+ * @brief HID Descriptor helper macro.
+ * @note This macro can only be used with a single HID report descriptor
+ */
+#define USB_DESC_HID(bcdHID, bCountryCode, bNumDescriptors, \
+ bDescriptorType, wDescriptorLength) \
+ USB_DESC_BYTE(USB_DESC_HID_SIZE), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_HID), \
+ USB_DESC_BCD(bcdHID), \
+ USB_DESC_BYTE(bCountryCode), \
+ USB_DESC_BYTE(bNumDescriptors), \
+ USB_DESC_BYTE(bDescriptorType), \
+ USB_DESC_WORD(wDescriptorLength)
+
+/**
+ * @brief HID Report Usage Page item helper macro (Single byte).
+ */
+#define HID_USAGE_PAGE_B(up) \
+ USB_DESC_BYTE(HID_REPORT_USAGE_PAGE | 0x01), \
+ USB_DESC_BYTE(up)
+
+/**
+ * @brief HID Report Usage Page item helper macro (Double byte).
+ */
+#define HID_USAGE_PAGE_W(up) \
+ USB_DESC_BYTE(HID_REPORT_USAGE_PAGE | 0x02), \
+ USB_DESC_WORD(up)
+
+/**
+ * @brief HID Report Usage item helper macro (Single byte).
+ */
+#define HID_USAGE_B(u) \
+ USB_DESC_BYTE(HID_REPORT_USAGE | 0x01), \
+ USB_DESC_BYTE(u)
+
+/**
+ * @brief HID Report Usage item helper macro (Double byte).
+ */
+#define HID_USAGE_W(u) \
+ USB_DESC_BYTE(HID_REPORT_USAGE | 0x02), \
+ USB_DESC_WORD(u)
+
+/**
+ * @brief HID Report Collection item helper macro (Single Byte).
+ */
+#define HID_COLLECTION_B(c) \
+ USB_DESC_BYTE(HID_REPORT_COLLECTION | 0x01), \
+ USB_DESC_BYTE(c)
+
+/**
+ * @brief HID Report Collection item helper macro (Double Byte).
+ */
+#define HID_COLLECTION_W(c) \
+ USB_DESC_BYTE(HID_REPORT_COLLECTION | 0x02), \
+ USB_DESC_WORD(c)
+
+/**
+ * @brief HID Report End Collection item helper macro.
+ */
+#define HID_END_COLLECTION \
+ USB_DESC_BYTE(HID_REPORT_END_COLLECTION)
+
+/**
+ * @brief HID Report Usage Minimum item helper macro (Single byte).
+ */
+#define HID_USAGE_MINIMUM_B(x) \
+ USB_DESC_BYTE(HID_REPORT_USAGE_MINIMUM | 0x01), \
+ USB_DESC_BYTE(x)
+
+/**
+ * @brief HID Report Usage Minimum item helper macro (Double byte).
+ */
+#define HID_USAGE_MINIMUM_W(x) \
+ USB_DESC_BYTE(HID_REPORT_USAGE_MINIMUM | 0x02), \
+ USB_DESC_WORD(x)
+
+/**
+ * @brief HID Report Usage Maximum item helper macro (Single byte).
+ */
+#define HID_USAGE_MAXIMUM_B(x) \
+ USB_DESC_BYTE(HID_REPORT_USAGE_MAXIMUM | 0x01), \
+ USB_DESC_BYTE(x)
+
+/**
+ * @brief HID Report Usage Maximum item helper macro (Double byte).
+ */
+#define HID_USAGE_MAXIMUM_W(x) \
+ USB_DESC_BYTE(HID_REPORT_USAGE_MAXIMUM | 0x02), \
+ USB_DESC_WORD(x)
+
+/**
+ * @brief HID Report Logical Minimum item helper macro (Single byte).
+ */
+#define HID_LOGICAL_MINIMUM_B(x) \
+ USB_DESC_BYTE(HID_REPORT_LOGICAL_MINIMUM | 0x01), \
+ USB_DESC_BYTE(x)
+
+/**
+ * @brief HID Report Logical Minimum item helper macro (Double byte).
+ */
+#define HID_LOGICAL_MINIMUM_W(x) \
+ USB_DESC_BYTE(HID_REPORT_LOGICAL_MINIMUM | 0x02), \
+ USB_DESC_WORD(x)
+
+/**
+ * @brief HID Report Logical Maximum item helper macro (Single byte).
+ */
+#define HID_LOGICAL_MAXIMUM_B(x) \
+ USB_DESC_BYTE(HID_REPORT_LOGICAL_MAXIMUM | 0x01), \
+ USB_DESC_BYTE(x)
+
+/**
+ * @brief HID Report Logical Maximum item helper macro (Double byte).
+ */
+#define HID_LOGICAL_MAXIMUM_W(x) \
+ USB_DESC_BYTE(HID_REPORT_LOGICAL_MAXIMUM | 0x02), \
+ USB_DESC_WORD(x)
+
+/**
+ * @brief HID Report Count item helper macro (Single byte).
+ */
+#define HID_REPORT_COUNT_B(x) \
+ USB_DESC_BYTE(HID_REPORT_REPORT_COUNT | 0x01), \
+ USB_DESC_BYTE(x)
+
+/**
+ * @brief HID Report Count item helper macro (Double byte).
+ */
+#define HID_REPORT_COUNT_W(x) \
+ USB_DESC_BYTE(HID_REPORT_REPORT_COUNT | 0x02), \
+ USB_DESC_WORD(x)
+
+/**
+ * @brief HID Report Size item helper macro (Single byte).
+ */
+#define HID_REPORT_SIZE_B(x) \
+ USB_DESC_BYTE(HID_REPORT_REPORT_SIZE | 0x01), \
+ USB_DESC_BYTE(x)
+
+/**
+ * @brief HID Report Size item helper macro (Double byte).
+ */
+#define HID_REPORT_SIZE_W(x) \
+ USB_DESC_BYTE(HID_REPORT_REPORT_SIZE | 0x02), \
+ USB_DESC_WORD(x)
+
+/**
+ * @brief HID Report Input item helper macro (Single byte).
+ */
+#define HID_INPUT_B(x) \
+ USB_DESC_BYTE(HID_REPORT_INPUT | 0x01), \
+ USB_DESC_BYTE(x)
+
+/**
+ * @brief HID Report Input item helper macro (Double byte).
+ */
+#define HID_INPUT_W(x) \
+ USB_DESC_BYTE(HID_REPORT_INPUT | 0x02), \
+ USB_DESC_WORD(x)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name USB HID configuration options
+ * @{
+ */
+/**
+ * @brief USB HID buffers size.
+ * @details Configuration parameter, the buffer size must be a multiple of
+ * the USB data endpoint maximum packet size.
+ * @note The default is 256 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(USB_HID_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define USB_HID_BUFFERS_SIZE 256
+#endif
+
+/**
+ * @brief USB HID number of buffers.
+ * @note The default is 2 buffers.
+ */
+#if !defined(USB_HID_BUFFERS_NUMBER) || defined(__DOXYGEN__)
+#define USB_HID_BUFFERS_NUMBER 2
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if HAL_USE_USB == FALSE
+#error "USB HID Driver requires HAL_USE_USB"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ HID_UNINIT = 0, /**< Not initialized. */
+ HID_STOP = 1, /**< Stopped. */
+ HID_READY = 2 /**< Ready. */
+} hidstate_t;
+
+/**
+ * @brief Structure representing a USB HID driver.
+ */
+typedef struct USBHIDDriver USBHIDDriver;
+
+/**
+ * @brief USB HID Driver configuration structure.
+ * @details An instance of this structure must be passed to @p hidStart()
+ * in order to configure and start the driver operations.
+ */
+typedef struct {
+ /**
+ * @brief USB driver to use.
+ */
+ USBDriver *usbp;
+ /**
+ * @brief Interrupt IN endpoint used for outgoing data transfer.
+ */
+ usbep_t int_in;
+ /**
+ * @brief Interrupt OUT endpoint used for incoming data transfer.
+ */
+ usbep_t int_out;
+} USBHIDConfig;
+
+/**
+ * @brief @p USBHIDDriver specific data.
+ */
+#define _usb_hid_driver_data \
+ _base_asynchronous_channel_data \
+ /* Driver state.*/ \
+ hidstate_t state; \
+ /* Input buffers queue.*/ \
+ input_buffers_queue_t ibqueue; \
+ /* Output queue.*/ \
+ output_buffers_queue_t obqueue; \
+ /* Input buffer.*/ \
+ uint8_t ib[BQ_BUFFER_SIZE(USB_HID_BUFFERS_NUMBER, \
+ USB_HID_BUFFERS_SIZE)]; \
+ /* Output buffer.*/ \
+ uint8_t ob[BQ_BUFFER_SIZE(USB_HID_BUFFERS_NUMBER, \
+ USB_HID_BUFFERS_SIZE)]; \
+ /* End of the mandatory fields.*/ \
+ /* Current configuration data.*/ \
+ const USBHIDConfig *config;
+
+/**
+ * @brief @p USBHIDDriver specific methods.
+ */
+#define _usb_hid_driver_methods \
+ _base_asynchronous_channel_methods \
+ /* Buffer flush method.*/ \
+ void (*flush)(void *instance);
+
+/**
+ * @extends BaseAsynchronousChannelVMT
+ *
+ * @brief @p USBHIDDriver virtual methods table.
+ */
+struct USBHIDDriverVMT {
+ _usb_hid_driver_methods
+};
+
+/**
+ * @extends BaseAsynchronousChannel
+ *
+ * @brief Full duplex USB HID driver class.
+ * @details This class extends @p BaseAsynchronousChannel by adding physical
+ * I/O queues.
+ */
+struct USBHIDDriver {
+ /** @brief Virtual Methods Table.*/
+ const struct USBHIDDriverVMT *vmt;
+ _usb_hid_driver_data
+};
+
+#define USB_DRIVER_EXT_FIELDS \
+ USBHIDDriver hid
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void hidInit(void);
+ void hidObjectInit(USBHIDDriver *uhdp);
+ void hidStart(USBHIDDriver *uhdp, const USBHIDConfig *config);
+ void hidStop(USBHIDDriver *uhdp);
+ void hidDisconnectI(USBHIDDriver *uhdp);
+ void hidConfigureHookI(USBHIDDriver *uhdp);
+ bool hidRequestsHook(USBDriver *usbp);
+ void hidDataTransmitted(USBDriver *usbp, usbep_t ep);
+ void hidDataReceived(USBDriver *usbp, usbep_t ep);
+ size_t hidWriteReport(USBHIDDriver *uhdp, uint8_t *bp, size_t n);
+ size_t hidWriteReportt(USBHIDDriver *uhdp, uint8_t *bp, size_t n, systime_t timeout);
+ size_t hidReadReport(USBHIDDriver *uhdp, uint8_t *bp, size_t n);
+ size_t hidReadReportt(USBHIDDriver *uhdp, uint8_t *bp, size_t n, systime_t timeout);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_USB_HID */
+
+#endif /* HAL_USB_HID_H */
+
+/** @} */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/hal_usbh.h b/ChibiOS_16.1.5/community/os/hal/include/hal_usbh.h
new file mode 100644
index 0000000..5fd0047
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/hal_usbh.h
@@ -0,0 +1,436 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+ Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+
+ 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.
+*/
+
+#ifndef USBH_H_
+#define USBH_H_
+
+#include "hal.h"
+
+
+#ifndef HAL_USBH_USE_FTDI
+#define HAL_USBH_USE_FTDI FALSE
+#endif
+
+#ifndef HAL_USBH_USE_HUB
+#define HAL_USBH_USE_HUB FALSE
+#endif
+
+#ifndef HAL_USBH_USE_MSD
+#define HAL_USBH_USE_MSD FALSE
+#endif
+
+#ifndef HAL_USBH_USE_UVC
+#define HAL_USBH_USE_UVC FALSE
+#endif
+
+#if (HAL_USE_USBH == TRUE) || defined(__DOXYGEN__)
+
+#include "osal.h"
+#include "usbh/list.h"
+#include "usbh/defs.h"
+
+/* TODO:
+ *
+ * - Integrate VBUS power switching functionality to the API.
+ *
+ */
+
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !HAL_USBH_USE_HUB
+#define USBH_MAX_ADDRESSES 1
+#else
+#define USBH_MAX_ADDRESSES (HAL_USBHHUB_MAX_PORTS + 1)
+#endif
+
+enum usbh_status {
+ USBH_STATUS_STOPPED = 0,
+ USBH_STATUS_STARTED,
+ USBH_STATUS_SUSPENDED,
+};
+
+enum usbh_devstatus {
+ USBH_DEVSTATUS_DISCONNECTED = 0,
+ USBH_DEVSTATUS_ATTACHED,
+ USBH_DEVSTATUS_CONNECTED,
+ USBH_DEVSTATUS_DEFAULT,
+ USBH_DEVSTATUS_ADDRESS,
+ USBH_DEVSTATUS_CONFIGURED,
+};
+
+enum usbh_devspeed {
+ USBH_DEVSPEED_LOW = 0,
+ USBH_DEVSPEED_FULL,
+ USBH_DEVSPEED_HIGH,
+};
+
+enum usbh_epdir {
+ USBH_EPDIR_IN = 0x80,
+ USBH_EPDIR_OUT = 0
+};
+
+enum usbh_eptype {
+ USBH_EPTYPE_CTRL = 0,
+ USBH_EPTYPE_ISO = 1,
+ USBH_EPTYPE_BULK = 2,
+ USBH_EPTYPE_INT = 3,
+};
+
+enum usbh_epstatus {
+ USBH_EPSTATUS_UNINITIALIZED = 0,
+ USBH_EPSTATUS_CLOSED,
+ USBH_EPSTATUS_OPEN,
+ USBH_EPSTATUS_HALTED,
+};
+
+enum usbh_urbstatus {
+ USBH_URBSTATUS_UNINITIALIZED = 0,
+ USBH_URBSTATUS_INITIALIZED,
+ USBH_URBSTATUS_PENDING,
+// USBH_URBSTATUS_QUEUED,
+ USBH_URBSTATUS_ERROR,
+ USBH_URBSTATUS_TIMEOUT,
+ USBH_URBSTATUS_CANCELLED,
+ USBH_URBSTATUS_STALL,
+ USBH_URBSTATUS_DISCONNECTED,
+// USBH_URBSTATUS_EPCLOSED,
+ USBH_URBSTATUS_OK,
+};
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/* forward declarations */
+typedef struct USBHDriver USBHDriver;
+typedef struct usbh_port usbh_port_t;
+typedef struct usbh_device usbh_device_t;
+typedef struct usbh_ep usbh_ep_t;
+typedef struct usbh_urb usbh_urb_t;
+typedef struct usbh_baseclassdriver usbh_baseclassdriver_t;
+typedef struct usbh_classdriverinfo usbh_classdriverinfo_t;
+#if HAL_USBH_USE_HUB
+typedef struct USBHHubDriver USBHHubDriver;
+#endif
+
+/* typedefs */
+typedef enum usbh_status usbh_status_t;
+typedef enum usbh_devspeed usbh_devspeed_t;
+typedef enum usbh_devstatus usbh_devstatus_t;
+typedef enum usbh_epdir usbh_epdir_t;
+typedef enum usbh_eptype usbh_eptype_t;
+typedef enum usbh_epstatus usbh_epstatus_t;
+typedef enum usbh_urbstatus usbh_urbstatus_t;
+typedef uint16_t usbh_portstatus_t;
+typedef uint16_t usbh_portcstatus_t;
+typedef void (*usbh_completion_cb)(usbh_urb_t *);
+
+/* include the low level driver; the required definitions are above */
+#include "hal_usbh_lld.h"
+
+#define USBH_DEFINE_BUFFER(type, name) USBH_LLD_DEFINE_BUFFER(type, name)
+
+struct usbh_urb {
+ usbh_ep_t *ep;
+
+ void *userData;
+ usbh_completion_cb callback;
+
+ const void *setup_buff;
+ void *buff;
+ uint32_t requestedLength;
+ uint32_t actualLength;
+
+ usbh_urbstatus_t status;
+
+ thread_reference_t waitingThread;
+ thread_reference_t abortingThread;
+
+ /* Low level part */
+ _usbh_urb_ll_data
+};
+
+struct usbh_ep {
+ usbh_device_t *device;
+ usbh_ep_t *next;
+
+ usbh_epstatus_t status;
+ uint8_t address;
+ bool in;
+ usbh_eptype_t type;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+
+ /* debug */
+ const char *name;
+
+ /* Low-level part */
+ _usbh_ep_ll_data
+};
+
+struct usbh_device {
+ USBHDriver *host; /* shortcut to host */
+
+ usbh_ep_t ctrl;
+ usbh_ep_t *endpoints;
+
+ usbh_baseclassdriver_t *drivers;
+
+ uint16_t langID0;
+
+ usbh_devstatus_t status;
+ usbh_devspeed_t speed;
+
+ USBH_DEFINE_BUFFER(usbh_device_descriptor_t, devDesc);
+ unsigned char align_bytes[2];
+ USBH_DEFINE_BUFFER(usbh_config_descriptor_t, basicConfigDesc);
+
+ uint8_t *fullConfigurationDescriptor;
+ uint8_t keepFullCfgDesc;
+
+ uint8_t address;
+ uint8_t bConfiguration;
+
+ /* Low level part */
+ _usbh_device_ll_data
+};
+
+
+struct usbh_port {
+#if HAL_USBH_USE_HUB
+ USBHHubDriver *hub;
+#endif
+
+ usbh_portstatus_t status;
+ usbh_portcstatus_t c_status;
+
+ usbh_port_t *next;
+
+ uint8_t number;
+
+ usbh_device_t device;
+
+ /* Low level part */
+ _usbh_port_ll_data
+};
+
+struct USBHDriver {
+ usbh_status_t status;
+ uint8_t address_bitmap[(USBH_MAX_ADDRESSES + 7) / 8];
+
+ usbh_port_t rootport;
+
+#if HAL_USBH_USE_HUB
+ struct list_head hubs;
+#endif
+
+ /* Low level part */
+ _usbhdriver_ll_data
+
+#if USBH_DEBUG_ENABLE
+ /* debug */
+ uint8_t dbg_buff[USBH_DEBUG_BUFFER];
+ THD_WORKING_AREA(waDebug, 512);
+ input_queue_t iq;
+#endif
+};
+
+
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_USBH_USE_OTG1
+extern USBHDriver USBHD1;
+#endif
+
+#if STM32_USBH_USE_OTG2
+extern USBHDriver USBHD2;
+#endif
+
+
+/*===========================================================================*/
+/* Main driver API. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Main functions */
+ void usbhObjectInit(USBHDriver *usbh);
+ void usbhInit(void);
+ void usbhStart(USBHDriver *usbh);
+ void usbhStop(USBHDriver *usbh);
+ void usbhSuspend(USBHDriver *usbh);
+ void usbhResume(USBHDriver *usbh);
+
+ /* Device-related */
+#if USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_INFO
+ void usbhDevicePrintInfo(usbh_device_t *dev);
+ void usbhDevicePrintConfiguration(const uint8_t *descriptor, uint16_t rem);
+#else
+# define usbhDevicePrintInfo(dev) do {} while(0)
+# define usbhDevicePrintConfiguration(descriptor, rem) do {} while(0)
+#endif
+ bool usbhDeviceReadString(usbh_device_t *dev, char *dest, uint8_t size,
+ uint8_t index, uint16_t langID);
+ static inline usbh_port_t *usbhDeviceGetPort(usbh_device_t *dev) {
+ return container_of(dev, usbh_port_t, device);
+ }
+
+ /* Synchronous API */
+ usbh_urbstatus_t usbhBulkTransfer(usbh_ep_t *ep,
+ void *data,
+ uint32_t len,
+ uint32_t *actual_len,
+ systime_t timeout);
+ usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev,
+ uint8_t bmRequestType,
+ uint8_t bRequest,
+ uint16_t wValue,
+ uint16_t wIndex,
+ uint16_t wLength,
+ uint8_t *buff);
+ usbh_urbstatus_t usbhControlRequestExtended(usbh_device_t *dev,
+ const usbh_control_request_t *req,
+ uint8_t *buff,
+ uint32_t *actual_len,
+ systime_t timeout);
+
+ /* Standard request helpers */
+ bool usbhStdReqGetDeviceDescriptor(usbh_device_t *dev,
+ uint16_t wLength,
+ uint8_t *buf);
+ bool usbhStdReqGetConfigurationDescriptor(usbh_device_t *dev,
+ uint8_t index,
+ uint16_t wLength,
+ uint8_t *buf);
+ bool usbhStdReqGetStringDescriptor(usbh_device_t *dev,
+ uint8_t index,
+ uint16_t langID,
+ uint16_t wLength,
+ uint8_t *buf);
+ bool usbhStdReqSetInterface(usbh_device_t *dev,
+ uint8_t bInterfaceNumber,
+ uint8_t bAlternateSetting);
+ bool usbhStdReqGetInterface(usbh_device_t *dev,
+ uint8_t bInterfaceNumber,
+ uint8_t *bAlternateSetting);
+
+ /* Endpoint/pipe management */
+ void usbhEPObjectInit(usbh_ep_t *ep, usbh_device_t *dev, const usbh_endpoint_descriptor_t *desc);
+ static inline void usbhEPOpen(usbh_ep_t *ep) {
+ osalDbgCheck(ep != 0);
+ osalSysLock();
+ osalDbgAssert(ep->status == USBH_EPSTATUS_CLOSED, "invalid state");
+ usbh_lld_ep_open(ep);
+ ep->next = ep->device->endpoints;
+ ep->device->endpoints = ep;
+ osalSysUnlock();
+ }
+ static inline void usbhEPCloseS(usbh_ep_t *ep) {
+ osalDbgCheck(ep != 0);
+ osalDbgCheckClassS();
+ osalDbgAssert(ep->status != USBH_EPSTATUS_UNINITIALIZED, "invalid state");
+ if (ep->status == USBH_EPSTATUS_CLOSED) {
+ osalOsRescheduleS();
+ return;
+ }
+ usbh_lld_ep_close(ep);
+ }
+ static inline void usbhEPClose(usbh_ep_t *ep) {
+ osalSysLock();
+ usbhEPCloseS(ep);
+ osalSysUnlock();
+ }
+ static inline void usbhEPResetI(usbh_ep_t *ep) {
+ osalDbgCheckClassI();
+ osalDbgCheck(ep != NULL);
+ usbh_lld_epreset(ep);
+ }
+ static inline bool usbhEPIsPeriodic(usbh_ep_t *ep) {
+ osalDbgCheck(ep != NULL);
+ return (ep->type & 1) != 0;
+ }
+ static inline bool usbhURBIsBusy(usbh_urb_t *urb) {
+ osalDbgCheck(urb != NULL);
+ return (urb->status == USBH_URBSTATUS_PENDING);
+ }
+ static inline void usbhEPSetName(usbh_ep_t *ep, const char *name) {
+ ep->name = name;
+ }
+
+ /* URB management */
+ void usbhURBObjectInit(usbh_urb_t *urb, usbh_ep_t *ep, usbh_completion_cb callback,
+ void *user, void *buff, uint32_t len);
+ void usbhURBObjectResetI(usbh_urb_t *urb);
+ void usbhURBSubmitI(usbh_urb_t *urb);
+ bool usbhURBCancelI(usbh_urb_t *urb);
+ msg_t usbhURBSubmitAndWaitS(usbh_urb_t *urb, systime_t timeout);
+ void usbhURBCancelAndWaitS(usbh_urb_t *urb);
+ msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout);
+
+ /* Main loop */
+ void usbhMainLoop(USBHDriver *usbh);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*===========================================================================*/
+/* Class driver definitions and API. */
+/*===========================================================================*/
+
+typedef struct usbh_classdriver_vmt usbh_classdriver_vmt_t;
+struct usbh_classdriver_vmt {
+ usbh_baseclassdriver_t *(*load)(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
+ void (*unload)(usbh_baseclassdriver_t *drv);
+};
+
+struct usbh_classdriverinfo {
+ int16_t class;
+ int16_t subclass;
+ int16_t protocol;
+ const char *name;
+ const usbh_classdriver_vmt_t *vmt;
+};
+
+#define _usbh_base_classdriver_data \
+ const usbh_classdriverinfo_t *info; \
+ usbh_device_t *dev; \
+ usbh_baseclassdriver_t *next;
+
+struct usbh_baseclassdriver {
+ _usbh_base_classdriver_data
+};
+
+
+/*===========================================================================*/
+/* Helper functions. */
+/*===========================================================================*/
+#include <usbh/desciter.h> /* descriptor iterators */
+#include <usbh/debug.h> /* debug */
+
+#endif
+
+#endif /* USBH_H_ */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/usbh/debug.h b/ChibiOS_16.1.5/community/os/hal/include/usbh/debug.h
new file mode 100644
index 0000000..5120121
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/usbh/debug.h
@@ -0,0 +1,44 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+ Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+
+ 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.
+*/
+
+
+#ifndef USBH_DEBUG_H_
+#define USBH_DEBUG_H_
+
+#include "hal_usbh.h"
+
+#if HAL_USE_USBH
+
+//TODO: Debug is only for USBHD1, make it generic.
+
+#if USBH_DEBUG_ENABLE
+ void usbDbgPrintf(const char *fmt, ...);
+ void usbDbgPuts(const char *s);
+ void usbDbgInit(USBHDriver *host);
+ void usbDbgReset(void);
+ void usbDbgSystemHalted(void);
+#else
+#define usbDbgPrintf(fmt, ...) do {} while(0)
+#define usbDbgPuts(s) do {} while(0)
+#define usbDbgInit(host) do {} while(0)
+#define usbDbgReset() do {} while(0)
+#define usbDbgSystemHalted() do {} while(0)
+#endif
+
+#endif
+
+#endif /* USBH_DEBUG_H_ */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/usbh/defs.h b/ChibiOS_16.1.5/community/os/hal/include/usbh/defs.h
new file mode 100644
index 0000000..c3d8a9a
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/usbh/defs.h
@@ -0,0 +1,160 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+ Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+
+ 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.
+*/
+
+#ifndef USBH_DEFS_H_
+#define USBH_DEFS_H_
+
+#include "hal.h"
+
+#if HAL_USE_USBH
+
+#include "osal.h"
+
+#ifdef __IAR_SYSTEMS_ICC__
+#define PACKED_STRUCT typedef PACKED_VAR struct
+#else
+#define PACKED_STRUCT typedef struct PACKED_VAR
+#endif
+
+PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
+} usbh_device_descriptor_t;
+#define USBH_DT_DEVICE 0x01
+#define USBH_DT_DEVICE_SIZE 18
+
+PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength;
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t bMaxPower;
+} usbh_config_descriptor_t;
+#define USBH_DT_CONFIG 0x02
+#define USBH_DT_CONFIG_SIZE 9
+
+PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wData[1];
+} usbh_string_descriptor_t;
+#define USBH_DT_STRING 0x03
+#define USBH_DT_STRING_SIZE 2
+
+PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+} usbh_interface_descriptor_t;
+#define USBH_DT_INTERFACE 0x04
+#define USBH_DT_INTERFACE_SIZE 9
+
+PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+} usbh_endpoint_descriptor_t;
+#define USBH_DT_ENDPOINT 0x05
+#define USBH_DT_ENDPOINT_SIZE 7
+
+PACKED_STRUCT {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bFirstInterface;
+ uint8_t bInterfaceCount;
+ uint8_t bFunctionClass;
+ uint8_t bFunctionSubClass;
+ uint8_t bFunctionProtocol;
+ uint8_t iFunction;
+} usbh_ia_descriptor_t;
+#define USBH_DT_INTERFACE_ASSOCIATION 0x0b
+#define USBH_DT_INTERFACE_ASSOCIATION_SIZE 8
+
+PACKED_STRUCT {
+ uint8_t bDescLength;
+ uint8_t bDescriptorType;
+ uint8_t bNbrPorts;
+ uint16_t wHubCharacteristics;
+ uint8_t bPwrOn2PwrGood;
+ uint8_t bHubContrCurrent;
+ uint32_t DeviceRemovable;
+} usbh_hub_descriptor_t;
+#define USBH_DT_HUB 0x29
+#define USBH_DT_HUB_SIZE (7 + 4)
+
+PACKED_STRUCT {
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} usbh_control_request_t;
+
+
+#define USBH_REQ_GET_STATUS 0x00
+#define USBH_REQ_CLEAR_FEATURE 0x01
+#define USBH_REQ_SET_FEATURE 0x03
+#define USBH_REQ_SET_ADDRESS 0x05
+#define USBH_REQ_GET_DESCRIPTOR 0x06
+#define USBH_REQ_SET_DESCRIPTOR 0x07
+#define USBH_REQ_GET_CONFIGURATION 0x08
+#define USBH_REQ_SET_CONFIGURATION 0x09
+#define USBH_REQ_GET_INTERFACE 0x0A
+#define USBH_REQ_SET_INTERFACE 0x0B
+#define USBH_REQ_SYNCH_FRAME 0x0C
+
+
+#define USBH_REQTYPE_IN 0x80
+#define USBH_REQTYPE_OUT 0x00
+
+#define USBH_REQTYPE_STANDARD 0x00
+#define USBH_REQTYPE_CLASS 0x20
+#define USBH_REQTYPE_VENDOR 0x40
+
+#define USBH_REQTYPE_DEVICE 0x00
+#define USBH_REQTYPE_INTERFACE 0x01
+#define USBH_REQTYPE_ENDPOINT 0x02
+#define USBH_REQTYPE_OTHER 0x03
+
+#endif
+
+
+#endif /* USBH_DEFS_H_ */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/usbh/desciter.h b/ChibiOS_16.1.5/community/os/hal/include/usbh/desciter.h
new file mode 100644
index 0000000..52b0c98
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/usbh/desciter.h
@@ -0,0 +1,63 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+ Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+
+ 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.
+*/
+
+
+#ifndef USBH_DESCITER_H_
+#define USBH_DESCITER_H_
+
+#include "hal.h"
+
+#if HAL_USE_USBH
+
+#include "usbh/defs.h"
+
+
+/* DESCRIPTOR PARSING */
+#define _generic_iterator_fields \
+ const uint8_t *curr; \
+ uint16_t rem; \
+ bool valid;
+
+typedef struct {
+ _generic_iterator_fields
+} generic_iterator_t;
+
+typedef struct {
+ _generic_iterator_fields
+ const usbh_ia_descriptor_t *iad;
+} if_iterator_t;
+
+void cfg_iter_init(generic_iterator_t *icfg, const uint8_t *buff, uint16_t rem);
+void if_iter_init(if_iterator_t *iif, const generic_iterator_t *icfg);
+void ep_iter_init(generic_iterator_t *iep, const if_iterator_t *iif);
+void cs_iter_init(generic_iterator_t *ics, const generic_iterator_t *iter);
+void if_iter_next(if_iterator_t *iif);
+void ep_iter_next(generic_iterator_t *iep);
+void cs_iter_next(generic_iterator_t *ics);
+static inline const usbh_config_descriptor_t *cfg_get(generic_iterator_t *icfg) {
+ return (const usbh_config_descriptor_t *)icfg->curr;
+}
+static inline const usbh_interface_descriptor_t *if_get(if_iterator_t *iif) {
+ return (const usbh_interface_descriptor_t *)iif->curr;
+}
+static inline const usbh_endpoint_descriptor_t *ep_get(generic_iterator_t *iep) {
+ return (const usbh_endpoint_descriptor_t *)iep->curr;
+}
+
+#endif
+
+#endif /* USBH_DESCITER_H_ */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/usbh/dev/ftdi.h b/ChibiOS_16.1.5/community/os/hal/include/usbh/dev/ftdi.h
new file mode 100644
index 0000000..ad6b4cd
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/usbh/dev/ftdi.h
@@ -0,0 +1,154 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+ Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+
+ 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.
+*/
+
+#ifndef USBH_FTDI_H_
+#define USBH_FTDI_H_
+
+#include "hal_usbh.h"
+
+#if HAL_USE_USBH && HAL_USBH_USE_FTDI
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+#define USBHFTDI_FRAMING_DATABITS_7 (0x7 << 0)
+#define USBHFTDI_FRAMING_DATABITS_8 (0x8 << 0)
+#define USBHFTDI_FRAMING_PARITY_NONE (0x0 << 8)
+#define USBHFTDI_FRAMING_PARITY_NONE (0x0 << 8)
+#define USBHFTDI_FRAMING_PARITY_ODD (0x1 << 8)
+#define USBHFTDI_FRAMING_PARITY_EVEN (0x2 << 8)
+#define USBHFTDI_FRAMING_PARITY_MARK (0x3 << 8)
+#define USBHFTDI_FRAMING_PARITY_SPACE (0x4 << 8)
+#define USBHFTDI_FRAMING_STOP_BITS_1 (0x0 << 11)
+#define USBHFTDI_FRAMING_STOP_BITS_15 (0x1 << 11)
+#define USBHFTDI_FRAMING_STOP_BITS_2 (0x2 << 11)
+
+#define USBHFTDI_HANDSHAKE_NONE (0x0)
+#define USBHFTDI_HANDSHAKE_RTS_CTS (0x1)
+#define USBHFTDI_HANDSHAKE_DTR_DSR (0x2)
+#define USBHFTDI_HANDSHAKE_XON_XOFF (0x4)
+
+
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+typedef struct {
+ uint32_t speed;
+ uint16_t framing;
+ uint8_t handshake;
+ uint8_t xon_character;
+ uint8_t xoff_character;
+} USBHFTDIPortConfig;
+
+typedef enum {
+ USBHFTDI_TYPE_A,
+ USBHFTDI_TYPE_B,
+ USBHFTDI_TYPE_H,
+} usbhftdi_type_t;
+
+typedef enum {
+ USBHFTDIP_STATE_UNINIT = 0,
+ USBHFTDIP_STATE_STOP = 1,
+ USBHFTDIP_STATE_ACTIVE = 2,
+ USBHFTDIP_STATE_READY = 3
+} usbhftdip_state_t;
+
+
+#define _ftdi_port_driver_methods \
+ _base_asynchronous_channel_methods
+
+struct FTDIPortDriverVMT {
+ _ftdi_port_driver_methods
+};
+
+typedef struct USBHFTDIPortDriver USBHFTDIPortDriver;
+typedef struct USBHFTDIDriver USBHFTDIDriver;
+
+struct USBHFTDIPortDriver {
+ /* inherited from abstract asyncrhonous channel driver */
+ const struct FTDIPortDriverVMT *vmt;
+ _base_asynchronous_channel_data
+
+ USBHFTDIDriver *ftdip;
+
+ usbhftdip_state_t state;
+
+ usbh_ep_t epin;
+ usbh_urb_t iq_urb;
+ threads_queue_t iq_waiting;
+ uint32_t iq_counter;
+ USBH_DEFINE_BUFFER(uint8_t, iq_buff[64]);
+ uint8_t *iq_ptr;
+
+
+ usbh_ep_t epout;
+ usbh_urb_t oq_urb;
+ threads_queue_t oq_waiting;
+ uint32_t oq_counter;
+ USBH_DEFINE_BUFFER(uint8_t, oq_buff[64]);
+ uint8_t *oq_ptr;
+
+ virtual_timer_t vt;
+ uint8_t ifnum;
+
+ USBHFTDIPortDriver *next;
+};
+
+typedef struct USBHFTDIDriver {
+ /* inherited from abstract class driver */
+ _usbh_base_classdriver_data
+
+ usbhftdi_type_t type;
+ USBHFTDIPortDriver *ports;
+
+ mutex_t mtx;
+} USBHFTDIDriver;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+extern USBHFTDIDriver USBHFTDID[HAL_USBHFTDI_MAX_INSTANCES];
+extern USBHFTDIPortDriver FTDIPD[HAL_USBHFTDI_MAX_PORTS];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ /* FTDI device driver */
+ void usbhftdiObjectInit(USBHFTDIDriver *ftdip);
+
+ /* FTDI port driver */
+ void usbhftdipObjectInit(USBHFTDIPortDriver *ftdipp);
+ void usbhftdipStart(USBHFTDIPortDriver *ftdipp, const USBHFTDIPortConfig *config);
+ void usbhftdipStop(USBHFTDIPortDriver *ftdipp);
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
+#endif /* USBH_FTDI_H_ */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/usbh/dev/hub.h b/ChibiOS_16.1.5/community/os/hal/include/usbh/dev/hub.h
new file mode 100644
index 0000000..07e88e6
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/usbh/dev/hub.h
@@ -0,0 +1,138 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+ Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+
+ 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.
+*/
+
+#ifndef USBH_HUB_H_
+#define USBH_HUB_H_
+
+#include "hal_usbh.h"
+
+#if HAL_USE_USBH
+#if HAL_USBH_USE_HUB
+
+typedef struct USBHHubDriver {
+ /* inherited from abstract class driver */
+ _usbh_base_classdriver_data
+
+ struct list_head node;
+
+ usbh_ep_t epint;
+ usbh_urb_t urb;
+
+ USBH_DEFINE_BUFFER(uint8_t, scbuff[4]);
+ volatile uint32_t statuschange;
+ uint16_t status;
+ uint16_t c_status;
+
+ usbh_port_t *ports;
+
+ USBH_DEFINE_BUFFER(usbh_hub_descriptor_t, hubDesc);
+
+ /* Low level part */
+ _usbh_hub_ll_data
+
+} USBHHubDriver;
+
+extern USBHHubDriver USBHHUBD[HAL_USBHHUB_MAX_INSTANCES];
+
+
+usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host, USBHHubDriver *hub,
+ uint8_t bmRequestType,
+ uint8_t bRequest,
+ uint16_t wValue,
+ uint16_t wIndex,
+ uint16_t wLength,
+ uint8_t *buf);
+
+
+static inline usbh_urbstatus_t usbhhubClearFeaturePort(usbh_port_t *port, uint8_t feature) {
+ return usbhhubControlRequest(port->device.host, port->hub,
+ USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER,
+ USBH_REQ_CLEAR_FEATURE,
+ feature,
+ port->number,
+ 0,
+ 0);
+}
+
+static inline usbh_urbstatus_t usbhhubClearFeatureHub(USBHDriver *host, USBHHubDriver *hub, uint8_t feature) {
+ return usbhhubControlRequest(host, hub,
+ USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE,
+ USBH_REQ_CLEAR_FEATURE,
+ feature,
+ 0,
+ 0,
+ 0);
+}
+
+static inline usbh_urbstatus_t usbhhubSetFeaturePort(usbh_port_t *port, uint8_t feature) {
+ return usbhhubControlRequest(port->device.host, port->hub,
+ USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER,
+ USBH_REQ_SET_FEATURE,
+ feature,
+ port->number,
+ 0,
+ 0);
+}
+
+void usbhhubObjectInit(USBHHubDriver *hubdp);
+#else
+
+static inline usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host,
+ uint8_t bmRequestType,
+ uint8_t bRequest,
+ uint16_t wValue,
+ uint16_t wIndex,
+ uint16_t wLength,
+ uint8_t *buf) {
+ return usbh_lld_root_hub_request(host, bmRequestType, bRequest, wValue, wIndex, wLength, buf);
+}
+
+static inline usbh_urbstatus_t usbhhubClearFeaturePort(usbh_port_t *port, uint8_t feature) {
+ return usbhhubControlRequest(port->device.host,
+ USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER,
+ USBH_REQ_CLEAR_FEATURE,
+ feature,
+ port->number,
+ 0,
+ 0);
+}
+
+static inline usbh_urbstatus_t usbhhubClearFeatureHub(USBHDriver *host, uint8_t feature) {
+ return usbhhubControlRequest(host,
+ USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE,
+ USBH_REQ_CLEAR_FEATURE,
+ feature,
+ 0,
+ 0,
+ 0);
+}
+
+static inline usbh_urbstatus_t usbhhubSetFeaturePort(usbh_port_t *port, uint8_t feature) {
+ return usbhhubControlRequest(port->device.host,
+ USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER,
+ USBH_REQ_SET_FEATURE,
+ feature,
+ port->number,
+ 0,
+ 0);
+}
+
+#endif
+
+#endif
+
+#endif /* USBH_HUB_H_ */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/usbh/dev/msd.h b/ChibiOS_16.1.5/community/os/hal/include/usbh/dev/msd.h
new file mode 100644
index 0000000..d164618
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/usbh/dev/msd.h
@@ -0,0 +1,125 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+ Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+
+ 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.
+*/
+
+#ifndef USBH_MSD_H_
+#define USBH_MSD_H_
+
+#include "hal_usbh.h"
+
+#if HAL_USE_USBH && HAL_USBH_USE_MSD
+
+/* TODO:
+ *
+ * - Implement of conditional compilation of multiple-luns per instance.
+ * - Implement error checking and recovery when commands fail.
+ *
+ */
+
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+#define _usbhmsd_driver_methods \
+ _base_block_device_methods
+
+struct USBHMassStorageDriverVMT {
+ _usbhmsd_driver_methods
+};
+
+typedef struct USBHMassStorageLUNDriver USBHMassStorageLUNDriver;
+typedef struct USBHMassStorageDriver USBHMassStorageDriver;
+
+struct USBHMassStorageLUNDriver {
+ /* inherited from abstract block driver */
+ const struct USBHMassStorageDriverVMT *vmt;
+ _base_block_device_data
+
+ BlockDeviceInfo info;
+ USBHMassStorageDriver *msdp;
+
+ USBHMassStorageLUNDriver *next;
+};
+
+typedef struct USBHMassStorageDriver {
+ /* inherited from abstract class driver */
+ _usbh_base_classdriver_data
+
+ /* for LUN request serialization, can be removed
+ * if the driver is configured to support only one LUN
+ * per USBHMassStorageDriver instance */
+ mutex_t mtx;
+
+ usbh_ep_t epin;
+ usbh_ep_t epout;
+ uint8_t ifnum;
+ uint8_t max_lun;
+ uint32_t tag;
+
+ USBHMassStorageLUNDriver *luns;
+} USBHMassStorageDriver;
+
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+extern USBHMassStorageLUNDriver MSBLKD[HAL_USBHMSD_MAX_LUNS];
+extern USBHMassStorageDriver USBHMSD[HAL_USBHMSD_MAX_INSTANCES];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ /* Mass Storage Driver */
+ void usbhmsdObjectInit(USBHMassStorageDriver *msdp);
+
+ /* Mass Storage LUN Driver (block driver) */
+ void usbhmsdLUNObjectInit(USBHMassStorageLUNDriver *lunp);
+ void usbhmsdLUNStart(USBHMassStorageLUNDriver *lunp);
+ void usbhmsdLUNStop(USBHMassStorageLUNDriver *lunp);
+ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp);
+ bool usbhmsdLUNDisconnect(USBHMassStorageLUNDriver *lunp);
+ bool usbhmsdLUNRead(USBHMassStorageLUNDriver *lunp, uint32_t startblk,
+ uint8_t *buffer, uint32_t n);
+ bool usbhmsdLUNWrite(USBHMassStorageLUNDriver *lunp, uint32_t startblk,
+ const uint8_t *buffer, uint32_t n);
+ bool usbhmsdLUNSync(USBHMassStorageLUNDriver *lunp);
+ bool usbhmsdLUNGetInfo(USBHMassStorageLUNDriver *lunp, BlockDeviceInfo *bdip);
+ bool usbhmsdLUNIsInserted(USBHMassStorageLUNDriver *lunp);
+ bool usbhmsdLUNIsProtected(USBHMassStorageLUNDriver *lunp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif /* USBH_MSD_H_ */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/usbh/internal.h b/ChibiOS_16.1.5/community/os/hal/include/usbh/internal.h
new file mode 100644
index 0000000..baa477f
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/usbh/internal.h
@@ -0,0 +1,148 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+ Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
+
+ 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.
+*/
+
+#ifndef USBH_INTERNAL_H_
+#define USBH_INTERNAL_H_
+
+#include "hal_usbh.h"
+
+#if HAL_USE_USBH
+
+/*===========================================================================*/
+/* These declarations are not part of the public API. */
+/*===========================================================================*/
+
+#if HAL_USBH_USE_FTDI
+extern const usbh_classdriverinfo_t usbhftdiClassDriverInfo;
+#endif
+#if HAL_USBH_USE_MSD
+extern const usbh_classdriverinfo_t usbhmsdClassDriverInfo;
+#endif
+#if HAL_USBH_USE_UVC
+extern const usbh_classdriverinfo_t usbhuvcClassDriverInfo;
+#endif
+#if HAL_USBH_USE_HUB
+extern const usbh_classdriverinfo_t usbhhubClassDriverInfo;
+void _usbhub_port_object_init(usbh_port_t *port, USBHDriver *usbh,
+ USBHHubDriver *hub, uint8_t number);
+#else
+void _usbhub_port_object_init(usbh_port_t *port, USBHDriver *usbh, uint8_t number);
+#endif
+
+void _usbh_port_disconnected(usbh_port_t *port);
+void _usbh_urb_completeI(usbh_urb_t *urb, usbh_urbstatus_t status);
+bool _usbh_urb_abortI(usbh_urb_t *urb, usbh_urbstatus_t status);
+void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status);
+
+
+#define USBH_CLASSIN(type, req, value, index) \
+ (USBH_REQTYPE_IN | type | USBH_REQTYPE_CLASS), \
+ req, \
+ value, \
+ index
+
+#define USBH_CLASSOUT(type, req, value, index) \
+ (USBH_REQTYPE_OUT | type | USBH_REQTYPE_CLASS), \
+ req, \
+ value, \
+ index
+
+#define USBH_STANDARDIN(type, req, value, index) \
+ (USBH_REQTYPE_IN | type | USBH_REQTYPE_STANDARD), \
+ req, \
+ value, \
+ index
+
+#define USBH_STANDARDOUT(type, req, value, index) \
+ (USBH_REQTYPE_OUT | type | USBH_REQTYPE_STANDARD), \
+ req, \
+ value, \
+ index
+
+
+#define USBH_PID_DATA0 0
+#define USBH_PID_DATA2 1
+#define USBH_PID_DATA1 2
+#define USBH_PID_MDATA 3
+#define USBH_PID_SETUP 3
+
+
+/* GetBusState and SetHubDescriptor are optional, omitted */
+#define ClearHubFeature (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
+ | USBH_REQ_CLEAR_FEATURE)
+#define SetHubFeature (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
+ | USBH_REQ_SET_FEATURE)
+#define ClearPortFeature (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER) << 8) \
+ | USBH_REQ_CLEAR_FEATURE)
+#define SetPortFeature (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER) << 8) \
+ | USBH_REQ_SET_FEATURE)
+#define GetHubDescriptor (((USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
+ | USBH_REQ_GET_DESCRIPTOR)
+#define GetHubStatus (((USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
+ | USBH_REQ_GET_STATUS)
+#define GetPortStatus (((USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER) << 8) \
+ | USBH_REQ_GET_STATUS)
+
+
+#define USBH_PORTSTATUS_CONNECTION 0x0001
+#define USBH_PORTSTATUS_ENABLE 0x0002
+#define USBH_PORTSTATUS_SUSPEND 0x0004
+#define USBH_PORTSTATUS_OVERCURRENT 0x0008
+#define USBH_PORTSTATUS_RESET 0x0010
+/* bits 5 to 7 are reserved */
+#define USBH_PORTSTATUS_POWER 0x0100
+#define USBH_PORTSTATUS_LOW_SPEED 0x0200
+#define USBH_PORTSTATUS_HIGH_SPEED 0x0400
+#define USBH_PORTSTATUS_TEST 0x0800
+#define USBH_PORTSTATUS_INDICATOR 0x1000
+/* bits 13 to 15 are reserved */
+
+#define USBH_PORTSTATUS_C_CONNECTION 0x0001
+#define USBH_PORTSTATUS_C_ENABLE 0x0002
+#define USBH_PORTSTATUS_C_SUSPEND 0x0004
+#define USBH_PORTSTATUS_C_OVERCURRENT 0x0008
+#define USBH_PORTSTATUS_C_RESET 0x0010
+
+#define USBH_HUBSTATUS_C_HUB_LOCAL_POWER 0x0001
+#define USBH_HUBSTATUS_C_HUB_OVER_CURRENT 0x0002
+
+/*
+ * Port feature numbers
+ * See USB 2.0 spec Table 11-17
+ */
+#define USBH_HUB_FEAT_C_HUB_LOCAL_POWER 0
+#define USBH_HUB_FEAT_C_HUB_OVER_CURRENT 1
+#define USBH_PORT_FEAT_CONNECTION 0
+#define USBH_PORT_FEAT_ENABLE 1
+#define USBH_PORT_FEAT_SUSPEND 2
+#define USBH_PORT_FEAT_OVERCURRENT 3
+#define USBH_PORT_FEAT_RESET 4
+#define USBH_PORT_FEAT_POWER 8
+#define USBH_PORT_FEAT_LOWSPEED 9
+#define USBH_PORT_FEAT_C_CONNECTION 16
+#define USBH_PORT_FEAT_C_ENABLE 17
+#define USBH_PORT_FEAT_C_SUSPEND 18
+#define USBH_PORT_FEAT_C_OVERCURRENT 19
+#define USBH_PORT_FEAT_C_RESET 20
+#define USBH_PORT_FEAT_TEST 21
+#define USBH_PORT_FEAT_INDICATOR 22
+
+#define sizeof_array(x) (sizeof(x)/sizeof(*(x)))
+
+#endif
+
+#endif /* USBH_INTERNAL_H_ */
diff --git a/ChibiOS_16.1.5/community/os/hal/include/usbh/list.h b/ChibiOS_16.1.5/community/os/hal/include/usbh/list.h
new file mode 100644
index 0000000..4eceacd
--- /dev/null
+++ b/ChibiOS_16.1.5/community/os/hal/include/usbh/list.h
@@ -0,0 +1,598 @@
+#ifndef USBH_LIST_H_
+#define USBH_LIST_H_
+
+/* TODO: re-write this file; stolen from linux */
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#define container_of(ptr, type, member) ((type *)(void *)((char *)(ptr) - offsetof(type, member)))
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ const typeof(((type *)0)->member) * __mptr = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); })
+#endif
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+#else
+extern void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next);
+#endif
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void __list_del_entry(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+}
+
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ // entry->next = LIST_POISON1;
+ // entry->prev = LIST_POISON2;
+}
+#else
+extern void __list_del_entry(struct list_head *entry);
+extern void list_del(struct list_head *entry);
+#endif
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old,
+ struct list_head *new)
+{
+ new->next = old->next;
+ new->next->prev = new;
+ new->prev = old->prev;
+ new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+ struct list_head *new)
+{
+ list_replace(old, new);
+ INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+ __list_del_entry(entry);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del_entry(list);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del_entry(list);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+ const struct list_head *head)
+{
+ return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+ struct list_head *next = head->next;
+ return (next == head) && (next == head->prev);
+}
+
+/**
+ * list_rotate_left - rotate the list to the left
+ * @head: the head of the list
+ */
+static inline void list_rotate_left(struct list_head *head)
+{
+ struct list_head *first;
+
+ if (!list_empty(head)) {
+ first = head->next;
+ list_move_tail(first, head);
+ }
+}
+
+/**
+ * list_is_singular - tests whether a list has just one entry.
+ * @head: the list to test.
+ */
+static inline int list_is_singular(const struct list_head *head)
+{
+ return !list_empty(head) && (head->next == head->prev);
+}
+
+static inline void __list_cut_position(struct list_head *list,
+ struct list_head *head, struct list_head *entry)
+{
+ struct list_head *new_first = entry->next;
+ list->next = head->next;
+ list->next->prev = list;
+ list->prev = entry;
+ entry->next = list;
+ head->next = new_first;
+ new_first->prev = head;
+}
+
+/**
+ * list_cut_position - cut a list into two
+ * @list: a new list to add all removed entries
+ * @head: a list with entries
+ * @entry: an entry within head, could be the head itself
+ * and if so we won't cut the list
+ *
+ * This helper moves the initial part of @head, up to and
+ * including @entry, from @head to @list. You should
+ * pass on @entry an element you know is on @head. @list
+ * should be an empty list or a list you do not care about
+ * losing its data.
+ *
+ */
+static inline void list_cut_position(struct list_head *list,
+ struct list_head *head, struct list_head *entry)
+{
+ if (list_empty(head))
+ return;
+ if (list_is_singular(head) &&
+ (head->next != entry && head != entry))
+ return;
+ if (entry == head)
+ INIT_LIST_HEAD(list);
+ else
+ __list_cut_position(list, head, entry);
+}
+
+static inline void __list_splice(const struct list_head *list,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+
+ first->prev = prev;
+ prev->next = first;
+
+ last->next = next;
+ next->prev = last;
+}
+
+/**
+ * list_splice - join two lists, this is designed for stacks
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(const struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head, head->next);
+}
+
+/**
+ * list_splice_tail - join two lists, each list being a queue
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice_tail(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head->prev, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head, head->next);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_splice_tail_init - join two lists and reinitialise the emptied list
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * Each of the lists is a queue.
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_tail_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head->prev, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * list_last_entry - get the last element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_last_entry(ptr, type, member) \
+ list_entry((ptr)->prev, type, member)
+
+/**
+ * list_first_entry_or_null - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note that if the list is empty, it returns NULL.
+ */
+#define list_first_entry_or_null(ptr, type, member) \
+ (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
+
+/**
+ * list_next_entry - get the next element in list
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ */
+#define list_next_entry(pos, type, member) \
+ list_entry((pos)->member.next, type, member)
+
+/**
+ * list_prev_entry - get the prev element in list
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ */
+#define list_prev_entry(pos, type, member) \
+ list_entry((pos)->member.prev, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; pos != (head); pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+ for (pos = (head)->prev, n = pos->prev; \
+ pos != (head); \
+ pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry(pos, type, head, member) \
+ for (pos = list_first_entry(head, type, member); \
+ &pos->member != (head); \
+ pos = list_next_entry(pos, type, member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry_reverse(pos, type, head, member) \
+ for (pos = list_last_entry(head, type, member); \
+ &pos->member != (head); \
+ pos = list_prev_entry(pos, type, member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos: the type * to use as a start point
+ * @head: the head of the list
+ * @member: the name of the list_head within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, type, head, member) \
+ ((pos) ? : list_entry(head, type, member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, type, head, member) \
+ for (pos = list_next_entry(pos, type, member); \
+ &pos->member != (head); \
+ pos = list_next_entry(pos, type, member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, type, head, member) \
+ for (pos = list_prev_entry(pos, type, member); \
+ &pos->member != (head); \
+ pos = list_prev_entry(pos, type, member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, type, head, member) \
+ for (; &pos->member != (head); \
+ pos = list_next_entry(pos, type, member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry_safe(pos, type, n, head, member) \
+ for (pos = list_first_entry(head, type, member), \
+ n = list_next_entry(pos, type, member); \
+ &pos->member != (head); \
+ pos = n, n = list_next_entry(n, type, member))
+
+/**
+ * list_for_each_entry_safe_continue - continue list iteration safe against removal
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, type, n, head, member) \
+ for (pos = list_next_entry(pos, type, member), \
+ n = list_next_entry(pos, type, member); \
+ &pos->member != (head); \
+ pos = n, n = list_next_entry(n, type, member))
+
+/**
+ * list_for_each_entry_safe_from - iterate over list from current point safe against removal
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, type, n, head, member) \
+ for (n = list_next_entry(pos, type, member); \
+ &pos->member != (head); \
+ pos = n, n = list_next_entry(n, type, member))
+
+/**
+ * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, type, n, head, member) \
+ for (pos = list_last_entry(head, type, member), \
+ n = list_prev_entry(pos, type, member); \
+ &pos->member != (head); \
+ pos = n, n = list_prev_entry(n, type, member))
+
+/**
+ * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
+ * @pos: the loop cursor used in the list_for_each_entry_safe loop
+ * @n: temporary storage used in list_for_each_entry_safe
+ * @member: the name of the list_head within the struct.
+ *
+ * list_safe_reset_next is not safe to use in general if the list may be
+ * modified concurrently (eg. the lock is dropped in the loop body). An
+ * exception to this is if the cursor element (pos) is pinned in the list,
+ * and list_safe_reset_next is called after re-taking the lock and before
+ * completing the current iteration of the loop body.
+ */
+#define list_safe_reset_next(pos, type, n, member) \
+ n = list_next_entry(pos, type, member)
+
+#endif /* USBH_LIST_H_ */