[STM32F4] STM32F4适配WINUSB1.0

[复制链接]
788|0
 楼主| tpgf 发表于 2025-1-10 09:42 | 显示全部楼层 |阅读模式
通过cubeMX生成USB CDC基础工程
过程略

修改工程代码
修改usbd_conf.h文件
添加如下宏定义

#define USBD_SUPPORT_WINUSB       1


修改usbd_def.h文件
添加如下宏定义

9847067807b003feed.png

#if (USBD_SUPPORT_WINUSB == 1)
#define  USB_REQ_MS_VENDOR_CODE                         0xA0U
#endif


USB类定义部分添加如下内容

5001467807af4ac7d9.png

#if (USBD_SUPPORT_WINUSB == 1)
  uint8_t  *(*GetWinUSBOSDescriptor)(uint16_t *length);
#endif


USB描述符类型定义结构体部分添加如下如下内容

370167807aead6f84.png

#if (USBD_SUPPORT_WINUSB == 1) //新增
  uint8_t *(*GetWinUSBOSFeatureDescriptor)(uint16_t *length);
  uint8_t *(*GetWinUSBOSPropertyDescriptor)(uint16_t *length);
#endif


修改usbd_desc.c文件
修改开始部分的宏定义,根据自己的需求修改即可,注意:VID和PID不要用和默认工程一样的

8913367807ae20089b.png

添加函数声明

4281267807ad81ec11.png

#if (USBD_SUPPORT_WINUSB == 1)
uint8_t *USBD_WinUSBOSStrDescriptor(uint16_t *length);
uint8_t *USBD_WinUSBOSFeatureDescriptor(uint16_t *length);
uint8_t *USBD_WinUSBOSPropertyDescriptor(uint16_t *length);
#endif


修改描述符结构体定义部分

8438267807acd2807d.png

#if (USBD_SUPPORT_WINUSB == 1)
, USBD_WinUSBOSFeatureDescriptor
, USBD_WinUSBOSPropertyDescriptor
#endif


描述符部分后面添加如下内容

#if (USBD_SUPPORT_WINUSB == 1)
#define USB_LEN_OS_FEATURE_DESC 0x28
#if defined ( __ICCARM__ ) /* IAR Compiler */
  #pragma data_alignment=4
#endif /* defined ( __ICCARM__ ) */

__ALIGN_BEGIN uint8_t USBD_WINUSB_OSFeatureDesc[USB_LEN_OS_FEATURE_DESC] __ALIGN_END =
{
   0x28, 0, 0, 0, // length
   0, 1,          // bcd version 1.0
   4, 0,          // windex: extended compat ID descritor
   1,             // no of function
   0, 0, 0, 0, 0, 0, 0, // reserve 7 bytes
// function
   0,             // interface no
   0,             // reserved
   'W', 'I', 'N', 'U', 'S', 'B', 0, 0, //  first ID
     0,   0,   0,   0,   0,   0, 0, 0,  // second ID
     0,   0,   0,   0,   0,   0 // reserved 6 bytes      
};
#define USB_LEN_OS_PROPERTY_DESC 0x8E
#if defined ( __ICCARM__ ) /* IAR Compiler */
  #pragma data_alignment=4
#endif /* defined ( __ICCARM__ ) */
__ALIGN_BEGIN uint8_t USBD_WINUSB_OSPropertyDesc[USB_LEN_OS_PROPERTY_DESC] __ALIGN_END =
{
      0x8E, 0, 0, 0,  // length 246 byte
      0x00, 0x01,   // BCD version 1.0
      0x05, 0x00,   // Extended Property Descriptor Index(5)
      0x01, 0x00,   // number of section (1)
//; property section        
      0x84, 0x00, 0x00, 0x00,   // size of property section
      0x1, 0, 0, 0,   //; property data type (1)
      0x28, 0,        //; property name length (42)
      'D', 0,
      'e', 0,
      'v', 0,
      'i', 0,
      'c', 0,
      'e', 0,
      'I', 0,
      'n', 0,
      't', 0,
      'e', 0,
      'r', 0,
      'f', 0,
      'a', 0,
      'c', 0,
      'e', 0,
      'G', 0,
      'U', 0,
      'I', 0,
      'D', 0,
      0, 0,
      // change by yourself
      0x4E, 0, 0, 0,  // ; property data length
      '{', 0,
      '1', 0,
      '2', 0,
      '3', 0,
      '4', 0,
      '5', 0,
      '6', 0,
      '7', 0,
      '8', 0,
      '-', 0,
      'A', 0,
      'B', 0,
      'C', 0,
      'D', 0,
      '-', 0,
      '1', 0,
      '2', 0,
      '3', 0,
      '4', 0,
      '-', 0,
      'A', 0,
      'B', 0,
      'C', 0,
      'D', 0,
      '-', 0,
      'F', 0,
      'E', 0,
      'D', 0,
      'C', 0,
      'B', 0,
      'A', 0,
      '9', 0,
      '8', 0,
      '7', 0,
      '6', 0,
      '5', 0,
      '4', 0,
      '}', 0,
      0, 0,

};
#endif



文件最后部分添加函数实现

#if (USBD_SUPPORT_WINUSB==1)

