【温故而知新】类似文章浅析USB HID ReportDesc (HID报告描述符)
现在将en.stm32cubef1\STM32Cube_FW_F1_V1.4.0\Middlewares\ST\STM32_USB_Host_Library\Core\Inc\usbh_def.H
/********************************************************************************* @file usbh_def.h* @author MCD Application Team* @version V3.2.2* @date 07-July-2015* @brief Definitions used in the USB host library******************************************************************************* @attention** <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>** Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2** 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.********************************************************************************//* Define to prevent recursive ----------------------------------------------*/ #ifndef USBH_DEF_H #define USBH_DEF_H#ifdef __cplusplusextern "C" { #endif/* Includes ------------------------------------------------------------------*/ #include "usbh_conf.h"/** @addtogroup USBH_LIB* @{*//** @addtogroup USBH_LIB_CORE * @{ *//** @defgroup USBH_DEF* @brief This file is includes USB descriptors* @{*/ #ifndef NULL #define NULL 0 #endif#ifndef FALSE #define FALSE 0 #endif#ifndef TRUE #define TRUE 1 #endif#define ValBit(VAR,POS) (VAR & (1 << POS)) #define SetBit(VAR,POS) (VAR |= (1 << POS)) #define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255))#define LE16(addr) (((uint16_t)(*((uint8_t *)(addr))))\+ (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))#define LE16S(addr) (uint16_t)(LE16((addr)))#define LE32(addr) ((((uint32_t)(*(((uint8_t *)(addr)) + 0))) + \(((uint32_t)(*(((uint8_t *)(addr)) + 1))) << 8) + \(((uint32_t)(*(((uint8_t *)(addr)) + 2))) << 16) + \(((uint32_t)(*(((uint8_t *)(addr)) + 3))) << 24)))#define LE64(addr) ((((uint64_t)(*(((uint8_t *)(addr)) + 0))) + \(((uint64_t)(*(((uint8_t *)(addr)) + 1))) << 8) +\(((uint64_t)(*(((uint8_t *)(addr)) + 2))) << 16) +\(((uint64_t)(*(((uint8_t *)(addr)) + 3))) << 24) +\(((uint64_t)(*(((uint8_t *)(addr)) + 4))) << 32) +\(((uint64_t)(*(((uint8_t *)(addr)) + 5))) << 40) +\(((uint64_t)(*(((uint8_t *)(addr)) + 6))) << 48) +\(((uint64_t)(*(((uint8_t *)(addr)) + 7))) << 56)))#define LE24(addr) ((((uint32_t)(*(((uint8_t *)(addr)) + 0))) + \(((uint32_t)(*(((uint8_t *)(addr)) + 1))) << 8) + \(((uint32_t)(*(((uint8_t *)(addr)) + 2))) << 16)))#define LE32S(addr) (int32_t)(LE32((addr)))#define USB_LEN_DESC_HDR 0x02 #define USB_LEN_DEV_DESC 0x12 #define USB_LEN_CFG_DESC 0x09 #define USB_LEN_IF_DESC 0x09 #define USB_LEN_EP_DESC 0x07 #define USB_LEN_OTG_DESC 0x03 #define USB_LEN_SETUP_PKT 0x08/* bmRequestType :D7 Data Phase Transfer Direction */ #define USB_REQ_DIR_MASK 0x80 #define USB_H2D 0x00 #define USB_D2H 0x80/* bmRequestType D6..5 Type */ #define USB_REQ_TYPE_STANDARD 0x00 #define USB_REQ_TYPE_CLASS 0x20 #define USB_REQ_TYPE_VENDOR 0x40 #define USB_REQ_TYPE_RESERVED 0x60/* bmRequestType D4..0 Recipient */ #define USB_REQ_RECIPIENT_DEVICE 0x00 #define USB_REQ_RECIPIENT_INTERFACE 0x01 #define USB_REQ_RECIPIENT_ENDPOINT 0x02 #define USB_REQ_RECIPIENT_OTHER 0x03/* Table 9-4. Standard Request Codes */ /* bRequest , Value */ #define USB_REQ_GET_STATUS 0x00 #define USB_REQ_CLEAR_FEATURE 0x01 #define USB_REQ_SET_FEATURE 0x03 #define USB_REQ_SET_ADDRESS 0x05 #define USB_REQ_GET_DESCRIPTOR 0x06 #define USB_REQ_SET_DESCRIPTOR 0x07 #define USB_REQ_GET_CONFIGURATION 0x08 #define USB_REQ_SET_CONFIGURATION 0x09 #define USB_REQ_GET_INTERFACE 0x0A #define USB_REQ_SET_INTERFACE 0x0B #define USB_REQ_SYNCH_FRAME 0x0C/* Table 9-5. Descriptor Types of USB Specifications */ #define USB_DESC_TYPE_DEVICE 1 #define USB_DESC_TYPE_CONFIGURATION 2 #define USB_DESC_TYPE_STRING 3 #define USB_DESC_TYPE_INTERFACE 4 #define USB_DESC_TYPE_ENDPOINT 5 #define USB_DESC_TYPE_DEVICE_QUALIFIER 6 #define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 #define USB_DESC_TYPE_INTERFACE_POWER 8 #define USB_DESC_TYPE_HID 0x21 #define USB_DESC_TYPE_HID_REPORT 0x22#define USB_DEVICE_DESC_SIZE 18 #define USB_CONFIGURATION_DESC_SIZE 9 #define USB_HID_DESC_SIZE 9 #define USB_INTERFACE_DESC_SIZE 9 #define USB_ENDPOINT_DESC_SIZE 7/* Descriptor Type and Descriptor Index */ /* Use the following values when calling the function USBH_GetDescriptor */ #define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00) #define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00) #define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00) #define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00) #define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00) #define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00) #define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00) #define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00) #define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00) #define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00)#define USB_EP_TYPE_CTRL 0x00 #define USB_EP_TYPE_ISOC 0x01 #define USB_EP_TYPE_BULK 0x02 #define USB_EP_TYPE_INTR 0x03#define USB_EP_DIR_OUT 0x00 #define USB_EP_DIR_IN 0x80 #define USB_EP_DIR_MSK 0x80 #ifndef USBH_MAX_PIPES_NBR#define USBH_MAX_PIPES_NBR 15 #endif /* USBH_MAX_PIPES_NBR */#define USBH_DEVICE_ADDRESS_DEFAULT 0 #define USBH_MAX_ERROR_COUNT 2 #define USBH_DEVICE_ADDRESS 1/*** @}*/ #define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \+ USB_INTERFACE_DESC_SIZE\+ (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE))#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\ConfigurationDescriptor.wTotalLength)typedef union {uint16_t w;struct BW{uint8_t msb;uint8_t lsb;}bw; } uint16_t_uint8_t;typedef union _USB_Setup {uint32_t d8[2];struct _SetupPkt_Struc{uint8_t bmRequestType;uint8_t bRequest;uint16_t_uint8_t wValue;uint16_t_uint8_t wIndex;uint16_t_uint8_t wLength;} b; } USB_Setup_TypeDef; typedef struct _DescHeader {uint8_t bLength; uint8_t bDescriptorType; } USBH_DescHeader_t;typedef struct _DeviceDescriptor {uint8_t bLength;uint8_t bDescriptorType;uint16_t bcdUSB; /* USB Specification Number which device complies too */uint8_t bDeviceClass;uint8_t bDeviceSubClass; uint8_t bDeviceProtocol;/* If equal to Zero, each interface specifies its own classcode if equal to 0xFF, the class code is vendor specified.Otherwise field is valid Class Code.*/uint8_t bMaxPacketSize;uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */uint16_t bcdDevice; /* Device Release Number */uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */uint8_t iProduct; /* Index of Product String Descriptor */uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */uint8_t bNumConfigurations; /* Number of Possible Configurations */ } USBH_DevDescTypeDef;typedef struct _EndpointDescriptor {uint8_t bLength;uint8_t bDescriptorType;uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */uint8_t bmAttributes; /* specifies the transfer type. */uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */ uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */ } USBH_EpDescTypeDef;typedef struct _InterfaceDescriptor {uint8_t bLength;uint8_t bDescriptorType;uint8_t bInterfaceNumber;uint8_t bAlternateSetting; /* Value used to select alternative setting */uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */uint8_t bInterfaceProtocol; /* Protocol Code */uint8_t iInterface; /* Index of String Descriptor Describing this interface */USBH_EpDescTypeDef Ep_Desc[USBH_MAX_NUM_ENDPOINTS]; } USBH_InterfaceDescTypeDef;typedef struct _ConfigurationDescriptor {uint8_t bLength;uint8_t bDescriptorType;uint16_t wTotalLength; /* Total Length of Data Returned */uint8_t bNumInterfaces; /* Number of Interfaces */uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/uint8_t iConfiguration; /*Index of String Descriptor Describing this configuration */uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/uint8_t bMaxPower; /*Maximum Power Consumption */USBH_InterfaceDescTypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES]; } USBH_CfgDescTypeDef;/* Following USB Host status */ typedef enum {USBH_OK = 0,USBH_BUSY,USBH_FAIL,USBH_NOT_SUPPORTED,USBH_UNRECOVERED_ERROR,USBH_ERROR_SPEED_UNKNOWN, }USBH_StatusTypeDef;/** @defgroup USBH_CORE_Exported_Types* @{*/typedef enum {USBH_SPEED_HIGH = 0,USBH_SPEED_FULL = 1,USBH_SPEED_LOW = 2, }USBH_SpeedTypeDef;/* Following states are used for gState */ typedef enum {HOST_IDLE =0,HOST_DEV_WAIT_FOR_ATTACHMENT, HOST_DEV_ATTACHED,HOST_DEV_DISCONNECTED, HOST_DETECT_DEVICE_SPEED,HOST_ENUMERATION,HOST_CLASS_REQUEST, HOST_INPUT,HOST_SET_CONFIGURATION,HOST_CHECK_CLASS,HOST_CLASS,HOST_SUSPENDED,HOST_ABORT_STATE, }HOST_StateTypeDef; /* Following states are used for EnumerationState */ typedef enum {ENUM_IDLE = 0,ENUM_GET_FULL_DEV_DESC,ENUM_SET_ADDR,ENUM_GET_CFG_DESC,ENUM_GET_FULL_CFG_DESC,ENUM_GET_MFC_STRING_DESC,ENUM_GET_PRODUCT_STRING_DESC,ENUM_GET_SERIALNUM_STRING_DESC, } ENUM_StateTypeDef; /* Following states are used for CtrlXferStateMachine */ typedef enum {CTRL_IDLE =0,CTRL_SETUP,CTRL_SETUP_WAIT,CTRL_DATA_IN,CTRL_DATA_IN_WAIT,CTRL_DATA_OUT,CTRL_DATA_OUT_WAIT,CTRL_STATUS_IN,CTRL_STATUS_IN_WAIT,CTRL_STATUS_OUT,CTRL_STATUS_OUT_WAIT,CTRL_ERROR,CTRL_STALLED,CTRL_COMPLETE }CTRL_StateTypeDef; /* Following states are used for RequestState */ typedef enum {CMD_IDLE =0,CMD_SEND,CMD_WAIT } CMD_StateTypeDef; typedef enum {USBH_URB_IDLE = 0,USBH_URB_DONE,USBH_URB_NOTREADY,USBH_URB_NYET, USBH_URB_ERROR,USBH_URB_STALL }USBH_URBStateTypeDef;typedef enum {USBH_PORT_EVENT = 1, USBH_URB_EVENT,USBH_CONTROL_EVENT, USBH_CLASS_EVENT, USBH_STATE_CHANGED_EVENT, } USBH_OSEventTypeDef;/* Control request structure */ typedef struct {uint8_t pipe_in; uint8_t pipe_out; uint8_t pipe_size; uint8_t *buff;uint16_t length;uint16_t timer; USB_Setup_TypeDef setup;CTRL_StateTypeDef state; uint8_t errorcount; } USBH_CtrlTypeDef;/* Attached device structure */ typedef struct { #if (USBH_KEEP_CFG_DESCRIPTOR == 1) uint8_t CfgDesc_Raw[USBH_MAX_SIZE_CONFIGURATION]; #endif uint8_t Data[USBH_MAX_DATA_BUFFER];uint8_t address;uint8_t speed;__IO uint8_t is_connected; uint8_t current_interface; USBH_DevDescTypeDef DevDesc;USBH_CfgDescTypeDef CfgDesc; }USBH_DeviceTypeDef;struct _USBH_HandleTypeDef;/* USB Host Class structure */ typedef struct {const char *Name;uint8_t ClassCode; USBH_StatusTypeDef (*Init) (struct _USBH_HandleTypeDef *phost);USBH_StatusTypeDef (*DeInit) (struct _USBH_HandleTypeDef *phost);USBH_StatusTypeDef (*Requests) (struct _USBH_HandleTypeDef *phost); USBH_StatusTypeDef (*BgndProcess) (struct _USBH_HandleTypeDef *phost);USBH_StatusTypeDef (*SOFProcess) (struct _USBH_HandleTypeDef *phost); void* pData; } USBH_ClassTypeDef;/* USB Host handle structure */ typedef struct _USBH_HandleTypeDef {__IO HOST_StateTypeDef gState; /* Host State Machine Value */ENUM_StateTypeDef EnumState; /* Enumeration state Machine */CMD_StateTypeDef RequestState; USBH_CtrlTypeDef Control;USBH_DeviceTypeDef device;USBH_ClassTypeDef* pClass[USBH_MAX_NUM_SUPPORTED_CLASS];USBH_ClassTypeDef* pActiveClass;uint32_t ClassNumber;uint32_t Pipes[15];__IO uint32_t Timer;uint8_t id; void* pData; void (* pUser )(struct _USBH_HandleTypeDef *pHandle, uint8_t id);#if (USBH_USE_OS == 1)osMessageQId os_event; osThreadId thread; #endif } USBH_HandleTypeDef;#if defined ( __GNUC__ )#ifndef __weak#define __weak __attribute__((weak))#endif /* __weak */#ifndef __packed#define __packed __attribute__((__packed__))#endif /* __packed */ #endif /* __GNUC__ */#ifdef __cplusplus } #endif#endif /* USBH_DEF_H *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
现在我们先看看 USBH_DevDescTypeDef结构体
/* Attached device structure */ typedef struct { #if (USBH_KEEP_CFG_DESCRIPTOR == 1) uint8_t CfgDesc_Raw[USBH_MAX_SIZE_CONFIGURATION]; #endif uint8_t Data[USBH_MAX_DATA_BUFFER];uint8_t address;uint8_t speed;__IO uint8_t is_connected; uint8_t current_interface; USBH_DevDescTypeDef DevDesc; USBH_CfgDescTypeDef CfgDesc; }USBH_DeviceTypeDef;
在看 USBH_DevDescTypeDef DevDesc之前我们先看 Universal Serial Bus Specification Revision 2.0 的
Table 9-8. Standard Device Descriptor
会发现USBH_DevDescTypeDef DevDesc就是上面的表格
typedef struct _DeviceDescriptor {uint8_t bLength;uint8_t bDescriptorType;uint16_t bcdUSB; /* USB Specification Number which device complies too */uint8_t bDeviceClass;uint8_t bDeviceSubClass; uint8_t bDeviceProtocol;/* If equal to Zero, each interface specifies its own classcode if equal to 0xFF, the class code is vendor specified.Otherwise field is valid Class Code.*/uint8_t bMaxPacketSize;uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */uint16_t bcdDevice; /* Device Release Number */uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */uint8_t iProduct; /* Index of Product String Descriptor */uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */uint8_t bNumConfigurations; /* Number of Possible Configurations */ } USBH_DevDescTypeDef;
在看 USBH_CfgDescTypeDef CfgDesc;之前我们看看
Table 9-10. Standard Configuration Descriptor
但是我们USBH_CfgDescTypeDef CfgDesc中多了USBH_InterfaceDescTypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES]
typedef struct _ConfigurationDescriptor
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength; /* Total Length of Data Returned */
uint8_t bNumInterfaces; /* Number of Interfaces */
uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/
uint8_t iConfiguration; /*Index of String Descriptor Describing this configuration */
uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/
uint8_t bMaxPower; /*Maximum Power Consumption */
USBH_InterfaceDescTypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES];
}
USBH_CfgDescTypeDef;
我们继续翻书
Table 9-12. Standard Interface Descriptor
我们会发现USBH_InterfaceDescTypeDef中有多了 USBH_EpDescTypeDef Ep_Desc[USBH_MAX_NUM_ENDPOINTS];
typedef struct _InterfaceDescriptor {uint8_t bLength;uint8_t bDescriptorType;uint8_t bInterfaceNumber;uint8_t bAlternateSetting; /* Value used to select alternative setting */uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */uint8_t bInterfaceProtocol; /* Protocol Code */uint8_t iInterface; /* Index of String Descriptor Describing this interface */USBH_EpDescTypeDef Ep_Desc[USBH_MAX_NUM_ENDPOINTS]; } USBH_InterfaceDescTypeDef;
还是老规则先翻书
Table 9-13. Standard Endpoint Descriptor
typedef struct _EndpointDescriptor {uint8_t bLength;uint8_t bDescriptorType;uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */uint8_t bmAttributes; /* specifies the transfer type. */uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */ uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */ } USBH_EpDescTypeDef;
其实上面的描述符