ST: USB Host and Device
ST: USB Host and Device
USB Devices实现
可实现用一个USB接口实现多个USB设备,如 HID+MSC; HID+CDC; HID+CDC+MSC等等
使用HAL库及USB库,以HID+MSC为例
一、增加端点
增加端点,同时修改FIFO配置大小,STM32 USB FS FIFO总大小为1.25KB,设置是使用的单位是32bit;
源码 usb_core.c 中的函数
USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev,
USB_OTG_CORE_ID_TypeDef coreID)
中部分内容修改如下:
if (coreID == USB_OTG_FS_CORE_ID) { baseAddress = USB_OTG_FS_BASE_ADDR; pdev->cfg.coreID = USB_OTG_FS_CORE_ID; pdev->cfg.host_channels = 12 ; pdev->cfg.dev_endpoints = 6 ; pdev->cfg.TotalFifoSize = 320; /* in 32-bits */ pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; #ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED pdev->cfg.Sof_output = 1; #endif #ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT pdev->cfg.low_power = 1; #endif }
另一个函数
USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev)
部分内容修改如下:
if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID ) { /* Set Full speed phy */ USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_FULL); /* set Rx FIFO size */ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE); /* EP0 TX*/ nptxfifosize.b.depth = TX0_FIFO_FS_SIZE; nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 ); /* EP1 TX*/ txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth; txfifosize.b.depth = TX1_FIFO_FS_SIZE; USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 ); /* EP2 TX*/ txfifosize.b.startaddr += txfifosize.b.depth; txfifosize.b.depth = TX2_FIFO_FS_SIZE; USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 ); /* EP3 TX*/ txfifosize.b.startaddr += txfifosize.b.depth; txfifosize.b.depth = TX3_FIFO_FS_SIZE; USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 ); /* EP4 TX*/ txfifosize.b.startaddr += txfifosize.b.depth; txfifosize.b.depth = TX4_FIFO_FS_SIZE; USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[3], txfifosize.d32 ); /* EP5 TX*/ txfifosize.b.startaddr += txfifosize.b.depth; txfifosize.b.depth = TX5_FIFO_FS_SIZE; USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[4], txfifosize.d32 ); }
二、更改设备描述符
usbd_desc.c 文件中部分内容修改如下
uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] = { 0x12, /*bLength */ USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/ 0x00, /*bcdUSB */ 0x02, 0xEF, /*bDeviceClass*/ 0x02, /*bDeviceSubClass*/ 0x01, /*bDeviceProtocol*/ USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID), /*idVendor*/ HIBYTE(USBD_PID), /*idVendor*/ 0x00, /*bcdDevice rel. 2.00*/ 0x02, USBD_IDX_MFC_STR, /*Index of manufacturer string*/ USBD_IDX_PRODUCT_STR, /*Index of product string*/ USBD_IDX_SERIAL_STR, /*Index of serial number string*/ USBD_CFG_MAX_NUM /*bNumConfigurations*/ } ; /* USB_DeviceDescriptor */
三、HID+MSC内核配置
新建 usbd_hid_msc_core.c 文件。
1、新建结构体
USBD_Class_cb_TypeDef USBD_MSC_HID_cb = { USBD_MSC_HID_Init, USBD_MSC_HID_DeInit, USBD_MSC_HID_Setup, NULL, /*EP0_TxSent*/ USBD_MSC_HID_EP0_RxReady, /*EP0_RxReady*/ USBD_MSC_HID_DataIn, /*DataIn*/ USBD_MSC_HID_DataOut, /*DataOut*/ NULL, /*SOF */ NULL, NULL, USBD_MSC_HID_GetCfgDesc, #ifdef USB_OTG_HS_CORE USBD_MSC_HID_GetCfgDesc, /* use same config as per FS */ #endif };
2、配置描述符
__ALIGN_BEGIN static uint8_t USBD_MSC_HID_CfgDesc[USB_MSC_HID_CONFIG_DESC_SIZ] __ALIGN_END = { /***************配置描述符***********************/ 0x09, /* bLength: Configuration Descriptor size */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ USB_MSC_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 0x00, 0x02, /*bNumInterfaces: 2 interface*/ 0x01, /*bConfigurationValue: Configuration value*/ 0x00, /*iConfiguration: Index of string descriptor describing the configuration*/ 0xC2, /*bmAttributes: bus powered and Support Remote Wake-up */ 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ /*---------------------------------------------------------------------------*/ //IAD Interface Association Descriptor USBD_IAD_DESC_SIZE ,//bLenght:Interface Descriptor size USBD_IAD_DESCRIPTOR_TYPE ,//bDescriptorType:IAD HID_INTERFACE,//bFirstInterface 0x01,//bInterfaceCount 0x03,//bFunctionClass:CDC 0x00,//bFunctionSubClass 0x00,//bInterfaceProtocol 0x02,//iFunction /************** Descriptor of Custom HID interface ****************/ /* 09 */ 0x09, /*bLength: Interface Descriptor size*/ USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*///接口描述符编号 HID_INTERFACE, /*bInterfaceNumber: Number of Interface*/ //该接口的编号 第一个编号 为0 0x00, /*bAlternateSetting: Alternate setting*/ //备用接口编号 0x02, /*bNumEndpoints*/ //非0端点的数目。该接口有2个批量端点 0x03, /*bInterfaceClass: HID*/ //该接口所使用的类。 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ 0, /*iInterface: Index of string descriptor*/ /******************** Descriptor of Custom HID ********************/ /* 18 */ 0x09, /*bLength: HID Descriptor size*/ CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ 0x11, /*bcdHID: HID Class Spec release number*/ 0x01, 0x00, /*bCountryCode: Hardware target country*/ 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ 0x22, /*bDescriptorType*/ USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ 0x00, /******************** Descriptor of HID endpoint ********************/ /* 27 */ 0x07, /*bLength: Endpoint Descriptor size*/ USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/ HID_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/ 0x03, /*bmAttributes: Interrupt endpoint*/ HID_IN_PACKET, /*wMaxPacketSize: 4 Byte max */ 0x00, 0x0A, /*bInterval: Polling Interval (10 ms)*/ /* 34 */ 0x07, /*bLength: Endpoint Descriptor size*/ USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/ HID_OUT_EP, /*bEndpointAddress: Endpoint Address (IN)*/ 0x03, /*bmAttributes: Interrupt endpoint*/ HID_OUT_PACKET, /*wMaxPacketSize: 4 Byte max */ 0x00, 0x10, /* bInterval: Polling Interval (31 ms) */ /* 34 */ /*---------------------------------------------------------------------------*/ //IAD Interface Association Descriptor USBD_IAD_DESC_SIZE ,//bLenght:Interface Descriptor size USBD_IAD_DESCRIPTOR_TYPE ,//bDescriptorType:IAD MSC_INTERFACE,//bFirstInterface 0x01,//bInterfaceCount 0x08,//bFunctionClass:MSC 0x06,//bFunctionSubClass 0x50,//bInterfaceProtocol 0x05,//iFunction /******************** Mass Storage interface ********************/ 0x09, /* bLength: Interface Descriptor size */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ MSC_INTERFACE, /* bInterfaceNumber: Number of Interface */ //该接口的编号 第二个接口 编号为1 0x00, /* bAlternateSetting: Alternate setting */ //备用编号 0x02, /* bNumEndpoints*/ 0x08, /* bInterfaceClass: MSC Class */ //该接口所使用的类 大容量存储设备 0x08 0x06, /* bInterfaceSubClass : SCSI transparent command set*///SCSI透明命令集的子类代码为0x06。 0x50, /* nInterfaceProtocol */ //协议为仅批量传输,代码为0x50。 0x05, /* iInterface: */ //该接口的字符串索引值 /******************** Mass Storage Endpoints ********************/ 0x07, /*Endpoint descriptor length = 7*/ USB_ENDPOINT_DESCRIPTOR_TYPE, /*Endpoint descriptor type */ MSC_IN_EP, /*Endpoint address (IN, address 1) */ 0x02, /*Bulk endpoint type */ 0x40, 0x00, 0x00, /*Polling interval in milliseconds */ 0x07, /*Endpoint descriptor length = 7 */ 0x05, /*Endpoint descriptor type */ MSC_OUT_EP, /*Endpoint address (OUT, address 1) */ 0x02, /*Bulk endpoint type */ 0x40, 0x00, 0x00 /*Polling interval in milliseconds*/ } ;
3、实现函数
以 USBD_MSC_HID_Init() 函数为例,其他函数同理。
static uint8_t USBD_MSC_HID_Init (void *pdev, uint8_t cfgidx) { /* HID initialization */ USBD_CUSTOM_HID_Init (pdev,cfgidx); /* MSC initialization */ USBD_MSC_Init (pdev,cfgidx); return USBD_OK; }
在加上结构体中的其他函数。
四、初始化使用
USBD_Init(&USB_OTG_dev,USB_OTG_FS_CORE_ID,&USR_desc,&USBD_MSC_HID_cb,&USR_cb);