Fork me on GitHub

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

 







posted @ 2023-09-20 18:50  AnimalRabbit  阅读(71)  评论(0编辑  收藏  举报