通过cubeMX生成USB CDC基础工程
过程略
修改工程代码
修改usbd_conf.h文件
添加如下宏定义
#define USBD_SUPPORT_WINUSB 1
修改usbd_def.h文件
添加如下宏定义
#if (USBD_SUPPORT_WINUSB == 1)
#define USB_REQ_MS_VENDOR_CODE 0xA0U
#endif
USB类定义部分添加如下内容
#if (USBD_SUPPORT_WINUSB == 1)
uint8_t *(*GetWinUSBOSDescriptor)(uint16_t *length);
#endif
USB描述符类型定义结构体部分添加如下如下内容
#if (USBD_SUPPORT_WINUSB == 1) //新增
uint8_t *(*GetWinUSBOSFeatureDescriptor)(uint16_t *length);
uint8_t *(*GetWinUSBOSPropertyDescriptor)(uint16_t *length);
#endif
修改usbd_desc.c文件
修改开始部分的宏定义,根据自己的需求修改即可,注意:VID和PID不要用和默认工程一样的
添加函数声明
#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
修改描述符结构体定义部分
#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文件
添加函数声明
USBD_CDC类定义部分添加如下内容
#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文件
添加如下函数声明
#if (USBD_SUPPORT_WINUSB==1)
static void USBD_WinUSBGetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
#endif
USBD_StdDevReq函数部分添加如下内容
#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
文件最后添加函数实现
#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设备
接下来便可以通过WINUSB的上位机进行通信测试了。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xiaoyuanwuhui/article/details/144960476
|
|