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);