本文共 6843 字,大约阅读时间需要 22 分钟。
芯片:STM32F407VE
编译器:KEIL5
作者:SY
日期:2017-7-19 08:14:14
STM32
USB
枚举用到比较重要的寄存器:OTG_HS 主机端口控制和状态寄存器 (OTG_HS_HPRT)
系统复位
USB
连接,延时100ms
USB
设备复位,主机检测到端口使能位置位
,与设备建立连接USB
设备复位,复位结束,开始枚举过程。8
个通道,其中IN
占用0通道,OUT
占用1通道。打开IN
和OUT
管道获取设备描述符
,只获取8个字节,为了得到通道0的最大包长度。将状态机调整到HOST_CTRL_XFER
。同时备份当前全局状态,便于跳转到HOST_CTRL_XFER
恢复状态。
USBH_Get_DevDesc(pdev , phost, 8); -->USBH_GetDescriptor(); --> phost->Control.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR; //发送的请求 phost->Control.setup.b.wLength.w = length; //数据长度。如果为0,则在[控制传输]中忽略数据阶段 USBH_CtlReq(); --> USBH_SubmitSetupRequest(); --> USBH_HandleControl(); --> CTRL_SETUP -> CTRL_SETUP_WAIT -> if (phost->Control.setup.b.wLength.w); then [CTRL_DATA_IN/CTRL_DATA_OUT] else [CTRL_STATUS_IN/CTRL_STATUS_OUT] fi
SETUP
令牌包,等待回复DATA1
数据包,等待回复流程走完后,获取到当前通道的最大包长度64
,因此修改当前通道的最大包长度为64
获取全部设备描述符,长度18
字节
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_DevDesc_TypeDef;
bMaxPacketSize
最大包大小VID
、PID
设置地址
#define USBH_DEVICE_ADDRESS 1USBH_SetAddress(pdev, phost, USBH_DEVICE_ADDRESS) -->phost->Control.setup.b.wValue.w = (uint16_t)DeviceAddress;USBH_CtlReq(pdev, phost, 0 , 0 ); --> USBH_HandleControl(); -->
typedef union _USB_Setup{uint8_t d8[8];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;
SETUP
包一共包含8
个字节+ 将设备的地址设置为`1`,`SETUP`包包含设备地址字段+ 发送`SETUP`令牌包,等待回复+ 发送状态,回复从机
获取配置描述符
#define USB_CONFIGURATION_DESC_SIZE 9USBH_Get_CfgDesc(pdev, phost, USB_CONFIGURATION_DESC_SIZE); -->USBH_GetDescriptor(); --> USBH_ParseCfgDesc();
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_CfgDesc_TypeDef;
wTotalLength
的值。实测wTotalLength=32
获取配置描述符集合
/* get FULL config descriptor (config, interface, endpoints) */USBH_Get_CfgDesc(pdev, phost, phost->device_prop.Cfg_Desc.wTotalLength); -->USBH_GetDescriptor(); --> USBH_ParseCfgDesc();
获取到的数据存储在数组中,数据结构如下:
typedef struct _DescHeader { uint8_t bLength; uint8_t bDescriptorType;} USBH_DescHeader_t;
描述符类型bDescriptorType
列表:
/* 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
解析数据:
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_InterfaceDesc_TypeDef;
获取到bNumEndpoints
端点个数为2
。
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_EpDesc_TypeDef;
通知用户,此时通过接口描述符可以知道设备是哪一种类:
#define MSC_CLASS 0x08 /* MSC */#define HID_CLASS 0x03 /* HID */#define USB_AUDIO 0x01 /* Audio */#define USB_CDCC 0x02 /* Communications and CDC Control */#define USB_HID 0x03 /* HID (Human Interface Device) */#define USB_PRINTER 0x07 /* Printer */#define USB_MSC 0x08 /* Mass Storage */#define USB_HUB 0x09 /* Hub */#define USB_CDCD 0x0A /* CDC-Data */#define USB_SMARTCARD 0x0B /* Smart Card */#define USB_VIDEO 0x0E /* Video */#define USB_AVD 0x10 /* Audio/Video Devices */
获取生产厂家字符串描述符
USBH_Get_StringDesc --> USBH_GetDescriptor --> USBH_ParseStringDesc -->
3SYSTEM
获取产品字符串描述符
USBH_Get_StringDesc -->USBH_GetDescriptor --> USBH_ParseStringDesc -->
USB Flash Disk
获取产品序列号
USBH_Get_StringDesc -->USBH_GetDescriptor --> USBH_ParseStringDesc -->
000000000000FD70AC4E2030
设置配置
USBH_SetCfg -->USBH_CtlReq -->
枚举完成!
转载地址:http://qnzii.baihongyu.com/