diff options
Diffstat (limited to 'os/hal/include')
26 files changed, 2040 insertions, 376 deletions
diff --git a/os/hal/include/hal_community.h b/os/hal/include/hal_community.h index 75b3916..cdedad6 100644 --- a/os/hal/include/hal_community.h +++ b/os/hal/include/hal_community.h @@ -63,6 +63,18 @@  #define HAL_USE_USBH                        FALSE
  #endif
 +#if !defined(HAL_USE_USB_HID)
 +#define HAL_USE_USB_HID                     FALSE
 +#endif
 +
 +#if !defined(HAL_USE_USB_MSD)
 +#define HAL_USE_USB_MSD                     FALSE
 +#endif
 +
 +#if !defined(HAL_USE_COMP)
 +#define HAL_USE_COMP                        FALSE
 +#endif
 +
  /* Abstract interfaces.*/
  /* Shared headers.*/
 @@ -74,11 +86,14 @@  #include "hal_usbh.h"
  #include "hal_timcap.h"
  #include "hal_qei.h"
 +#include "hal_comp.h"
  /* Complex drivers.*/
  #include "hal_onewire.h"
  #include "hal_crc.h"
  #include "hal_eeprom.h"
 +#include "hal_usb_hid.h"
 +#include "hal_usb_msd.h"
  /*===========================================================================*/
  /* Driver constants.                                                         */
 diff --git a/os/hal/include/hal_comp.h b/os/hal/include/hal_comp.h new file mode 100644 index 0000000..835704d --- /dev/null +++ b/os/hal/include/hal_comp.h @@ -0,0 +1,131 @@ +/* +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio +              Copyright (C) 2017 Fabien Poussin (fabien.poussin (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 HAL_COMP_H_ +#define HAL_COMP_H_ + +#include "hal.h" + + +#if (HAL_USE_COMP == 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 { +  COMP_UNINIT = 0,                   /**< Not initialized.                   */ +  COMP_STOP = 1,                     /**< Stopped.                           */ +  COMP_READY = 2,                    /**< Ready.                             */ +  COMP_ACTIVE = 3,                   /**< Active cycle phase.                */ +} compstate_t; + +/** + * @brief   Type of a structure representing an COMP driver. + */ +typedef struct COMPDriver COMPDriver; + +/** + * @brief   COMP notification callback type. + * + * @param[in] comp      pointer to a @p COMPDriver object + */ +typedef void (*compcallback_t)(COMPDriver *comp); + +#include "hal_comp_lld.h" + +/*===========================================================================*/ +/* Driver macros.                                                            */ +/*===========================================================================*/ + +/** + * @name    Macro Functions + * @{ + */ +/** + * @brief   Enables the input capture. + * + * @param[in] comp      pointer to the @p COMPDriver object + * + * @iclass + */ +#define compEnableI(comp) comp_lld_enable(comp) + +/** + * @brief   Disables the input capture. + * + * @param[in] comp      pointer to the @p COMPDriver object + * + * @iclass + */ +#define compDisableI(comp) comp_lld_disable(comp) +/** @} */ + + +/** + * @name    Low Level driver helper macros + * @{ + */ + +/** + * @brief   Common ISR code, main event. + * + * @param[in] comp      pointer to the @p COMPDriver object + * + * @notapi + */ +#define _comp_isr_invoke_cb(comp) {                                 \ +  (comp)->config->cb(comp);                                        \ +} +/** @} */ + +/*===========================================================================*/ +/* External declarations.                                                    */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +  void compInit(void); +  void compObjectInit(COMPDriver *comp); +  void compStart(COMPDriver *comp, const COMPConfig *config); +  void compStop(COMPDriver *comp); +  void compEnable(COMPDriver *comp); +  void compDisable(COMPDriver *comp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_COMP */ + + +#endif /* HAL_COMP_H_ */ diff --git a/os/hal/include/hal_crc.h b/os/hal/include/hal_crc.h index 8c4c895..d7ef10f 100644 --- a/os/hal/include/hal_crc.h +++ b/os/hal/include/hal_crc.h @@ -14,8 +14,8 @@      limitations under the License.  */ -#ifndef _CRC_H_ -#define _CRC_H_ +#ifndef HAL_CRC_H_ +#define HAL_CRC_H_  #if (HAL_USE_CRC == TRUE) || defined(__DOXYGEN__) @@ -153,6 +153,6 @@ extern "C" {  #endif /* HAL_USE_CRC */ -#endif /* _CRC_H_ */ +#endif /* HAL_CRC_H_ */  /** @} */ diff --git a/os/hal/include/hal_ee24xx.h b/os/hal/include/hal_ee24xx.h index ab12fd1..00cdc95 100644 --- a/os/hal/include/hal_ee24xx.h +++ b/os/hal/include/hal_ee24xx.h @@ -4,8 +4,8 @@    The work is provided "as is" without warranty of any kind, neither express nor implied.  */ -#ifndef EE24XX_H -#define EE24XX_H +#ifndef HAL_EE24XX_H +#define HAL_EE24XX_H  #include "hal.h" @@ -61,4 +61,4 @@ typedef struct {  #endif /* #if defined(EEPROM_USE_EE24XX) && EEPROM_USE_EE24XX */ -#endif // EE24XX_H +#endif // HAL_EE24XX_H diff --git a/os/hal/include/hal_ee25xx.h b/os/hal/include/hal_ee25xx.h index fc2ad6f..e520bd6 100644 --- a/os/hal/include/hal_ee25xx.h +++ b/os/hal/include/hal_ee25xx.h @@ -4,8 +4,8 @@    The work is provided "as is" without warranty of any kind, neither express nor implied.  */ -#ifndef EE25XX_H -#define EE25XX_H +#ifndef HAL_EE25XX_H +#define HAL_EE25XX_H  #include "hal.h" @@ -60,4 +60,4 @@ EepromFileStream *SPIEepromFileOpen(SPIEepromFileStream *efs,  #endif /* #if defined(EEPROM_USE_EE25XX) && EEPROM_USE_EE25XX */ -#endif // EE25XX_H +#endif // HAL_EE25XX_H diff --git a/os/hal/include/hal_eeprom.h b/os/hal/include/hal_eeprom.h index cd05e14..25e03bd 100644 --- a/os/hal/include/hal_eeprom.h +++ b/os/hal/include/hal_eeprom.h @@ -26,10 +26,9 @@    The work is provided "as is" without warranty of any kind, neither express nor implied.  */ -#ifndef __EEPROM_H__ -#define __EEPROM_H__ +#ifndef HAL_EEPROM_H_ +#define HAL_EEPROM_H_ -#include "ch.h"  #include "hal.h"  #ifndef EEPROM_USE_EE25XX @@ -140,4 +139,4 @@ msg_t eepfs_get(void *ip);  #include "hal_ee25xx.h"  #endif /* #if defined(HAL_USE_EEPROM) && HAL_USE_EEPROM */ -#endif /* __EEPROM_H__ */ +#endif /* HAL_EEPROM_H_ */ diff --git a/os/hal/include/hal_eicu.h b/os/hal/include/hal_eicu.h index d4b0ed2..8b4b07d 100644 --- a/os/hal/include/hal_eicu.h +++ b/os/hal/include/hal_eicu.h @@ -22,8 +22,8 @@     32-bit timers and timers with single capture/compare channels.  */ -#ifndef _EICU_H_ -#define _EICU_H_ +#ifndef HAL_EICU_H_ +#define HAL_EICU_H_  #if (HAL_USE_EICU == TRUE) || defined(__DOXYGEN__) @@ -186,6 +186,6 @@ extern "C" {  #endif /* HAL_USE_EICU */ -#endif /* _EICU_H_ */ +#endif /* HAL_EICU_H_ */  /** @} */ diff --git a/os/hal/include/hal_nand.h b/os/hal/include/hal_nand.h index d5a1c04..f907152 100644 --- a/os/hal/include/hal_nand.h +++ b/os/hal/include/hal_nand.h @@ -15,15 +15,15 @@  */  /** - * @file    nand.h + * @file    hal_nand.h   * @brief   NAND Driver macros and structures.   *   * @addtogroup NAND   * @{   */ -#ifndef _NAND_H_ -#define _NAND_H_ +#ifndef HAL_NAND_H_ +#define HAL_NAND_H_  #if (HAL_USE_NAND == TRUE) || defined(__DOXYGEN__) @@ -82,6 +82,7 @@ typedef enum {    NAND_READ = 6,                     /**< Reading from NAND.              */    NAND_DMA_TX = 7,                   /**< DMA transmitting.               */    NAND_DMA_RX = 8,                   /**< DMA receiving.                  */ +  NAND_RESET = 9,                    /**< Software reset in progress.     */  } nandstate_t;  /** @@ -106,21 +107,21 @@ extern "C" {    void nandObjectInit(NANDDriver *nandp);    void nandStart(NANDDriver *nandp, const NANDConfig *config, bitmap_t *bb_map);    void nandStop(NANDDriver *nandp); +  uint8_t nandErase(NANDDriver *nandp, uint32_t block);    void nandReadPageWhole(NANDDriver *nandp, uint32_t block, uint32_t page, -                         uint8_t *data, size_t datalen); -  void nandMarkBad(NANDDriver *nandp, uint32_t block); +                         void *data, size_t datalen);    void nandReadPageData(NANDDriver *nandp, uint32_t block, uint32_t page, -                        uint8_t *data, size_t datalen, uint32_t *ecc); +                        void *data, size_t datalen, uint32_t *ecc);    void nandReadPageSpare(NANDDriver *nandp, uint32_t block, uint32_t page, -                         uint8_t *spare, size_t sparelen); +                         void *spare, size_t sparelen);    uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block, uint32_t page, -                             const uint8_t *data, size_t datalen); +                             const void *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); +                            const void *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); +                             const void *spare, size_t sparelen); +  uint16_t nandReadBadMark(NANDDriver *nandp, uint32_t block, uint32_t page); +  void nandMarkBad(NANDDriver *nandp, uint32_t block);    bool nandIsBad(NANDDriver *nandp, uint32_t block);  #if NAND_USE_MUTUAL_EXCLUSION    void nandAcquireBus(NANDDriver *nandp); diff --git a/os/hal/include/hal_onewire.h b/os/hal/include/hal_onewire.h index 2d27f48..bbaf77b 100644 --- a/os/hal/include/hal_onewire.h +++ b/os/hal/include/hal_onewire.h @@ -15,15 +15,15 @@  */  /** - * @file    onewire.h + * @file    hal_onewire.h   * @brief   1-wire Driver macros and structures.   *   * @addtogroup onewire   * @{   */ -#ifndef _ONEWIRE_H_ -#define _ONEWIRE_H_ +#ifndef HAL_ONEWIRE_H_ +#define HAL_ONEWIRE_H_  #if (HAL_USE_ONEWIRE == TRUE) || defined(__DOXYGEN__) @@ -59,11 +59,13 @@  /*===========================================================================*/  /* Driver pre-compile time settings.                                         */  /*===========================================================================*/ +#if ONEWIRE_SYNTH_SEARCH_TEST && !ONEWIRE_USE_SEARCH_ROM +#error "Synthetic search rom test needs ONEWIRE_USE_SEARCH_ROM" +#endif  /*===========================================================================*/  /* Derived constants and error checks.                                       */  /*===========================================================================*/ -  #if !HAL_USE_PWM  #error "1-wire Driver requires HAL_USE_PWM"  #endif @@ -328,7 +330,6 @@ 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); @@ -342,8 +343,8 @@ extern "C" {                            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, uint8_t bit); -  uint_fast8_t _synth_ow_read_bit(void); +  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 @@ -352,7 +353,7 @@ extern "C" {  #endif /* HAL_USE_ONEWIRE */ -#endif /* _ONEWIRE_H_ */ +#endif /* HAL_ONEWIRE_H_ */  /** @} */ diff --git a/os/hal/include/hal_qei.h b/os/hal/include/hal_qei.h index 92f03fc..ce4a089 100644 --- a/os/hal/include/hal_qei.h +++ b/os/hal/include/hal_qei.h @@ -65,8 +65,36 @@ typedef struct QEIDriver QEIDriver;   */
  typedef void (*qeicallback_t)(QEIDriver *qeip);
 +/**
 + * @brief   Driver possible handling of counter overflow/underflow.
 + *
 + * @details When counter is going to overflow, the new value is
 + *          computed according to this mode in such a way that 
 + *          the counter will either wrap around, stay unchange 
 + *          or reach min/max
 + *
 + * @note    All driver implementation should support the
 + *          QEI_OVERFLOW_WRAP mode.
 + *
 + * @note    Mode QEI_OVERFLOW_DISCARD and QEI_OVERFLOW_MINMAX are included
 + *          if QEI_USE_OVERFLOW_DISCARD and QEI_USE_OVERFLOW_MINMAX are
 + *          set to TRUE in halconf_community.h and are not necessary supported
 + *          by all drivers
 + */
 +typedef enum {
 +  QEI_OVERFLOW_WRAP    = 0,     /**< Counter value will wrap around.        */
 +#if QEI_USE_OVERFLOW_DISCARD == TRUE
 +  QEI_OVERFLOW_DISCARD = 1,     /**< Counter doesn't change.                */
 +#endif
 +#if QEI_USE_OVERFLOW_MINMAX == TRUE
 +  QEI_OVERFLOW_MINMAX  = 2,     /**< Counter will be updated upto min or max.*/
 +#endif
 +} qeioverflow_t;
 +
 +
  #include "hal_qei_lld.h"
 +
  /*===========================================================================*/
  /* Driver macros.                                                            */
  /*===========================================================================*/
 @@ -119,6 +147,7 @@ extern "C" {    qeicnt_t qeiGetCount(QEIDriver *qeip);
    qeidelta_t qeiUpdate(QEIDriver *qeip);
    qeidelta_t qeiUpdateI(QEIDriver *qeip);
 +  qeidelta_t qeiAdjustI(QEIDriver *qeip, qeidelta_t delta);
  #ifdef __cplusplus
  }
  #endif
 diff --git a/os/hal/include/hal_rng.h b/os/hal/include/hal_rng.h index 0e3c484..dc146c7 100644 --- a/os/hal/include/hal_rng.h +++ b/os/hal/include/hal_rng.h @@ -14,8 +14,8 @@      limitations under the License.  */ -#ifndef _RNG_H_ -#define _RNG_H_ +#ifndef HAL_RNG_H_ +#define HAL_RNG_H_  #if (HAL_USE_RNG == TRUE) || defined(__DOXYGEN__) @@ -131,6 +131,6 @@ extern "C" {  #endif /* HAL_USE_RNG */ -#endif /* _RNG_H_ */ +#endif /* HAL_RNG_H_ */  /** @} */ diff --git a/os/hal/include/hal_timcap.h b/os/hal/include/hal_timcap.h index bd43dd1..a5db7d8 100644 --- a/os/hal/include/hal_timcap.h +++ b/os/hal/include/hal_timcap.h @@ -19,17 +19,16 @@  */  /** - * @file    timcap.h + * @file    hal_timcap.h   * @brief   TIMCAP Driver macros and structures.   *   * @addtogroup TIMCAP   * @{   */ -#ifndef _TIMCAP_H_ -#define _TIMCAP_H_ +#ifndef HAL_TIMCAP_H_ +#define HAL_TIMCAP_H_ -#include "ch.h"  #include "hal.h"  #if (HAL_USE_TIMCAP == TRUE) || defined(__DOXYGEN__) @@ -201,6 +200,6 @@ extern "C" {  #endif /* HAL_USE_TIMCAP */ -#endif /* _TIMCAP_H_ */ +#endif /* HAL_TIMCAP_H_ */  /** @} */ diff --git a/os/hal/include/hal_usb_hid.h b/os/hal/include/hal_usb_hid.h new file mode 100644 index 0000000..d50c455 --- /dev/null +++ b/os/hal/include/hal_usb_hid.h @@ -0,0 +1,571 @@ +/*
 +    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_INPUT                    0x80
 +#define HID_REPORT_OUTPUT                   0x90
 +#define HID_REPORT_COLLECTION               0xA0
 +#define HID_REPORT_FEATURE                  0xB0
 +#define HID_REPORT_END_COLLECTION           0xC0
 +
 +#define HID_REPORT_USAGE_PAGE               0x04
 +#define HID_REPORT_LOGICAL_MINIMUM          0x14
 +#define HID_REPORT_LOGICAL_MAXIMUM          0x24
 +#define HID_REPORT_PHYSICAL_MINIMUM         0x34
 +#define HID_REPORT_PHYSICAL_MAXIMUM         0x44
 +#define HID_REPORT_UNIT_EXPONENT            0x54
 +#define HID_REPORT_UNIT                     0x64
 +#define HID_REPORT_REPORT_SIZE              0x74
 +#define HID_REPORT_REPORT_ID                0x84
 +#define HID_REPORT_REPORT_COUNT             0x94
 +#define HID_REPORT_REPORT_PUSH              0xA4
 +#define HID_REPORT_REPORT_POP               0xB4
 +
 +#define HID_REPORT_USAGE                    0x08
 +#define HID_REPORT_USAGE_MINIMUM            0x18
 +#define HID_REPORT_USAGE_MAXIMUM            0x28
 +#define HID_REPORT_DESIGNATOR_INDEX         0x38
 +#define HID_REPORT_DESIGNATOR_MINUMUM       0x48
 +#define HID_REPORT_DESIGNATOR_MAXIMUM       0x58
 +#define HID_REPORT_STRING_INDEX             0x78
 +#define HID_REPORT_STRING_MINUMUM           0x88
 +#define HID_REPORT_STRING_MAXIMUM           0x98
 +#define HID_REPORT_DELIMITER                0xA8
 +/** @} */
 +
 +/**
 + * @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
 +#define HID_USAGE_PAGE_VENDOR               0xFF00
 +/** @} */
 +
 +/**
 + * @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 item types definitions
 + * @{
 + */
 +#define HID_ITEM_DATA                       0x00
 +#define HID_ITEM_CNST                       0x01
 +#define HID_ITEM_ARR                        0x00
 +#define HID_ITEM_VAR                        0x02
 +#define HID_ITEM_ABS                        0x00
 +#define HID_ITEM_REL                        0x04
 +#define HID_ITEM_NWRP                       0x00
 +#define HID_ITEM_WRP                        0x08
 +#define HID_ITEM_LIN                        0x00
 +#define HID_ITEM_NLIN                       0x10
 +#define HID_ITEM_PRF                        0x00
 +#define HID_ITEM_NPRF                       0x20
 +#define HID_ITEM_NNUL                       0x00
 +#define HID_ITEM_NUL                        0x40
 +#define HID_ITEM_NVOL                       0x00
 +#define HID_ITEM_VOL                        0x80
 +
 +#define HID_ITEM_DATA_VAR_ABS               (HID_ITEM_DATA |                \
 +                                             HID_ITEM_VAR |                 \
 +                                             HID_ITEM_ABS)
 +#define HID_ITEM_CNST_VAR_ABS               (HID_ITEM_CNST |                \
 +                                             HID_ITEM_VAR |                 \
 +                                             HID_ITEM_ABS)
 +#define HID_ITEM_DATA_VAR_REL               (HID_ITEM_DATA |                \
 +                                             HID_ITEM_VAR |                 \
 +                                             HID_ITEM_REL)
 +/** @} */
 +
 +/**
 + * @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 item helper macro (Single byte).
 + */
 +#define HID_ITEM_B(id, value)                                               \
 +  USB_DESC_BYTE(id | 0x01),                                                 \
 +  USB_DESC_BYTE(value)
 +
 +/**
 + * @brief   HID Report item helper macro (Double byte).
 + */
 +#define HID_ITEM_W(id, value)                                               \
 +  USB_DESC_BYTE(id | 0x02),                                                 \
 +  USB_DESC_WORD(value)
 +
 +/**
 + * @brief   HID Report Usage Page item helper macro (Single byte).
 + */
 +#define HID_USAGE_PAGE_B(up)                                                \
 +  HID_ITEM_B(HID_REPORT_USAGE_PAGE, up)
 +
 +/**
 + * @brief   HID Report Usage Page item helper macro (Double byte).
 + */
 +#define HID_USAGE_PAGE_W(up)                                                \
 +  HID_ITEM_W(HID_REPORT_USAGE_PAGE, up)
 +
 +/**
 + * @brief   HID Report Usage item helper macro (Single byte).
 + */
 +#define HID_USAGE_B(u)                                                      \
 +  HID_ITEM_B(HID_REPORT_USAGE, u)
 +
 +/**
 + * @brief   HID Report Usage item helper macro (Double byte).
 + */
 +#define HID_USAGE_W(u)                                                      \
 +  HID_ITEM_W(HID_REPORT_USAGE, u)
 +
 +/**
 + * @brief   HID Report Collection item helper macro (Single Byte).
 + */
 +#define HID_COLLECTION_B(c)                                                 \
 +  HID_ITEM_B(HID_REPORT_COLLECTION, c)
 +
 +/**
 + * @brief   HID Report Collection item helper macro (Double Byte).
 + */
 +#define HID_COLLECTION_W(c)                                                 \
 +  HID_ITEM_W(HID_REPORT_COLLECTION, 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)                                              \
 +  HID_ITEM_B(HID_REPORT_USAGE_MINIMUM, x)
 +  
 +/**
 + * @brief   HID Report Usage Minimum item helper macro (Double byte).
 + */
 +#define HID_USAGE_MINIMUM_W(x)                                              \
 +  HID_ITEM_W(HID_REPORT_USAGE_MINIMUM, x)
 +
 +/**
 + * @brief   HID Report Usage Maximum item helper macro (Single byte).
 + */
 +#define HID_USAGE_MAXIMUM_B(x)                                              \
 +  HID_ITEM_B(HID_REPORT_USAGE_MAXIMUM, x)
 +  
 +/**
 + * @brief   HID Report Usage Maximum item helper macro (Double byte).
 + */
 +#define HID_USAGE_MAXIMUM_W(x)                                              \
 +  HID_ITEM_W(HID_REPORT_USAGE_MAXIMUM, x)
 +
 +/**
 + * @brief   HID Report Logical Minimum item helper macro (Single byte).
 + */
 +#define HID_LOGICAL_MINIMUM_B(x)                                            \
 +  HID_ITEM_B(HID_REPORT_LOGICAL_MINIMUM, x)
 +
 +/**
 + * @brief   HID Report Logical Minimum item helper macro (Double byte).
 + */
 +#define HID_LOGICAL_MINIMUM_W(x)                                            \
 +  HID_ITEM_W(HID_REPORT_LOGICAL_MINIMUM, x)
 +
 +/**
 + * @brief   HID Report Logical Maximum item helper macro (Single byte).
 + */
 +#define HID_LOGICAL_MAXIMUM_B(x)                                            \
 +  HID_ITEM_B(HID_REPORT_LOGICAL_MAXIMUM, x)
 +
 +/**
 + * @brief   HID Report Logical Maximum item helper macro (Double byte).
 + */
 +#define HID_LOGICAL_MAXIMUM_W(x)                                            \
 +  HID_ITEM_W(HID_REPORT_LOGICAL_MAXIMUM, x)
 +
 +/**
 + * @brief   HID Report ID item helper macro (Single byte).
 + */
 +#define HID_REPORT_ID_B(x)                                               \
 +  HID_ITEM_B(HID_REPORT_REPORT_ID, x)
 +
 +/**
 + * @brief   HID Report ID item helper macro (Double byte).
 + */
 +#define HID_REPORT_ID_W(x)                                               \
 +  HID_ITEM_W(HID_REPORT_REPORT_ID, x)
 +  
 +/**
 + * @brief   HID Report Count item helper macro (Single byte).
 + */
 +#define HID_REPORT_COUNT_B(x)                                               \
 +  HID_ITEM_B(HID_REPORT_REPORT_COUNT, x)
 +
 +/**
 + * @brief   HID Report Count item helper macro (Double byte).
 + */
 +#define HID_REPORT_COUNT_W(x)                                               \
 +  HID_ITEM_W(HID_REPORT_REPORT_COUNT, x)
 +
 +/**
 + * @brief   HID Report Size item helper macro (Single byte).
 + */
 +#define HID_REPORT_SIZE_B(x)                                                \
 +  HID_ITEM_B(HID_REPORT_REPORT_SIZE, x)
 +
 +/**
 + * @brief   HID Report Size item helper macro (Double byte).
 + */
 +#define HID_REPORT_SIZE_W(x)                                                \
 +  HID_ITEM_W(HID_REPORT_REPORT_SIZE, x)
 +
 +/**
 + * @brief   HID Report Input item helper macro (Single byte).
 + */
 +#define HID_INPUT_B(x)                                                      \
 +  HID_ITEM_B(HID_REPORT_INPUT, x)
 +
 +/**
 + * @brief   HID Report Input item helper macro (Double byte).
 + */
 +#define HID_INPUT_W(x)                                                      \
 +  HID_ITEM_W(HID_REPORT_INPUT, x)
 +/** @} */
 +
 +/**
 + * @brief   HID Report Output item helper macro (Single byte).
 + */
 +#define HID_OUTPUT_B(x)                                                     \
 +  HID_ITEM_B(HID_REPORT_OUTPUT, x)
 +
 +/**
 + * @brief   HID Report Output item helper macro (Double byte).
 + */
 +#define HID_OUTPUT_W(x)                                                     \
 +  HID_ITEM_W(HID_REPORT_OUTPUT, 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/os/hal/include/hal_usb_msd.h b/os/hal/include/hal_usb_msd.h new file mode 100644 index 0000000..0fe03e4 --- /dev/null +++ b/os/hal/include/hal_usb_msd.h @@ -0,0 +1,196 @@ +/* +    ChibiOS/HAL - Copyright (C) 2016 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_usb_msd.h + * @brief   USM mass storage device driver macros and structures. + * + * @addtogroup usb_msd + * @{ + */ + +#ifndef HAL_USB_MSD_H +#define HAL_USB_MSD_H + +#if (HAL_USE_USB_MSD == TRUE) || defined(__DOXYGEN__) + +#include "lib_scsi.h" + +/*===========================================================================*/ +/* Driver constants.                                                         */ +/*===========================================================================*/ + +#define USB_MSD_DATA_EP                 0x01 + +/*===========================================================================*/ +/* Driver pre-compile time settings.                                         */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks.                                       */ +/*===========================================================================*/ + +#if !HAL_USE_USB +#error "Mass storage Driver requires HAL_USE_USB" +#endif + +#if !USB_USE_WAIT +#error "Mass storage Driver requires USB_USE_WAIT" +#endif + +/*===========================================================================*/ +/* Driver data structures and types.                                         */ +/*===========================================================================*/ + +/** + * @brief   Type of a structure representing an USB mass storage driver. + */ +typedef struct USBMassStorageDriver USBMassStorageDriver; + +/** + * @brief   Type of a driver state machine possible states. + */ +typedef enum { +  USB_MSD_UNINIT = 0, +  USB_MSD_STOP, +  USB_MSD_READY, +} usbmsdstate_t; + +/** + * @brief   Represents command block wrapper structure. + * @details See USB Mass Storage Class Specification. + */ +typedef struct PACKED_VAR { +  uint32_t  signature; +  uint32_t  tag; +  uint32_t  data_len; +  uint8_t   flags; +  uint8_t   lun; +  uint8_t   cmd_len; +  uint8_t   cmd_data[16]; +} msd_cbw_t; + +/** + * @brief   Represents command status wrapper structure. + * @details See USB Mass Storage Class Specification. + */ +typedef struct PACKED_VAR { +  uint32_t  signature; +  uint32_t  tag; +  uint32_t  data_residue; +  uint8_t   status; +} msd_csw_t; + +/** + * @brief   Transport handler passed to SCSI layer. + */ +typedef struct { +  /** +   * @brief   Pointer to the @p USBDriver object. +   */ +  USBDriver *usbp; +  /** +   * @brief   USB endpoint number. +   */ +  usbep_t   ep; +} usb_scsi_transport_handler_t; + + +/** + * @brief   Structure representing an USB mass storage driver. + */ +struct USBMassStorageDriver { +  /** +   * @brief   Pointer to the @p USBDriver object. +   */ +  USBDriver                     *usbp; +  /** +   * @brief   Driver state. +   */ +  usbmsdstate_t                 state; +  /** +   * @brief   CBW structure. +   */ +  msd_cbw_t                     cbw; +  /** +   * @brief   CSW structure. +   */ +  msd_csw_t                     csw; +  /** +   * @brief   Thread working area. +   */ +  THD_WORKING_AREA(             waMSDWorker, 512); +  /** +   * @brief   Worker thread handler. +   */ +  thread_reference_t            worker; +  /** +   * @brief   SCSI target driver structure. +   */ +  SCSITarget                    scsi_target; +  /** +   * @brief   SCSI target configuration structure. +   */ +  SCSITargetConfig              scsi_config; +  /** +   * @brief   SCSI transport structure. +   */ +  SCSITransport                 scsi_transport; +  /** +   * @brief   SCSI over USB transport handler structure. +   */ +  usb_scsi_transport_handler_t  usb_scsi_transport_handler; +}; + + +/*===========================================================================*/ +/* Driver macros.                                                            */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations.                                                    */ +/*===========================================================================*/ + +extern USBMassStorageDriver USBMSD1; + +#ifdef __cplusplus +extern "C" { +#endif +  void msdObjectInit(USBMassStorageDriver *msdp); +  void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp, +                BaseBlockDevice *blkdev, uint8_t *blkbuf, +                const scsi_inquiry_response_t *scsi_inquiry_response, +                const scsi_unit_serial_number_inquiry_response_t *serialInquiry); +  void msdStop(USBMassStorageDriver *msdp); +  bool msd_request_hook(USBDriver *usbp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_USB_MSD */ + +#endif /* HAL_USB_MSD_H */ + +/** @} */ + + + + + + + + + diff --git a/os/hal/include/hal_usbh.h b/os/hal/include/hal_usbh.h index 5fd0047..1ed6416 100644 --- a/os/hal/include/hal_usbh.h +++ b/os/hal/include/hal_usbh.h @@ -1,6 +1,6 @@  /* -    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio -              Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail) +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio +              Copyright (C) 2015..2017 Diego Ismirlian, (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. @@ -15,11 +15,14 @@      limitations under the License.  */ -#ifndef USBH_H_ -#define USBH_H_ +#ifndef HAL_USBH_H_ +#define HAL_USBH_H_  #include "hal.h" +#ifndef HAL_USE_USBH +#define HAL_USE_USBH FALSE +#endif  #ifndef HAL_USBH_USE_FTDI  #define HAL_USBH_USE_FTDI FALSE @@ -37,19 +40,26 @@  #define HAL_USBH_USE_UVC FALSE  #endif +#ifndef HAL_USBH_USE_AOA +#define HAL_USBH_USE_AOA FALSE +#endif + +#ifndef HAL_USBH_USE_HID +#define HAL_USBH_USE_HID FALSE +#endif + +#ifndef HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS +#define HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS	FALSE +#endif + +#define HAL_USBH_USE_IAD     HAL_USBH_USE_UVC +  #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.                                       */  /*===========================================================================*/ @@ -66,6 +76,7 @@ enum usbh_status {  	USBH_STATUS_SUSPENDED,  }; +/* These correspond to the USB spec */  enum usbh_devstatus {  	USBH_DEVSTATUS_DISCONNECTED = 0,  	USBH_DEVSTATUS_ATTACHED, @@ -104,13 +115,11 @@ 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,  }; @@ -145,7 +154,8 @@ 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) +#define USBH_DEFINE_BUFFER(var)	USBH_LLD_DEFINE_BUFFER(var) +#define USBH_DECLARE_STRUCT_MEMBER(member) USBH_LLD_DECLARE_STRUCT_MEMBER(member)  struct usbh_urb {  	usbh_ep_t *ep; @@ -198,9 +208,8 @@ struct usbh_device {  	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); +	USBH_DECLARE_STRUCT_MEMBER(usbh_device_descriptor_t devDesc); +	USBH_DECLARE_STRUCT_MEMBER(usbh_config_descriptor_t basicConfigDesc);  	uint8_t *fullConfigurationDescriptor;  	uint8_t keepFullCfgDesc; @@ -258,14 +267,6 @@ struct USBHDriver {  /* External declarations.                                                    */  /*===========================================================================*/ -#if STM32_USBH_USE_OTG1 -extern USBHDriver USBHD1; -#endif - -#if STM32_USBH_USE_OTG2 -extern USBHDriver USBHD2; -#endif -  /*===========================================================================*/  /* Main driver API.		                                                     */ @@ -351,10 +352,8 @@ extern "C" {  		osalDbgCheck(ep != 0);  		osalDbgCheckClassS();  		osalDbgAssert(ep->status != USBH_EPSTATUS_UNINITIALIZED, "invalid state"); -		if (ep->status == USBH_EPSTATUS_CLOSED) { -			osalOsRescheduleS(); +		if (ep->status == USBH_EPSTATUS_CLOSED)  			return; -		}  		usbh_lld_ep_close(ep);  	}  	static inline void usbhEPClose(usbh_ep_t *ep) { @@ -362,11 +361,7 @@ extern "C" {  		usbhEPCloseS(ep);  		osalSysUnlock();  	} -	static inline void usbhEPResetI(usbh_ep_t *ep) { -		osalDbgCheckClassI(); -		osalDbgCheck(ep != NULL); -		usbh_lld_epreset(ep); -	} +	bool usbhEPReset(usbh_ep_t *ep);  	static inline bool usbhEPIsPeriodic(usbh_ep_t *ep) {  		osalDbgCheck(ep != NULL);  		return (ep->type & 1) != 0; @@ -389,6 +384,22 @@ extern "C" {  	void usbhURBCancelAndWaitS(usbh_urb_t *urb);  	msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout); +	static inline void usbhURBSubmit(usbh_urb_t *urb) { +		osalSysLock(); +		usbhURBSubmitI(urb); +		osalOsRescheduleS(); +		osalSysUnlock(); +	} + +	static inline bool usbhURBCancel(usbh_urb_t *urb) { +		bool ret; +		osalSysLock(); +		ret = usbhURBCancelI(urb); +		osalOsRescheduleS(); +		osalSysUnlock(); +		return ret; +	} +  	/* Main loop */  	void usbhMainLoop(USBHDriver *usbh); @@ -403,14 +414,13 @@ extern "C" {  typedef struct usbh_classdriver_vmt usbh_classdriver_vmt_t;  struct usbh_classdriver_vmt { +	void (*init)(void);  	usbh_baseclassdriver_t *(*load)(usbh_device_t *dev,	const uint8_t *descriptor, uint16_t rem);  	void (*unload)(usbh_baseclassdriver_t *drv); +	/* TODO: add power control, suspend, etc */  };  struct usbh_classdriverinfo { -	int16_t class; -	int16_t subclass; -	int16_t protocol;  	const char *name;  	const usbh_classdriver_vmt_t *vmt;  }; @@ -424,13 +434,6 @@ struct usbh_baseclassdriver {  	_usbh_base_classdriver_data  }; - -/*===========================================================================*/ -/* Helper functions.				                                         */ -/*===========================================================================*/ -#include <usbh/desciter.h>	/* descriptor iterators */ -#include <usbh/debug.h>		/* debug */ -  #endif -#endif /* USBH_H_ */ +#endif /* HAL_USBH_H_ */ diff --git a/os/hal/include/usbh/debug.h b/os/hal/include/usbh/debug.h index 5120121..d3bdee7 100644 --- a/os/hal/include/usbh/debug.h +++ b/os/hal/include/usbh/debug.h @@ -1,6 +1,6 @@  /*
 -    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 -              Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
 +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
 +              Copyright (C) 2015..2017 Diego Ismirlian, (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.
 @@ -23,8 +23,6 @@  #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);
 diff --git a/os/hal/include/usbh/defs.h b/os/hal/include/usbh/defs.h index c3d8a9a..5e0c466 100644 --- a/os/hal/include/usbh/defs.h +++ b/os/hal/include/usbh/defs.h @@ -1,6 +1,6 @@  /*
 -    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 -              Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
 +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
 +              Copyright (C) 2015..2017 Diego Ismirlian, (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.
 @@ -25,12 +25,12 @@  #include "osal.h"
  #ifdef __IAR_SYSTEMS_ICC__
 -#define PACKED_STRUCT typedef PACKED_VAR struct
 +#define PACKED_STRUCT PACKED_VAR struct
  #else
 -#define PACKED_STRUCT typedef struct PACKED_VAR
 +#define PACKED_STRUCT struct PACKED_VAR
  #endif
 -PACKED_STRUCT {
 +typedef PACKED_STRUCT {
  	uint8_t  bLength;
  	uint8_t  bDescriptorType;
  	uint16_t bcdUSB;
 @@ -49,7 +49,7 @@ PACKED_STRUCT {  #define USBH_DT_DEVICE                   0x01
  #define USBH_DT_DEVICE_SIZE              18
 -PACKED_STRUCT {
 +typedef PACKED_STRUCT {
  	uint8_t  bLength;
  	uint8_t  bDescriptorType;
  	uint16_t wTotalLength;
 @@ -62,7 +62,7 @@ PACKED_STRUCT {  #define USBH_DT_CONFIG                   0x02
  #define USBH_DT_CONFIG_SIZE              9
 -PACKED_STRUCT {
 +typedef PACKED_STRUCT {
  	uint8_t  bLength;
  	uint8_t  bDescriptorType;
  	uint16_t wData[1];
 @@ -70,7 +70,7 @@ PACKED_STRUCT {  #define USBH_DT_STRING                   0x03
  #define USBH_DT_STRING_SIZE              2
 -PACKED_STRUCT {
 +typedef PACKED_STRUCT {
  	uint8_t  bLength;
  	uint8_t  bDescriptorType;
  	uint8_t  bInterfaceNumber;
 @@ -84,7 +84,7 @@ PACKED_STRUCT {  #define USBH_DT_INTERFACE                0x04
  #define USBH_DT_INTERFACE_SIZE           9
 -PACKED_STRUCT {
 +typedef PACKED_STRUCT {
  	uint8_t	bLength;
  	uint8_t	bDescriptorType;
  	uint8_t	bEndpointAddress;
 @@ -95,7 +95,7 @@ PACKED_STRUCT {  #define USBH_DT_ENDPOINT                 0x05
  #define USBH_DT_ENDPOINT_SIZE            7
 -PACKED_STRUCT {
 +typedef PACKED_STRUCT {
  	uint8_t  bLength;
  	uint8_t  bDescriptorType;
  	uint8_t  bFirstInterface;
 @@ -108,7 +108,7 @@ PACKED_STRUCT {  #define USBH_DT_INTERFACE_ASSOCIATION    	0x0b
  #define USBH_DT_INTERFACE_ASSOCIATION_SIZE	8
 -PACKED_STRUCT {
 +typedef PACKED_STRUCT {
  	uint8_t  bDescLength;
  	uint8_t  bDescriptorType;
  	uint8_t  bNbrPorts;
 @@ -120,7 +120,7 @@ PACKED_STRUCT {  #define USBH_DT_HUB				    	0x29
  #define USBH_DT_HUB_SIZE		    	(7 + 4)
 -PACKED_STRUCT {
 +typedef PACKED_STRUCT {
  	uint8_t  bmRequestType;
  	uint8_t  bRequest;
  	uint16_t wValue;
 @@ -141,18 +141,17 @@ PACKED_STRUCT {  #define USBH_REQ_SET_INTERFACE           0x0B
  #define USBH_REQ_SYNCH_FRAME             0x0C
 +#define USBH_REQTYPE_DIR_IN				0x80
 +#define USBH_REQTYPE_DIR_OUT			0x00
 -#define USBH_REQTYPE_IN					0x80
 -#define USBH_REQTYPE_OUT				0x00
 +#define USBH_REQTYPE_TYPE_STANDARD		0x00
 +#define USBH_REQTYPE_TYPE_CLASS			0x20
 +#define USBH_REQTYPE_TYPE_VENDOR		0x40
 -#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
 +#define USBH_REQTYPE_RECIP_DEVICE		0x00
 +#define USBH_REQTYPE_RECIP_INTERFACE	0x01
 +#define USBH_REQTYPE_RECIP_ENDPOINT		0x02
 +#define USBH_REQTYPE_RECIP_OTHER		0x03
  #endif
 diff --git a/os/hal/include/usbh/desciter.h b/os/hal/include/usbh/desciter.h index 52b0c98..142bd3c 100644 --- a/os/hal/include/usbh/desciter.h +++ b/os/hal/include/usbh/desciter.h @@ -1,6 +1,6 @@  /*
 -    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 -              Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
 +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
 +              Copyright (C) 2015..2017 Diego Ismirlian, (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.
 diff --git a/os/hal/include/usbh/dev/aoa.h b/os/hal/include/usbh/dev/aoa.h new file mode 100644 index 0000000..a7f1c1b --- /dev/null +++ b/os/hal/include/usbh/dev/aoa.h @@ -0,0 +1,152 @@ +/* +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio +              Copyright (C) 2015..2017 Diego Ismirlian, (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_AOA_H_ +#define USBH_AOA_H_ + +#include "hal_usbh.h" + +#if HAL_USE_USBH && HAL_USBH_USE_AOA + +/*===========================================================================*/ +/* Driver pre-compile time settings.                                         */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks.                                       */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types.                                         */ +/*===========================================================================*/ + +typedef enum { +	USBHAOA_CHANNEL_STATE_UNINIT = 0, +	USBHAOA_CHANNEL_STATE_STOP = 1, +	USBHAOA_CHANNEL_STATE_ACTIVE = 2, +	USBHAOA_CHANNEL_STATE_READY = 3 +} usbhaoa_channel_state_t; + +typedef enum { +	USBHAOA_STATE_UNINIT = 0, +	USBHAOA_STATE_STOP = 1, +	USBHAOA_STATE_ACTIVE = 2, +	USBHAOA_STATE_READY = 3 +} usbhaoa_state_t; + +typedef enum { +	USBHAOA_AUDIO_MODE_DISABLED = 0, +	USBHAOA_AUDIO_MODE_2CH_16BIT_PCM_44100 = 1, +} usbhaoa_audio_mode_t; + +typedef struct { +	struct _aoa_channel_cfg { +		const char *manufacturer; +		const char *model; +		const char *description; +		const char *version; +		const char *uri; +		const char *serial; +	} channel; + +	struct _aoa_audio_cfg { +		usbhaoa_audio_mode_t mode; +	} audio; + +} USBHAOAConfig; + +#define _aoa_driver_methods                                          \ +  _base_asynchronous_channel_methods + +struct AOADriverVMT { +	_aoa_driver_methods +}; + +typedef struct USBHAOAChannel USBHAOAChannel; +typedef struct USBHAOADriver USBHAOADriver; + +struct USBHAOAChannel { +	/* inherited from abstract asyncrhonous channel driver */ +	const struct AOADriverVMT *vmt; +	_base_asynchronous_channel_data + +	usbh_ep_t epin; +	usbh_urb_t iq_urb; +	threads_queue_t	iq_waiting; +	uint32_t iq_counter; +	USBH_DECLARE_STRUCT_MEMBER(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_DECLARE_STRUCT_MEMBER(uint8_t oq_buff[64]); +	uint8_t *oq_ptr; + +	virtual_timer_t vt; + +	usbhaoa_channel_state_t state; +}; + +struct USBHAOADriver { +	/* inherited from abstract class driver */ +	_usbh_base_classdriver_data + +	USBHAOAChannel channel; + +	usbhaoa_state_t state; + +}; + +#define USBHAOA_ACCESSORY_STRING_MANUFACTURER   0 +#define USBHAOA_ACCESSORY_STRING_MODEL          1 +#define USBHAOA_ACCESSORY_STRING_DESCRIPTION    2 +#define USBHAOA_ACCESSORY_STRING_VERSION        3 +#define USBHAOA_ACCESSORY_STRING_URI            4 +#define USBHAOA_ACCESSORY_STRING_SERIAL         5 + +typedef bool (*usbhaoa_filter_callback_t)(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem, USBHAOAConfig *config); + +/*===========================================================================*/ +/* Driver macros.                                                            */ +/*===========================================================================*/ +#define usbhaoaStop(aoap) + +#define usbhaoaGetState(aoap) ((aoap)->state) + +#define usbhaoaGetChannelState(aoap) ((aoap)->channel.state) + +/*===========================================================================*/ +/* External declarations.                                                    */ +/*===========================================================================*/ +extern USBHAOADriver USBHAOAD[HAL_USBHAOA_MAX_INSTANCES]; + +#ifdef __cplusplus +extern "C" { +#endif +	/* AOA device driver */ +	void usbhaoaChannelStart(USBHAOADriver *aoap); +	void usbhaoaChannelStop(USBHAOADriver *aoap); +#ifdef __cplusplus +} +#endif + + +#endif + +#endif /* USBH_AOA_H_ */ diff --git a/os/hal/include/usbh/dev/ftdi.h b/os/hal/include/usbh/dev/ftdi.h index ad6b4cd..eedb056 100644 --- a/os/hal/include/usbh/dev/ftdi.h +++ b/os/hal/include/usbh/dev/ftdi.h @@ -1,6 +1,6 @@  /*
 -    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 -              Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
 +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
 +              Copyright (C) 2015..2017 Diego Ismirlian, (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.
 @@ -96,7 +96,7 @@ struct USBHFTDIPortDriver {  	usbh_urb_t iq_urb;
  	threads_queue_t	iq_waiting;
  	uint32_t iq_counter;
 -	USBH_DEFINE_BUFFER(uint8_t, iq_buff[64]);
 +	USBH_DECLARE_STRUCT_MEMBER(uint8_t iq_buff[64]);
  	uint8_t *iq_ptr;
 @@ -104,7 +104,7 @@ struct USBHFTDIPortDriver {  	usbh_urb_t oq_urb;
  	threads_queue_t	oq_waiting;
  	uint32_t oq_counter;
 -	USBH_DEFINE_BUFFER(uint8_t, oq_buff[64]);
 +	USBH_DECLARE_STRUCT_MEMBER(uint8_t oq_buff[64]);
  	uint8_t *oq_ptr;
  	virtual_timer_t vt;
 @@ -113,7 +113,7 @@ struct USBHFTDIPortDriver {  	USBHFTDIPortDriver *next;
  };
 -typedef struct USBHFTDIDriver {
 +struct USBHFTDIDriver {
  	/* inherited from abstract class driver */
  	_usbh_base_classdriver_data
 @@ -121,11 +121,12 @@ typedef struct USBHFTDIDriver {  	USBHFTDIPortDriver *ports;
  	mutex_t mtx;
 -} USBHFTDIDriver;
 +};
  /*===========================================================================*/
  /* Driver macros.                                                            */
  /*===========================================================================*/
 +#define usbhftdipGetState(ftdipp) ((ftdipp)->state)
  /*===========================================================================*/
 @@ -137,11 +138,7 @@ 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
 diff --git a/os/hal/include/usbh/dev/hid.h b/os/hal/include/usbh/dev/hid.h new file mode 100644 index 0000000..c7371ee --- /dev/null +++ b/os/hal/include/usbh/dev/hid.h @@ -0,0 +1,144 @@ +/* +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio +              Copyright (C) 2015..2017 Diego Ismirlian, (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_HID_H_ +#define USBH_HID_H_ + +#include "hal_usbh.h" + +#if HAL_USE_USBH && HAL_USBH_USE_HID + +/* TODO: + * + */ + + +/*===========================================================================*/ +/* Driver pre-compile time settings.                                         */ +/*===========================================================================*/ +#if !defined(HAL_USBHHID_USE_INTERRUPT_OUT) +#define HAL_USBHHID_USE_INTERRUPT_OUT 				FALSE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks.                                       */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* Driver data structures and types.                                         */ +/*===========================================================================*/ + +typedef enum { +	USBHHID_STATE_UNINIT = 0, +	USBHHID_STATE_STOP = 1, +	USBHHID_STATE_ACTIVE = 2, +	USBHHID_STATE_READY = 3 +} usbhhid_state_t; + +typedef enum { +	USBHHID_DEVTYPE_GENERIC = 0, +	USBHHID_DEVTYPE_BOOT_KEYBOARD = 1, +	USBHHID_DEVTYPE_BOOT_MOUSE = 2, +} usbhhid_devtype_t; + +typedef enum { +	USBHHID_REPORTTYPE_INPUT = 1, +	USBHHID_REPORTTYPE_OUTPUT = 2, +	USBHHID_REPORTTYPE_FEATURE = 3, +} usbhhid_reporttype_t; + +typedef enum { +	USBHHID_PROTOCOL_BOOT = 0, +	USBHHID_PROTOCOL_REPORT = 1, +} usbhhid_protocol_t; + +typedef struct USBHHIDDriver USBHHIDDriver; +typedef struct USBHHIDConfig USBHHIDConfig; + +typedef void (*usbhhid_report_callback)(USBHHIDDriver *hidp, uint16_t len); + +struct USBHHIDConfig { +	usbhhid_report_callback cb_report; +	void *report_buffer; +	uint16_t report_len; +	usbhhid_protocol_t protocol; +}; + +struct USBHHIDDriver { +	/* inherited from abstract class driver */ +	_usbh_base_classdriver_data + +	usbh_ep_t epin; +#if HAL_USBHHID_USE_INTERRUPT_OUT +	usbh_ep_t epout; +#endif +	uint8_t ifnum; + +	usbhhid_devtype_t type; +	usbhhid_state_t state; + +	usbh_urb_t in_urb; + +	const USBHHIDConfig *config; + +	semaphore_t sem; +}; + + +/*===========================================================================*/ +/* Driver macros.                                                            */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* External declarations.                                                    */ +/*===========================================================================*/ + +extern USBHHIDDriver USBHHIDD[HAL_USBHHID_MAX_INSTANCES]; + +#ifdef __cplusplus +extern "C" { +#endif +	/* HID Common API */ +	usbh_urbstatus_t usbhhidGetReport(USBHHIDDriver *hidp, +			uint8_t report_id, usbhhid_reporttype_t report_type, +			void *data, uint16_t len); +	usbh_urbstatus_t usbhhidSetReport(USBHHIDDriver *hidp, +			uint8_t report_id, usbhhid_reporttype_t report_type, +			const void *data, uint16_t len); +	usbh_urbstatus_t usbhhidGetIdle(USBHHIDDriver *hidp, uint8_t report_id, uint8_t *duration); +	usbh_urbstatus_t usbhhidSetIdle(USBHHIDDriver *hidp, uint8_t report_id, uint8_t duration); +	usbh_urbstatus_t usbhhidGetProtocol(USBHHIDDriver *hidp, uint8_t *protocol); +	usbh_urbstatus_t usbhhidSetProtocol(USBHHIDDriver *hidp, uint8_t protocol); + +	static inline uint8_t usbhhidGetType(USBHHIDDriver *hidp) { +		return hidp->type; +	} + +	static inline usbhhid_state_t usbhhidGetState(USBHHIDDriver *hidp) { +		return hidp->state; +	} + +	void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg); +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* USBH_HID_H_ */ diff --git a/os/hal/include/usbh/dev/hub.h b/os/hal/include/usbh/dev/hub.h index 07e88e6..406fbaf 100644 --- a/os/hal/include/usbh/dev/hub.h +++ b/os/hal/include/usbh/dev/hub.h @@ -1,6 +1,6 @@  /*
 -    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 -              Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
 +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
 +              Copyright (C) 2015..2017 Diego Ismirlian, (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.
 @@ -23,7 +23,7 @@  #if HAL_USE_USBH
  #if HAL_USBH_USE_HUB
 -typedef struct USBHHubDriver {
 +struct USBHHubDriver {
  	/* inherited from abstract class driver */
  	_usbh_base_classdriver_data
 @@ -32,19 +32,19 @@ typedef struct USBHHubDriver {  	usbh_ep_t epint;
  	usbh_urb_t urb;
 -	USBH_DEFINE_BUFFER(uint8_t, scbuff[4]);
 +	USBH_DECLARE_STRUCT_MEMBER(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);
 +	USBH_DECLARE_STRUCT_MEMBER(usbh_hub_descriptor_t hubDesc);
  	/* Low level part */
  	_usbh_hub_ll_data
 -} USBHHubDriver;
 +};
  extern USBHHubDriver USBHHUBD[HAL_USBHHUB_MAX_INSTANCES];
 @@ -60,7 +60,7 @@ usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host, USBHHubDriver *hub,  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_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER,
  				USBH_REQ_CLEAR_FEATURE,
  				feature,
  				port->number,
 @@ -70,7 +70,7 @@ static inline usbh_urbstatus_t usbhhubClearFeaturePort(usbh_port_t *port, uint8_  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_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE,
  				USBH_REQ_CLEAR_FEATURE,
  				feature,
  				0,
 @@ -80,7 +80,7 @@ static inline usbh_urbstatus_t usbhhubClearFeatureHub(USBHDriver *host, USBHHubD  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_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER,
  				USBH_REQ_SET_FEATURE,
  				feature,
  				port->number,
 @@ -88,7 +88,6 @@ static inline usbh_urbstatus_t usbhhubSetFeaturePort(usbh_port_t *port, uint8_t  				0);
  }
 -void usbhhubObjectInit(USBHHubDriver *hubdp);
  #else
  static inline usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host,
 @@ -103,7 +102,7 @@ static inline usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host,  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_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER,
  				USBH_REQ_CLEAR_FEATURE,
  				feature,
  				port->number,
 @@ -113,7 +112,7 @@ static inline usbh_urbstatus_t usbhhubClearFeaturePort(usbh_port_t *port, uint8_  static inline usbh_urbstatus_t usbhhubClearFeatureHub(USBHDriver *host, uint8_t feature) {
  	return usbhhubControlRequest(host,
 -				USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE,
 +				USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE,
  				USBH_REQ_CLEAR_FEATURE,
  				feature,
  				0,
 @@ -123,7 +122,7 @@ static inline usbh_urbstatus_t usbhhubClearFeatureHub(USBHDriver *host, uint8_t  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_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER,
  				USBH_REQ_SET_FEATURE,
  				feature,
  				port->number,
 diff --git a/os/hal/include/usbh/dev/msd.h b/os/hal/include/usbh/dev/msd.h index d164618..eedd474 100644 --- a/os/hal/include/usbh/dev/msd.h +++ b/os/hal/include/usbh/dev/msd.h @@ -1,6 +1,6 @@  /*
 -    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 -              Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
 +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
 +              Copyright (C) 2015..2017 Diego Ismirlian, (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.
 @@ -25,7 +25,6 @@  /* TODO:
   *
   * - Implement of conditional compilation of multiple-luns per instance.
 - * - Implement error checking and recovery when commands fail.
   *
   */
 @@ -59,30 +58,15 @@ struct USBHMassStorageLUNDriver {  	const struct USBHMassStorageDriverVMT *vmt;
  	_base_block_device_data
 +	/* for serializing access to the LUN driver */
 +	semaphore_t sem;
 +
  	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.                                                            */
 @@ -94,18 +78,13 @@ typedef struct USBHMassStorageDriver {  /*===========================================================================*/
  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);
 +//	void usbhmsdLUNStart(USBHMassStorageLUNDriver *lunp);
 +//	void usbhmsdLUNStop(USBHMassStorageLUNDriver *lunp);
  	bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp);
  	bool usbhmsdLUNDisconnect(USBHMassStorageLUNDriver *lunp);
  	bool usbhmsdLUNRead(USBHMassStorageLUNDriver *lunp, uint32_t startblk,
 diff --git a/os/hal/include/usbh/dev/uvc.h b/os/hal/include/usbh/dev/uvc.h new file mode 100644 index 0000000..817d465 --- /dev/null +++ b/os/hal/include/usbh/dev/uvc.h @@ -0,0 +1,459 @@ +/* +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio +              Copyright (C) 2015..2017 Diego Ismirlian, (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_INCLUDE_USBH_UVC_H_ +#define USBH_INCLUDE_USBH_UVC_H_ + +#include "hal_usbh.h" + +#if HAL_USE_USBH && HAL_USBH_USE_UVC + +#include "usbh/desciter.h" + +/*===========================================================================*/ +/* Driver pre-compile time settings.                                         */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* Derived constants and error checks.                                       */ +/*===========================================================================*/ +#define USBHUVC_MAX_STATUS_PACKET_SZ	16 + + +/*===========================================================================*/ +/* Driver data structures and types.                                         */ +/*===========================================================================*/ + + +typedef enum { +	UVC_CS_INTERFACE 	= 0x24, +	UVC_CS_ENDPOINT 	= 0x25 +} usbh_uvc_cstype_t; + +typedef enum { +	UVC_CC_VIDEO 		= 0x0e +} usbh_uvc_cctype_t; + +typedef enum { +	UVC_SC_UNKNOWN = 0x00, +	UVC_SC_VIDEOCONTROL, +	UVC_SC_VIDEOSTREAMING, +	UVC_SC_VIDEO_INTERFACE_COLLECTION +} usbh_uvc_sctype_t; + +typedef enum { +	UVC_VC_UNDEF = 0x00, +	UVC_VC_HEADER, +	UVC_VC_INPUT_TERMINAL, +	UVC_VC_OUTPUT_TERMINAL, +	UVC_VC_SELECTOR_UNIT, +	UVC_VC_PROCESSING_UNIT, +	UVC_VC_EXTENSION_UNIT +} usbh_uvc_vctype_t; + +typedef enum { +	UVC_VS_UNDEF = 0x00, +	UVC_VS_INPUT_HEADER, +	UVC_VS_OUTPUT_HEADER, +	UVC_VS_STILL_IMAGE_FRAME, +	UVC_VS_FORMAT_UNCOMPRESSED, +	UVC_VS_FRAME_UNCOMPRESSED, +	UVC_VS_FORMAT_MJPEG, +	UVC_VS_FRAME_MJPEG, +	UVC_VS_RESERVED_0, +	UVC_VS_RESERVED_1, +	UVC_VS_FORMAT_MPEG2TS, +	UVC_VS_RESERVED_2, +	UVC_VS_FORMAT_DV, +	UVC_VS_COLOR_FORMAT, +	UVC_VS_RESERVED_3, +	UVC_VS_RESERVED_4, +	UVC_VS_FORMAT_FRAME_BASED, +	UVC_VS_FRAME_FRAME_BASED, +	UVC_VS_FORMAT_STREAM_BASED +} usbh_uvc_vstype_t; + +typedef enum { +	UVC_TT_VENDOR_SPECIFIC 			= 0x0100, +	UVC_TT_STREAMING 				= 0x0101, +	UVC_ITT_VENDOR_SPECIFIC 		= 0x0200, +	UVC_ITT_CAMERA 					= 0x0201, +	UVC_ITT_MEDIA_TRANSPORT_INPUT 	= 0x0202, +	UVC_OTT_VENDOR_SPECIFIC 		= 0x0300, +	UVC_OTT_DISPLAY 				= 0x0301, +	UVC_OTT_MEDIA_TRANSPORT 		= 0x0302 +} usbh_uvc_tttype_t; + +typedef enum { +	UVC_SET_CUR	 =	0x01, +	UVC_GET_CUR	 =	0x81, +	UVC_GET_MIN	 =	0x82, +	UVC_GET_MAX	 =	0x83, +	UVC_GET_RES  =	0x84, +	UVC_GET_LEN  = 	0x85, +	UVC_GET_INFO =	0x86, +	UVC_GET_DEF  =	0x87 +} usbh_uvc_ctrlops_t; + +typedef enum { +	UVC_CTRL_VC_CONTROL_UNDEFINED  = 0x00, +	UVC_CTRL_VC_VIDEO_POWER_MODE_CONTROL = 0x01, +	UVC_CTRL_VC_REQUEST_ERROR_CODE_CONTROL = 0x02, +} usbh_uvc_ctrl_vc_interface_controls_t; + +typedef enum { +	UVC_CTRL_SU_CONTROL_UNDEFINED = 0x00, +	UVC_CTRL_SU_INPUT_SELECT_CONTROL = 0x01, +} usbh_uvc_ctrl_vc_selectorunit_controls_t; + +typedef enum { +	UVC_CTRL_CT_CONTROL_UNDEFINED = 0x00, +	UVC_CTRL_CT_SCANNING_MODE_CONTROL = 0x01, +	UVC_CTRL_CT_AE_MODE_CONTROL = 0x02, +	UVC_CTRL_CT_AE_PRIORITY_CONTROL = 0x03, +	UVC_CTRL_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL = 0x04, +	UVC_CTRL_CT_EXPOSURE_TIME_RELATIVE_CONTROL = 0x05, +	UVC_CTRL_CT_FOCUS_ABSOLUTE_CONTROL = 0x06, +	UVC_CTRL_CT_FOCUS_RELATIVE_CONTROL = 0x07, +	UVC_CTRL_CT_FOCUS_AUTO_CONTROL = 0x08, +	UVC_CTRL_CT_IRIS_ABSOLUTE_CONTROL = 0x09, +	UVC_CTRL_CT_IRIS_RELATIVE_CONTROL = 0x0A, +	UVC_CTRL_CT_ZOOM_ABSOLUTE_CONTROL = 0x0B, +	UVC_CTRL_CT_ZOOM_RELATIVE_CONTROL = 0x0C, +	UVC_CTRL_CT_PANTILT_ABSOLUTE_CONTROL = 0x0D, +	UVC_CTRL_CT_PANTILT_RELATIVE_CONTROL = 0x0E, +	UVC_CTRL_CT_ROLL_ABSOLUTE_CONTROL = 0x0F, +	UVC_CTRL_CT_ROLL_RELATIVE_CONTROL = 0x10, +	UVC_CTRL_CT_PRIVACY_CONTROL = 0x11 +} usbh_uvc_ctrl_vc_cameraterminal_controls_t; + +typedef enum { +	UVC_CTRL_PU_CONTROL_UNDEFINED = 0x00, +	UVC_CTRL_PU_BACKLIGHT_COMPENSATION_CONTROL = 0x01, +	UVC_CTRL_PU_BRIGHTNESS_CONTROL = 0x02, +	UVC_CTRL_PU_CONTRAST_CONTROL = 0x03, +	UVC_CTRL_PU_GAIN_CONTROL = 0x04, +	UVC_CTRL_PU_POWER_LINE_FREQUENCY_CONTROL = 0x05, +	UVC_CTRL_PU_HUE_CONTROL = 0x06, +	UVC_CTRL_PU_SATURATION_CONTROL = 0x07, +	UVC_CTRL_PU_SHARPNESS_CONTROL = 0x08, +	UVC_CTRL_PU_GAMMA_CONTROL = 0x09, +	UVC_CTRL_PU_WHITE_BALANCE_TEMPERATURE_CONTROL = 0x0A, +	UVC_CTRL_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL = 0x0B, +	UVC_CTRL_PU_WHITE_BALANCE_COMPONENT_CONTROL = 0x0C, +	UVC_CTRL_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL = 0x0D, +	UVC_CTRL_PU_DIGITAL_MULTIPLIER_CONTROL = 0x0E, +	UVC_CTRL_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL = 0x0F, +	UVC_CTRL_PU_HUE_AUTO_CONTROL = 0x10, +	UVC_CTRL_PU_ANALOG_VIDEO_STANDARD_CONTROL = 0x11, +	UVC_CTRL_PU_ANALOG_LOCK_STATUS_CONTROL = 0x12, +} usbh_uvc_ctrl_vc_processingunit_controls_t; + +typedef enum { +	UVC_CTRL_VS_CONTROL_UNDEFINED = 0x00, +	UVC_CTRL_VS_PROBE_CONTROL = 0x01, +	UVC_CTRL_VS_COMMIT_CONTROL = 0x02, +	UVC_CTRL_VS_STILL_PROBE_CONTROL = 0x03, +	UVC_CTRL_VS_STILL_COMMIT_CONTROL = 0x04, +	UVC_CTRL_VS_STILL_IMAGE_TRIGGER_CONTROL = 0x05, +	UVC_CTRL_VS_STREAM_ERROR_CODE_CONTROL = 0x06, +	UVC_CTRL_VS_GENERATE_KEY_FRAME_CONTROL = 0x07, +	UVC_CTRL_VS_UPDATE_FRAME_SEGMENT_CONTROL = 0x08, +	UVC_CTRL_VS_SYNCH_DELAY_CONTROL = 0x09 +} usbh_uvc_ctrl_vs_interface_controls_t; + + +typedef PACKED_STRUCT { +	uint8_t bLength; +	uint8_t bDescriptorType; +	uint8_t bDescriptorSubType; +	uint8_t bFormatIndex; +	uint8_t bNumFrameDescriptors; +	uint8_t bmFlags; +	uint8_t bDefaultFrameIndex; +	uint8_t bAspectRatioX; +	uint8_t bAspectRatioY; +	uint8_t bmInterfaceFlags; +	uint8_t bCopyProtect; +} usbh_uvc_format_mjpeg_t; + +typedef PACKED_STRUCT { +	uint8_t  bLength; +	uint8_t  bDescriptorType; +	uint8_t  bDescriptorSubType; +	uint8_t  bFrameIndex; +	uint8_t  bmCapabilities; +	uint16_t wWidth; +	uint16_t wHeight; +	uint32_t dwMinBitRate; +	uint32_t dwMaxBitRate; +	uint32_t dwMaxVideoFrameBufferSize; +	uint32_t dwDefaultFrameInterval; +	uint8_t bFrameIntervalType; +	uint32_t dwFrameInterval[0]; +} usbh_uvc_frame_mjpeg_t; + + +typedef PACKED_STRUCT { +	uint8_t bLength; +	uint8_t bDescriptorType; +	uint8_t bDescriptorSubType; +	uint8_t bFrameIndex; +	uint8_t bmCapabilities; +	uint16_t wWidth; +	uint16_t wHeight; +	uint32_t dwMinBitRate; +	uint32_t dwMaxBitRate; +	uint32_t dwMaxVideoFrameBufferSize; +	uint32_t dwDefaultFrameInterval; +	uint8_t bFrameIntervalType; +	uint32_t dwFrameInterval[0]; +} usbh_uvc_frame_uncompressed_t; + +typedef PACKED_STRUCT { +	uint8_t  bLength; +	uint8_t  bDescriptorType; +	uint8_t  bDescriptorSubType; +	uint8_t  bFormatIndex; +	uint8_t  bNumFrameDescriptors; +	uint8_t  guidFormat[16]; +	uint8_t  bBitsPerPixel; +	uint8_t  bDefaultFrameIndex; +	uint8_t  bAspectRatioX; +	uint8_t  bAspectRatioY; +	uint8_t  bmInterfaceFlags; +	uint8_t  bCopyProtect; +} usbh_uvc_format_uncompressed; + +typedef PACKED_STRUCT { +    uint16_t bmHint; +    uint8_t bFormatIndex; +    uint8_t bFrameIndex; +    uint32_t dwFrameInterval; +    uint16_t wKeyFrameRate; +    uint16_t wPFrameRate; +    uint16_t wCompQuality; +    uint16_t wCompWindowSize; +    uint16_t wDelay; +    uint32_t dwMaxVideoFrameSize; +    uint32_t dwMaxPayloadTransferSize; +//    uint32_t dwClockFrequency; +//    uint8_t bmFramingInfo; +//    uint8_t bPreferedVersion; +//    uint8_t bMinVersion; +//    uint8_t bMaxVersion; +} usbh_uvc_ctrl_vs_probecommit_data_t; + + + +/* D0: Frame ID. + * 	For frame-based formats, this bit toggles between 0 and 1 every time a new video frame begins. + * 	For stream-based formats, this bit toggles between 0 and 1 at the start of each new codec-specific + * 	segment. This behavior is required for frame-based payload formats (e.g., DV) and is optional + * 	for stream-based payload formats (e.g., MPEG-2 TS). For stream-based formats, support for this + * 	bit must be indicated via the bmFramingInfofield of the Video Probe and Commitcontrols + * 	(see section 4.3.1.1, “Video Probe and Commit Controls”). + * + * D1: End of Frame. + *  This bit is set if the following payload data marks the end of the current video or still image + *  frame (for framebased formats), or to indicate the end of a codec-specific segment + *  (for stream-based formats). This behavior is optional for all payload formats. + *  For stream-based formats, support for this bit must be indicated via the bmFramingInfofield + *  of the Video Probe and CommitControls (see section 4.3.1.1, “Video Probe and Commit Controls”). + * + * D2: Presentation Time. + *  This bit is set if the dwPresentationTimefield is being sent as part of the header. + * + * D3: Source Clock Reference + *  This bit is set if the dwSourceClockfield is being sent as part of the header. + * + * D4: Reserved + * + * D5: Still Image + *  This bit is set ifthe following data is part of a still image frame, and is only used for + *  methods 2 and 3 of still image capture. + * + * D6: Error + *  This bit is set ifthere was an error in the video or still image transmission + *  for this payload. The StreamError Code control would reflect the cause of the error. + * + * D7: End of header + *  This bit is set if this is the last header group in the packet, where the + *  header group refers to this field and any optional fields identified by the bits in this + *  field (Defined for future extension) +*/ + +#define UVC_HDR_EOH				(1 << 7)	/* End of header */ +#define UVC_HDR_ERR				(1 << 6)	/* Error */ +#define UVC_HDR_STILL			(1 << 5)	/* Still Image */ +#define UVC_HDR_SCR				(1 << 3)	/* Source Clock Reference */ +#define UVC_HDR_PT				(1 << 2)	/* Presentation Time */ +#define UVC_HDR_EOF				(1 << 1)	/* End of Frame */ +#define UVC_HDR_FID				(1 << 0)	/* Frame ID */ + + + +typedef struct USBHUVCDriver USBHUVCDriver; + +#define USBHUVC_MESSAGETYPE_STATUS	1 +#define USBHUVC_MESSAGETYPE_DATA	2 + + +#define _usbhuvc_message_base_data				\ +		uint16_t type;							\ +		uint16_t length;						\ +		systime_t timestamp; + +typedef struct { +	_usbhuvc_message_base_data +} usbhuvc_message_base_t; + +typedef struct { +	_usbhuvc_message_base_data +	USBH_DECLARE_STRUCT_MEMBER(uint8_t data[0]); +} usbhuvc_message_data_t; + +typedef struct { +	_usbhuvc_message_base_data +	USBH_DECLARE_STRUCT_MEMBER(uint8_t data[USBHUVC_MAX_STATUS_PACKET_SZ]); +} usbhuvc_message_status_t; + + +typedef enum { +	USBHUVC_STATE_UNINITIALIZED = 0,	//must call usbhuvcObjectInit +	USBHUVC_STATE_STOP	 		= 1,	//the device is disconnected +	USBHUVC_STATE_ACTIVE 		= 2,	//the device is connected +	USBHUVC_STATE_READY		 	= 3,	//the device has negotiated the parameters +	USBHUVC_STATE_STREAMING 	= 4,	//the device is streaming data +	USBHUVC_STATE_BUSY	 		= 5		//the driver is busy performing some action +} usbhuvc_state_t; + + +struct USBHUVCDriver { +	/* inherited from abstract class driver */ +	_usbh_base_classdriver_data + +	usbhuvc_state_t state; + +	usbh_ep_t ep_int; +	usbh_ep_t ep_iso; + +	usbh_urb_t urb_iso; +	usbh_urb_t urb_int; + +	if_iterator_t ivc; +	if_iterator_t ivs; + +	USBH_DECLARE_STRUCT_MEMBER(usbh_uvc_ctrl_vs_probecommit_data_t pc); +	USBH_DECLARE_STRUCT_MEMBER(usbh_uvc_ctrl_vs_probecommit_data_t pc_min); +	USBH_DECLARE_STRUCT_MEMBER(usbh_uvc_ctrl_vs_probecommit_data_t pc_max); + +	mailbox_t mb; +	msg_t mb_buff[HAL_USBHUVC_MAX_MAILBOX_SZ]; + +	memory_pool_t mp_data; +	void *mp_data_buffer; + +	memory_pool_t mp_status; +	usbhuvc_message_status_t mp_status_buffer[HAL_USBHUVC_STATUS_PACKETS_COUNT]; + +	mutex_t mtx; +}; + + +/*===========================================================================*/ +/* Driver macros.                                                            */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* External declarations.                                                    */ +/*===========================================================================*/ + +extern USBHUVCDriver USBHUVCD[HAL_USBHUVC_MAX_INSTANCES]; + +#ifdef __cplusplus +extern "C" { +#endif +	static inline usbhuvc_state_t usbhuvcGetState(USBHUVCDriver *uvcd) { +		return uvcd->state; +	} + +	bool usbhuvcVCRequest(USBHUVCDriver *uvcdp, +			uint8_t bRequest, uint8_t entity, uint8_t control, +			uint16_t wLength, uint8_t *data); +	bool usbhuvcVSRequest(USBHUVCDriver *uvcdp, +			uint8_t bRequest, uint8_t control, +			uint16_t wLength, uint8_t *data); +	bool usbhuvcFindVSDescriptor(USBHUVCDriver *uvcdp, +			generic_iterator_t *ics, +			uint8_t bDescriptorSubtype, +			bool start); +	uint32_t usbhuvcEstimateRequiredEPSize(USBHUVCDriver *uvcdp, const uint8_t *formatdesc, +			const uint8_t *framedesc, uint32_t dwFrameInterval); + +#if	USBH_DEBUG_ENABLE && USBHUVC_DEBUG_ENABLE_INFO +	void usbhuvcPrintProbeCommit(const usbh_uvc_ctrl_vs_probecommit_data_t *pc); +#else +#	define usbhuvcPrintProbeCommit(pc) do {} while(0) +#endif +	bool usbhuvcProbe(USBHUVCDriver *uvcdp); +	bool usbhuvcCommit(USBHUVCDriver *uvcdp); +	void usbhuvcResetPC(USBHUVCDriver *uvcdp); +	static inline const usbh_uvc_ctrl_vs_probecommit_data_t *usbhuvcGetPCMin(USBHUVCDriver *uvcdp) { +		return &uvcdp->pc_min; +	} +	static inline const usbh_uvc_ctrl_vs_probecommit_data_t *usbhuvcGetPCMax(USBHUVCDriver *uvcdp) { +		return &uvcdp->pc_min; +	} +	static inline usbh_uvc_ctrl_vs_probecommit_data_t *usbhuvcGetPC(USBHUVCDriver *uvcdp) { +		return &uvcdp->pc; +	} + +	bool usbhuvcStreamStart(USBHUVCDriver *uvcdp, uint16_t min_ep_sz); +	bool usbhuvcStreamStop(USBHUVCDriver *uvcdp); + +	static inline msg_t usbhuvcLockAndFetchS(USBHUVCDriver *uvcdp, msg_t *msg, systime_t timeout) { +		chMtxLockS(&uvcdp->mtx); +		msg_t ret = chMBFetchS(&uvcdp->mb, msg, timeout); +		if (ret != MSG_OK) +			chMtxUnlockS(&uvcdp->mtx); +		return ret; +	} +	static inline msg_t usbhuvcLockAndFetch(USBHUVCDriver *uvcdp, msg_t *msg, systime_t timeout) { +		osalSysLock(); +		msg_t ret = usbhuvcLockAndFetchS(uvcdp, msg, timeout); +		osalSysUnlock(); +		return ret; +	} +	static inline void usbhuvcUnlock(USBHUVCDriver *uvcdp) { +		chMtxUnlock(&uvcdp->mtx); +	} +	static inline void usbhuvcFreeDataMessage(USBHUVCDriver *uvcdp, usbhuvc_message_data_t *msg) { +		chPoolFree(&uvcdp->mp_data, msg); +	} +	static inline void usbhuvcFreeStatusMessage(USBHUVCDriver *uvcdp, usbhuvc_message_status_t *msg) { +		chPoolFree(&uvcdp->mp_status, msg); +	} +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* USBH_INCLUDE_USBH_UVC_H_ */ diff --git a/os/hal/include/usbh/internal.h b/os/hal/include/usbh/internal.h index baa477f..f6f17b7 100644 --- a/os/hal/include/usbh/internal.h +++ b/os/hal/include/usbh/internal.h @@ -1,6 +1,6 @@  /*
 -    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 -              Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail)
 +    ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
 +              Copyright (C) 2015..2017 Diego Ismirlian, (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.
 @@ -29,9 +29,15 @@  #if HAL_USBH_USE_FTDI
  extern const usbh_classdriverinfo_t usbhftdiClassDriverInfo;
  #endif
 +#if HAL_USBH_USE_AOA
 +extern const usbh_classdriverinfo_t usbhaoaClassDriverInfo;
 +#endif
  #if HAL_USBH_USE_MSD
  extern const usbh_classdriverinfo_t usbhmsdClassDriverInfo;
  #endif
 +#if HAL_USBH_USE_HID
 +extern const usbh_classdriverinfo_t usbhhidClassDriverInfo;
 +#endif
  #if HAL_USBH_USE_UVC
  extern const usbh_classdriverinfo_t usbhuvcClassDriverInfo;
  #endif
 @@ -48,30 +54,21 @@ 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);
 +bool _usbh_match_vid_pid(usbh_device_t *dev, int32_t vid, int32_t pid);
 +bool _usbh_match_descriptor(const uint8_t *descriptor, uint16_t rem,
 +		int16_t type, int16_t _class, int16_t subclass, int16_t protocol);
 -#define USBH_CLASSIN(type, req, value, index)	\
 -	(USBH_REQTYPE_IN | type | USBH_REQTYPE_CLASS), \
 -	req, \
 -	value, \
 -	index
 +#define USBH_REQTYPE_CLASSIN(type)	\
 +	(USBH_REQTYPE_DIR_IN | type | USBH_REQTYPE_TYPE_CLASS)
 -#define USBH_CLASSOUT(type, req, value, index)	\
 -	(USBH_REQTYPE_OUT | type | USBH_REQTYPE_CLASS), \
 -	req, \
 -	value, \
 -	index
 +#define USBH_REQTYPE_CLASSOUT(type)	\
 +	(USBH_REQTYPE_DIR_OUT | type | USBH_REQTYPE_TYPE_CLASS)
 -#define USBH_STANDARDIN(type, req, value, index)	\
 -	(USBH_REQTYPE_IN | type | USBH_REQTYPE_STANDARD), \
 -	req, \
 -	value, \
 -	index
 +#define USBH_REQTYPE_STANDARDIN(type)	\
 +	(USBH_REQTYPE_DIR_IN | type | USBH_REQTYPE_TYPE_STANDARD)
 -#define USBH_STANDARDOUT(type, req, value, index)	\
 -	(USBH_REQTYPE_OUT | type | USBH_REQTYPE_STANDARD), \
 -	req, \
 -	value, \
 -	index
 +#define USBH_REQTYPE_STANDARDOUT(type)	\
 +	(USBH_REQTYPE_DIR_OUT | type | USBH_REQTYPE_TYPE_STANDARD)
  #define USBH_PID_DATA0            0
 @@ -82,19 +79,19 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status);  /* GetBusState and SetHubDescriptor are optional, omitted */
 -#define ClearHubFeature   (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
 +#define ClearHubFeature   (((USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE) << 8) \
  							| USBH_REQ_CLEAR_FEATURE)
 -#define SetHubFeature     (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
 +#define SetHubFeature     (((USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE) << 8) \
  							| USBH_REQ_SET_FEATURE)
 -#define ClearPortFeature   (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER) << 8) \
 +#define ClearPortFeature   (((USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER) << 8) \
  							| USBH_REQ_CLEAR_FEATURE)
 -#define SetPortFeature     (((USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER) << 8) \
 +#define SetPortFeature     (((USBH_REQTYPE_DIR_OUT | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER) << 8) \
  							| USBH_REQ_SET_FEATURE)
 -#define GetHubDescriptor  (((USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
 +#define GetHubDescriptor  (((USBH_REQTYPE_DIR_IN | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE) << 8) \
  							| USBH_REQ_GET_DESCRIPTOR)
 -#define GetHubStatus      (((USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE) << 8) \
 +#define GetHubStatus      (((USBH_REQTYPE_DIR_IN | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_DEVICE) << 8) \
  							| USBH_REQ_GET_STATUS)
 -#define GetPortStatus     (((USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER) << 8) \
 +#define GetPortStatus     (((USBH_REQTYPE_DIR_IN | USBH_REQTYPE_TYPE_CLASS | USBH_REQTYPE_RECIP_OTHER) << 8) \
  							| USBH_REQ_GET_STATUS)
 @@ -143,6 +140,9 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status);  #define sizeof_array(x) 	(sizeof(x)/sizeof(*(x)))
 +#include "usbh/desciter.h"	/* descriptor iterators */
 +#include "usbh/debug.h"
 +
  #endif
  #endif /* USBH_INTERNAL_H_ */
 diff --git a/os/hal/include/usbh/list.h b/os/hal/include/usbh/list.h index 4eceacd..cdcca04 100644 --- a/os/hal/include/usbh/list.h +++ b/os/hal/include/usbh/list.h @@ -7,11 +7,8 @@  #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)); })
 +#define container_of(ptr, type, member) ((type *)(void *)((char *)(ptr) - offsetof(type, member)))
  #endif
  /*
 @@ -44,21 +41,15 @@ static inline void INIT_LIST_HEAD(struct list_head *list)   * 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,
 +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;
 +        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
 @@ -68,9 +59,9 @@ extern void __list_add(struct list_head *new,   * 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)
 +static inline void list_add(struct list_head *_new, struct list_head *head)
  {
 -        __list_add(new, head, head->next);
 +        __list_add(_new, head, head->next);
  }
 @@ -82,9 +73,9 @@ static inline void list_add(struct list_head *new, struct list_head *head)   * 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)
 +static inline void list_add_tail(struct list_head *_new, struct list_head *head)
  {
 -        __list_add(new, head->prev, head);
 +        __list_add(_new, head->prev, head);
  }
  /*
 @@ -106,7 +97,7 @@ static inline void __list_del(struct list_head * prev, struct list_head * next)   * 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);
 @@ -115,35 +106,6 @@ static inline void __list_del_entry(struct list_head *entry)  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);
  }
  /**
 @@ -157,26 +119,159 @@ static inline void list_del_init(struct list_head *entry)  }
  /**
 - * list_move - delete from one list and add as another's head
 + * list_move_tail - delete from one list and add as another's tail
   * @list: the entry to move
 - * @head: the head that will precede our entry
 + * @head: the head that will follow our entry
   */
 -static inline void list_move(struct list_head *list, struct list_head *head)
 +static inline void list_move_tail(struct list_head *list,
 +                                  struct list_head *head)
  {
          __list_del_entry(list);
 -        list_add(list, head);
 +        list_add_tail(list, head);
  }
 +
  /**
 - * list_move_tail - delete from one list and add as another's tail
 + * 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_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_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_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_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))
 +
 +#if 0
 +
 +/**
 + * 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_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_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_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_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_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_move - delete from one list and add as another's head
   * @list: the entry to move
 - * @head: the head that will follow our entry
 + * @head: the head that will precede our entry
   */
 -static inline void list_move_tail(struct list_head *list,
 -                                  struct list_head *head)
 +static inline void list_move(struct list_head *list, struct list_head *head)
  {
          __list_del_entry(list);
 -        list_add_tail(list, head);
 +        list_add(list, head);
  }
  /**
 @@ -191,15 +286,6 @@ static inline int list_is_last(const struct list_head *list,  }
  /**
 - * 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
   *
 @@ -353,110 +439,28 @@ static inline void list_splice_tail_init(struct 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.
 + * list_replace - replace old entry by new one
 + * @old : the element to be replaced
 + * @new : the new element to insert
   *
 - * 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.
 + * If @old was empty, it will be overwritten.
   */
 -#define list_for_each_safe(pos, n, head) \
 -        for (pos = (head)->next, n = pos->next; pos != (head); \
 -                pos = n, n = pos->next)
 +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;
 +}
 -/**
 - * 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)
 +static inline void list_replace_init(struct list_head *old,
 +                                        struct list_head *_new)
 +{
 +        list_replace(old, _new);
 +        INIT_LIST_HEAD(old);
 +}
 -/**
 - * 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.
 @@ -521,19 +525,6 @@ static inline void list_splice_tail_init(struct list_head *list,               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
 @@ -594,5 +585,6 @@ static inline void list_splice_tail_init(struct list_head *list,   */
  #define list_safe_reset_next(pos, type, n, member)                            \
          n = list_next_entry(pos, type, member)
 +#endif
  #endif /* USBH_LIST_H_ */
  | 
