可实现用一个USB接口实现多个USB设备,如 HID+MSC; HID+CDC; HID+CDC+MSC等等
使用HAL库,以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 */
新建 usbd_hid_msc_core.c 文件。
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
};
__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*/
} ;
以 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);