设备描述符:
/* USB Standard Device Descriptor */
const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
{
0x12, /* bLength 该描述符总长度*/
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType 设备描述符类型,这里是设备描述符为0x01*/
0x00,
0x02, /* bcdUSB = 2.00 USB协议版本*/
0x02, /* bDeviceClass: CDC这个在下面有详解 */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol协议代码由USB-IF分配 */
0x40, /* bMaxPacketSize0 端点0的最大包长*/
0x83,
0x04, /* idVendor = 0x0483 厂商ID号由USB-IF分配*/
0x40,
0x57, /* idProduct = 0x7540产品ID号,由厂商自己定义 */
0x00,
0x02, /* bcdDevice = 2.00 */
1, /* Index of string descriptor describing manufacturer */
2, /* Index of string descriptor describing product */
3, /* Index of string descriptor describing the device's serial number */
0x01 /* bNumConfigurations */
};
bDeviceClass这里为什么是0x02(通信设备类的类代码),如果这里不指定为通信类设备,会由于在配置集合中有两个接口,而被系统认为是一个USB复合设备,从而导致设备工作不正常。而且当指定了设备类型为通信设备类后,子类和所使用的协议都必须指定为0,既bDeviceSubClass和bDeviceProtocol为0;
usb defined class codes部分截图如下:
描述符集合:
代码如下:
const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
{
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size 配置描述符长度*/
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration描述符类型 */
VIRTUAL_COM_PORT_SIZ_CONFIG_DESC, /* wTotalLength:no of returned bytes整个配置描述符的总长度 的低字节*/
0x00, /* wTotalLength:no of returned bytes整个配置描述符的总长度 的高字节*/
0x02, /* bNumInterfaces: 2 interface 接口数量*/
0x01, /* bConfigurationValue:该配置值,USB支持多个配置,设置配置请求时会发送一个配置值,或与这个配置值相同,表示该配置被激活 */
0x00, /* iConfiguration: 该配置的字符串的索引值,为0表示没有字符串 */
0xC0, /* bmAttributes: 7bit保留位必须为1,6bit为1表示设备自供电为0设备是总线供电的,5bit表示是否支持远程唤醒,1支持远程唤醒。4bit~0bit保留设置为0 */
0x32, /* MaxPower 0 mA 表示设备需要从总线获取的最大电流量,单位为2ma,0x32 * 2ma = 100ma*/
/*Interface Descriptor*/
0x09, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: 接口描述符类型0x04 */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: 该接口的编号,当一个配置有多个接口时,每个编号都不相同,从0开始依次递增 */
0x00, /* bAlternateSetting: 该接口的备用编号,编号规则与 bInterfaceNumber一样,很少用,设置为0*/
0x01, /* bNumEndpoints: 该接口所使用的端点数(不包括0端点)如果该字段为0,则表示没有非0端点,只使用默认的控制端点 */
/* bInterfaceClass,bInterfaceSubClass,bInterfaceProtocol分别是接口所使用的类,子类以及协议,他们的代码由USB协会定义,跟设备描述符中的意义类似。通常在接口中定义设备的功能,而在设备描述符中将类,子类以及协议字段的值设置为0 */
0x02, /* bInterfaceClass: 该接口所使用的类,CDC接口类代码为0x02*/
0x02, /* bInterfaceSubClass: 该接口所使用的子类,要实现USB转串口,就必须使用Abstract Control Model(抽象控制模型)子类,他的编号为0x02 */
0x01, /* bInterfaceProtocol: Common AT commands (通用AT命令协议)*/
0x00, /* iInterface: 该接口的字符串索引值,这里没有为0*/
/*在CDC类中,不再有HID描述符和报告描述符,而是功能描述符的类特殊接口描述符,他们主要用来描述接口的功能,功能描述符放在CDC接口(主接口)之后,功能描述符完毕之后就是主接口的端点描述符,再接下来是其它接口以及他们的端点描述符*/
/*功能描述符*/
/*Header Functional Descriptor*/
0x05, /* bLength: Endpoint Descriptor size 该描述符长度为5字节*/
0x24, /* bDescriptorType: CS_INTERFACE 描述符类型为类特殊接口(CS_INTERFACE),编号为0x24*/
/*抽象控制模型中需要用到的功能描述符有:
Header Functional Descriptor : 0x00
Call Management Functional Descriptor:0x01
ACM Functional Descriptor:0x02
Union Functional Descriptor:0x06
接下来会对这4个功能分别进行描述
*/
/*Header Functional Descriptor*/
0x00, /* bDescriptorSubtype: Header Func Desc(0x00 0x01 0x02 0x06) */
0x10, /* bcdCDC: spec release number CDC版本号,低字节在前*/
0x01,
/*Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1:设备自己不处理调用管理 */
0x01, /* bDataInterface: 1 用来做调用管理的数据类接口编号*/
/*ACM Functional Descriptor*/
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint 端点描述符编号为0x05*/
0x82, /* bEndpointAddress: (IN2) 7bit表示数据方向,1表示输入,端点为2*/
0x03, /* bmAttributes: Interrupt 中断端点:0x03,批量端点:0x02*/
VIRTUAL_COM_PORT_INT_SIZE, /* wMaxPacketSize: 该端点的最大包长,端点2的最大包长为64字节*/
0x00,
0xFF, /* bInterval: 端点的查询时间*/
/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: 接口描述符的编号为0x04*/
0x01, /* bInterfaceNumber: Number of Interface 该接口的编号,这里是第二个接口,所以编号为1*/
0x00, /* bAlternateSetting: Alternate setting 该接口的备用编号为0*/
0x02, /* bNumEndpoints: Two endpoints used 非0端点的数目,这里使用端点1和端点3两个端点*/
0x0A, /* bInterfaceClass: CDC 该接口所使用的类,数据类接口的代码为0x0A*/
0x00, /* bInterfaceSubClass: 该接口所使用的子类为0*/
0x00, /* bInterfaceProtocol: 该接口所使用的协议为0*/
0x00, /* iInterface: 该接口的字符串索引值,这里没有为0*/
/*Endpoint 3 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x03, /* bEndpointAddress: (OUT3) */
0x02, /* bmAttributes: Bulk 批量端点:0x02*/
VIRTUAL_COM_PORT_DATA_SIZE, /* wMaxPacketSize: */
0x00,
0x00, /* bInterval: ignore for Bulk transfer 查询端点的时间,这里对批量端点无效*/
/*Endpoint 1 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x81, /* bEndpointAddress: (IN1) */
0x02, /* bmAttributes: Bulk 批量端点,0x02*/
VIRTUAL_COM_PORT_DATA_SIZE, /* wMaxPacketSize: */
0x00,
0x00 /* bInterval */
};
/* USB String Descriptors */
const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID] =
{
VIRTUAL_COM_PORT_SIZ_STRING_LANGID,
USB_STRING_DESCRIPTOR_TYPE,
0x09,
0x04 /* LangID = 0x0409: U.S. English */
};
const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR] =
{
VIRTUAL_COM_PORT_SIZ_STRING_VENDOR, /* Size of Vendor string */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/
/* Manufacturer: "STMicroelectronics" */
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
'c', 0, 's', 0
};
const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT] =
{
VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
/* Product name: "STM32 Virtual COM Port" */
'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'V', 0, 'i', 0,
'r', 0, 't', 0, 'u', 0, 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0,
'M', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0, ' ', 0, ' ', 0
};
uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] =
{
VIRTUAL_COM_PORT_SIZ_STRING_SERIAL, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0
};