const uint8_t USBD_OS_STRING[8] = {
   'M',
   'S',
   'F',
   'T',
   '1',
   '0',
   '0',
   USB_REQ_MS_VENDOR_CODE,
};
uint8_t *USBD_WinUSBOSStrDescriptor(uint16_t *length)
{
   USBD_GetString((uint8_t *)USBD_OS_STRING, USBD_StrDesc, length);
   return USBD_StrDesc;
}
uint8_t *USBD_WinUSBOSFeatureDescriptor(uint16_t *length)
{
  *length = USB_LEN_OS_FEATURE_DESC;
  return USBD_WINUSB_OSFeatureDesc;
}
uint8_t *USBD_WinUSBOSPropertyDescriptor(uint16_t *length)
{
  *length = USB_LEN_OS_PROPERTY_DESC;
   return USBD_WINUSB_OSPropertyDesc;
}
#endif // (USBD_SUPPORT_WINUSB==1)



修改usbd_cdc.c文件
添加函数声明

9618767807aafbe61b.png

USBD_CDC类定义部分添加如下内容

4422667807aa49eaf4.png

  #if (USBD_SUPPORT_WINUSB==1)   
  USBD_WinUSBOSStrDescriptor
  #endif


将配置描述符部分都修改为如下一样的内容

#define WINUSB_CONFIG_DESC_SIZE 32
__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[WINUSB_CONFIG_DESC_SIZE] __ALIGN_END =
{
  /*Configuration Descriptor*/
  0x09,   /* bLength: Configuration Descriptor size */
  USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
  WINUSB_CONFIG_DESC_SIZE,                /* wTotalLength:no of returned bytes */
  0x00,
  0x01,   /* bNumInterfaces: 1 interface for Game IO */
  0x01,   /* bConfigurationValue: Configuration value */
  USBD_IDX_CONFIG_STR,   /* iConfiguration: Index of string descriptor describing the configuration */
  0xC0,   /* bmAttributes: self powered */
  0x32,   /* MaxPower 0 mA */

  /*---------------------------------------------------------------------------*/
  /*Data class interface descriptor*/
  0x09,   /* bLength: Endpoint Descriptor size */
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
  0x00,   /* bInterfaceNumber: Number of Interface, zero based index of this interface */
  0x00,   /* bAlternateSetting: Alternate setting */
  0x02,   /* bNumEndpoints: Two endpoints used */
  0xff,   /* bInterfaceClass: vendor */
//  0x00,   /* bInterfaceClass: vendor */
  0x00,   /* bInterfaceSubClass: */
  0x00,   /* bInterfaceProtocol: */
  0x00,   /* iInterface: */

  /*Endpoint OUT Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
  CDC_OUT_EP,                        /* bEndpointAddress */
  0x02,                              /* bmAttributes: Bulk */
  LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
  0x00,                              /* bInterval: ignore for Bulk transfer */

  /*Endpoint IN Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
  CDC_IN_EP,                         /* bEndpointAddress */
  0x02,                              /* bmAttributes: Bulk */
  LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
  0x00                               /* bInterval: ignore for Bulk transfer */
} ;  



修改usbd_ctlreq.c文件
添加如下函数声明

119367807a6adf9fc.png

#if (USBD_SUPPORT_WINUSB==1)
static void USBD_WinUSBGetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
#endif


USBD_StdDevReq函数部分添加如下内容

7591167807a1eb5c49.png

  #if (USBD_SUPPORT_WINUSB==1)
  if(req->bRequest == USB_REQ_MS_VENDOR_CODE)
  {
    USBD_WinUSBGetDescriptor( pdev, req );
    return ret;
  }
  #endif


USBD_GetDescriptor函数部分添加如下内容


#if (USBD_SUPPORT_WINUSB==1)
        case 0xEE: // OS String
          if (pdev->pClass->GetWinUSBOSDescriptor != NULL)
          {
            pbuf = pdev->pClass->GetWinUSBOSDescriptor(&len);
          }
          else
          {
            USBD_CtlError(pdev, req);
            err++;
          }  
        break;
#endif


文件最后添加函数实现

60916780785816dfa.png

#if (USBD_SUPPORT_WINUSB==1)
static void USBD_WinUSBGetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
  uint16_t len;
  uint8_t *pbuf;


  switch (req->wIndex)
  {
  case 0x04: // compat ID
    pbuf = pdev->pDesc->GetWinUSBOSFeatureDescriptor(&len);
    break;
  case 0x05:
    pbuf = pdev->pDesc->GetWinUSBOSPropertyDescriptor(&len);
    break;

  default:
     USBD_CtlError(pdev , req);
    return;
  }
  if((len != 0)&& (req->wLength != 0))
  {

    len = MIN(len , req->wLength);

    USBD_CtlSendData (pdev,
                      pbuf,
                      len);
  }


}   

#endif


测试验证
至此上面的工程就修改完成了编译下载到单片机上便能够正常识别为USB设备

4257767807849586d8.png

接下来便可以通过WINUSB的上位机进行通信测试了。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/xiaoyuanwuhui/article/details/144960476

您需要登录后才可以回帖 登录 | 注册

本版积分规则

2384

主题

17635

帖子

21

粉丝
快速回复 在线客服 返回列表 返回顶部