STM32 -- Multiple USB CDC (USB IAD)

Multiple USB CDC (USB IAD)

One CDC function requires 2 IN / 1 OUT endpoints (interrupt IN/ bulk IN/ bulk OUT), other than the default EP.
Available endpoints of each STM32F family are,

STM32F102/103 - FS Device core: 7 IN / 7 OUT
STM32F105/107 - OTG_FS: 3 IN / 3 OUT
STM32F2xx/4xx - OTG_FS: 3 IN / 3 OUT
STM32F2xx/4xx - OTG_HS: 5 IN / 5 OUT


STM32F102/103 - 3x CDC composite [ 6 IN - 3 OUT ]
STM32F105/107 - just one CDC [ 2 IN - 1 OUT ]
STM32F2xx/4xx - 2x CDC composite on OTG_HS [ 4 IN - 2 OUT ]


Starting from ST's example, it isn't so hard, to make them a CDC composite device, 

if you would know where and how to touch on the source code :-)

OK, then let's start here on this thread.

The agenda of modification is,
1) Descriptors and INF file
2) Bulk IN/OUT endpoints
3) Class requests

The base ST example is STM32F10x and STM32L1xx USB full-speed device library v3.4.0
http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32_usb-fs-device_lib.zip
\STM32_USB-FS-Device_Lib_V3.4.0\Project\Virtual_COM_Port

We'll make 3x CDC composite device.

1) Descriptors

First the device descriptor is modified at class/subclass/protocol and VID/PID (idVendor/idProduct) fields.
We assign temporary VID/PID just for this development. Get official VID/PID afterward.
Virtual_Com_Port_DeviceDescriptor() is replaced, as follows.

usb_desc.c

/* USB Standard Device Descriptor */

const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
  {
    0x12,   /* bLength */
    USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */
    0x00,
    0x02,   /* bcdUSB = 2.00 */
    0xEF,   /* bDeviceClass    (Misc)   */
    0x02,   /* bDeviceSubClass (common) */
    0x01,   /* bDeviceProtocol (IAD)    */
    0x40,   /* bMaxPacketSize0 */
    0x83,
    0x02,   /* idVendor = 0xFF02 */
    0xFF,
    0x01,   /* idProduct = 0x0001 */
    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 */
  };

 

Next, the Configuration descriptor set is heavy, because we have to repeat three sets of IAD / CDC interfaces. We make them macros

#define WBVAL(x) (x & 0xFF),((x >> 8) & 0xFF)

#define USB_CONFIGUARTION_DESC_SIZE             9
#define USB_INTERFACE_DESC_SIZE                 9
#define USB_ENDPOINT_DESC_SIZE                  7
#define USB_ENDPOINT_TYPE_BULK                  0x02
#define USB_ENDPOINT_TYPE_INTERRUPT             0x03

#define USB_CONFIG_BUS_POWERED                 0x80
#define USB_CONFIG_SELF_POWERED                0xC0
#define USB_CONFIG_POWER_MA(mA)                ((mA)/2)

#define CDC_COMMUNICATION_INTERFACE_CLASS       0x02
#define CDC_DATA_INTERFACE_CLASS                0x0A
#define CDC_ABSTRACT_CONTROL_MODEL              0x02
#define CDC_CS_INTERFACE                        0x24
#define CDC_HEADER                              0x00
#define CDC_CALL_MANAGEMENT                     0x01
#define CDC_ABSTRACT_CONTROL_MANAGEMENT         0x02
#define CDC_UNION                               0x06

#define CDC_IF_DESC_SET_SIZE                    \
( USB_INTERFACE_DESC_SIZE + 0x05 + 0x05 + 0x04 + 0x05 + USB_ENDPOINT_DESC_SIZE + USB_INTERFACE_DESC_SIZE + 2 * USB_ENDPOINT_DESC_SIZE ) #define CDC_IF_DESC_SET( comIfNum, datIfNum, comInEp, datOutEp, datInEp ) \ /* CDC Communication Interface Descriptor */ \ USB_INTERFACE_DESC_SIZE, /* bLength */ \ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ comIfNum, /* bInterfaceNumber */ \ 0x00, /* bAlternateSetting */ \ 0x01, /* bNumEndpoints */ \ CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass */ \ CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ \ 0x01, /* bInterfaceProtocol */ \ 0x00, /* iInterface */ \ /* Header Functional Descriptor */ \ 0x05, /* bLength */ \ CDC_CS_INTERFACE, /* bDescriptorType */ \ CDC_HEADER, /* bDescriptorSubtype */ \ WBVAL(CDC_V1_10), /* 1.10 */ /* bcdCDC */ \ /* Call Management Functional Descriptor */ \ 0x05, /* bFunctionLength */ \ CDC_CS_INTERFACE, /* bDescriptorType */ \ CDC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \ 0x03, /* bmCapabilities */ \ datIfNum, /* bDataInterface */ \ /* Abstract Control Management Functional Descriptor */ \ 0x04, /* bFunctionLength */ \ CDC_CS_INTERFACE, /* bDescriptorType */ \ CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \ 0x02, /* bmCapabilities */ \ /* Union Functional Descriptor */ \ 0x05, /* bFunctionLength */ \ CDC_CS_INTERFACE, /* bDescriptorType */ \ CDC_UNION, /* bDescriptorSubtype */ \ comIfNum, /* bMasterInterface */ \ datIfNum, /* bSlaveInterface0 */ \ /* Endpoint, Interrupt IN */ /* event notification */ \ USB_ENDPOINT_DESC_SIZE, /* bLength */ \ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \ comInEp, /* bEndpointAddress */ \ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ \ WBVAL(0x000A), /* wMaxPacketSize */ \ 0x01, /* bInterval */ \ \ /* CDC Data Interface Descriptor */ \ USB_INTERFACE_DESC_SIZE, /* bLength */ \ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ datIfNum, /* bInterfaceNumber */ \ 0x00, /* bAlternateSetting */ \ 0x02, /* bNumEndpoints */ \ CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \ 0x00, /* bInterfaceSubClass */ \ 0x00, /* bInterfaceProtocol */ \ 0x00, /* iInterface */ \ /* Endpoint, Bulk OUT */ \ USB_ENDPOINT_DESC_SIZE, /* bLength */ \ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \ datOutEp, /* bEndpointAddress */ \ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ \ WBVAL(VIRTUAL_COM_PORT_DATA_SIZE), /* wMaxPacketSize */ \ 0x00, /* bInterval */ \ /* Endpoint, Bulk IN */ \ USB_ENDPOINT_DESC_SIZE, /* bLength */ \ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \ datInEp, /* bEndpointAddress */ \ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ \ WBVAL(VIRTUAL_COM_PORT_DATA_SIZE), /* wMaxPacketSize */ \ 0x00 /* bInterval */ #define IAD_CDC_IF_DESC_SET_SIZE ( 8 + CDC_IF_DESC_SET_SIZE ) #define IAD_CDC_IF_DESC_SET( comIfNum, datIfNum, comInEp, datOutEp, datInEp ) \ /* Interface Association Descriptor */ \ 0x08, /* bLength */ \ 0x0B, /* bDescriptorType */ \ comIfNum, /* bFirstInterface */ \ 0x02, /* bInterfaceCount */ \ CDC_COMMUNICATION_INTERFACE_CLASS, /* bFunctionClass */ \ CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */ \ 0x01, /* bFunctionProcotol */ \ 0x00, /* iInterface */ \ /* CDC Interface descriptor set */ \ CDC_IF_DESC_SET( comIfNum, datIfNum, comInEp, datOutEp, datInEp )

Now that the configuration descriptor set is simplified. Virtual_Com_Port_ConfigDescriptor[] is replaced as follows, 

usb_desc.c

// Interface numbers
enum {
    USB_CDC_CIF_NUM0,
    USB_CDC_DIF_NUM0,
    USB_CDC_CIF_NUM1,
    USB_CDC_DIF_NUM1,
    USB_CDC_CIF_NUM2,
    USB_CDC_DIF_NUM2,
    
    USB_NUM_INTERFACES        // number of interfaces
};

const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
  {
/* Configuration 1 */
  USB_CONFIGUARTION_DESC_SIZE,       /* bLength */
  USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
  WBVAL(                             /* wTotalLength */
      USB_CONFIGUARTION_DESC_SIZE
    + 3 * IAD_CDC_IF_DESC_SET_SIZE
  ),
  USB_NUM_INTERFACES,                /* bNumInterfaces */
  0x01,                              /* bConfigurationValue: 0x01 is used to select this configuration */
  0x00,                              /* iConfiguration: no string to describe this configuration */
  USB_CONFIG_BUS_POWERED /*|*/       /* bmAttributes USB_CONFIG_REMOTE_WAKEUP*/,
  USB_CONFIG_POWER_MA(100),          /* bMaxPower, device power consumption is 100 mA */

  IAD_CDC_IF_DESC_SET( USB_CDC_CIF_NUM0, USB_CDC_DIF_NUM0, USB_ENDPOINT_IN(1), USB_ENDPOINT_OUT(2), USB_ENDPOINT_IN(2) ),
  IAD_CDC_IF_DESC_SET( USB_CDC_CIF_NUM1, USB_CDC_DIF_NUM1, USB_ENDPOINT_IN(3), USB_ENDPOINT_OUT(4), USB_ENDPOINT_IN(4) ),
  IAD_CDC_IF_DESC_SET( USB_CDC_CIF_NUM2, USB_CDC_DIF_NUM2, USB_ENDPOINT_IN(5), USB_ENDPOINT_OUT(6), USB_ENDPOINT_IN(6) ),
};

 

Auu, I remember that the packet buffer of STM32F102/103 is limited to 512 bytes.

To pack all of endpoint packet buffers into this size,

we have to shrink EP0 bMaxPacketSize0 on the Device Descriptor from 0x40 to 0x08 (minimum)

/* USB Standard Device Descriptor */

const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
  {
    0x12,   /* bLength */
    USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */
    0x00,
    0x02,   /* bcdUSB = 2.00 */
    0xEF,   /* bDeviceClass    (Misc)   */
    0x02,   /* bDeviceSubClass (common) */
    0x01,   /* bDeviceProtocol (IAD)    */
    0x08,   /* bMaxPacketSize0 */        // <-----------
    0x83,
    0x02,   /* idVendor = 0xFF02 */
    0xFF,
    0x01,   /* idProduct = 0x0001 */
    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 */
  };

 

Next, enable all endpoints in Virtual_Com_Port_Reset() Here, packet buffer is allocated for each endpoint.

\inc\usb_conf.h

/*-------------------------------------------------------------*/
/* --------------   Buffer Description Table  -----------------*/
/*-------------------------------------------------------------*/
/* buffer table base address */
/* buffer table base address */
#define BTABLE_ADDRESS      (0x00)

/* EP0  */
/* rx/tx buffer base address */
#define ENDP0_RXADDR        (0x40)
#define ENDP0_TXADDR        (0x48)

/* EP1  */
/* tx buffer base address */
#define ENDP1_TXADDR        (0x50)
#define ENDP2_TXADDR        (0x60)
#define ENDP2_RXADDR        (0xA0)
#define ENDP3_TXADDR        (0xE0)
#define ENDP4_TXADDR        (0xF0)
#define ENDP4_RXADDR        (0x130)
#define ENDP5_TXADDR        (0x170)
#define ENDP6_TXADDR        (0x180)
#define ENDP6_RXADDR        (0x1C0)

usb_prop.c

/*******************************************************************************
* Function Name  : Virtual_Com_Port_Reset
* Description    : Virtual_Com_Port Mouse reset routine
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_Reset(void)
{
  /* Set Virtual_Com_Port DEVICE as not configured */
  pInformation->Current_Configuration = 0;

  /* Current Feature initialization */
  pInformation->Current_Feature = Virtual_Com_Port_ConfigDescriptor[7];

  /* Set Virtual_Com_Port DEVICE with the default Interface*/
  pInformation->Current_Interface = 0;

  SetBTABLE(BTABLE_ADDRESS);

  /* Initialize Endpoint 0 */
  SetEPType(ENDP0, EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_STALL);
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  Clear_Status_Out(ENDP0);
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPRxValid(ENDP0);

  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_INTERRUPT);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
  SetEPRxStatus(ENDP1, EP_RX_DIS);

  /* Initialize Endpoint 2 */
  SetEPType(ENDP2, EP_BULK);
  SetEPTxAddr(ENDP2, ENDP2_TXADDR);
  SetEPTxStatus(ENDP2, EP_TX_NAK);
  SetEPRxAddr(ENDP2, ENDP2_RXADDR);
  SetEPRxCount(ENDP2, VIRTUAL_COM_PORT_DATA_SIZE);
  SetEPRxStatus(ENDP2, EP_RX_VALID);

  /* Initialize Endpoint 3 */
  SetEPType(ENDP3, EP_INTERRUPT);
  SetEPTxAddr(ENDP3, ENDP3_TXADDR);
  SetEPTxStatus(ENDP3, EP_TX_NAK);
  SetEPRxStatus(ENDP3, EP_RX_DIS);

  /* Initialize Endpoint 4 */
  SetEPType(ENDP4, EP_BULK);
  SetEPTxAddr(ENDP4, ENDP4_TXADDR);
  SetEPTxStatus(ENDP4, EP_TX_NAK);
  SetEPRxAddr(ENDP4, ENDP4_RXADDR);
  SetEPRxCount(ENDP4, VIRTUAL_COM_PORT_DATA_SIZE);
  SetEPRxStatus(ENDP4, EP_RX_VALID);

  /* Initialize Endpoint 5 */
  SetEPType(ENDP5, EP_INTERRUPT);
  SetEPTxAddr(ENDP5, ENDP5_TXADDR);
  SetEPTxStatus(ENDP5, EP_TX_NAK);
  SetEPRxStatus(ENDP5, EP_RX_DIS);

  /* Initialize Endpoint 6 */
  SetEPType(ENDP6, EP_BULK);
  SetEPTxAddr(ENDP6, ENDP6_TXADDR);
  SetEPTxStatus(ENDP6, EP_TX_NAK);
  SetEPRxAddr(ENDP6, ENDP6_RXADDR);
  SetEPRxCount(ENDP6, VIRTUAL_COM_PORT_DATA_SIZE);
  SetEPRxStatus(ENDP6, EP_RX_VALID);

  /* Set this device to response on default address */
  SetDeviceAddress(0);

  bDeviceState = ATTACHED;
}

And the last of this section, INF file for windows. Now that our device should appear on Windows. :-)

STM32-CDC-Composite.inf

;
; STM32-CDC-Composite.inf  Communication Device Class driver installation file
;

[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%MICHELE%
;;; LayoutFile=layout.inf ;; not supported in Vista and later
DriverVer =04/14/2008, 5.1.2600.5512
; CatalogFile=STM32-CDC-Composite.cat

[Manufacturer]
%MICHELE%=DeviceList,ntamd64

;------------------------------------------------------------------------------
;  Device list
;------------------------------------------------------------------------------

[DeviceList]
%DESCRIPTION1% = STM32CDCCMP, USB¥VID_FF02&PID_0001&MI_00
%DESCRIPTION2% = STM32CDCCMP, USB¥VID_FF02&PID_0001&MI_02
%DESCRIPTION3% = STM32CDCCMP, USB¥VID_FF02&PID_0001&MI_04

[DeviceList.ntamd64]
%DESCRIPTION1% = STM32CDCCMP, USB¥VID_FF02&PID_0001&MI_00
%DESCRIPTION2% = STM32CDCCMP, USB¥VID_FF02&PID_0001&MI_02
%DESCRIPTION3% = STM32CDCCMP, USB¥VID_FF02&PID_0001&MI_04

;------------------------------------------------------------------------------
;  Installation
;------------------------------------------------------------------------------

[SourceDisksNames]
;;; this blank section satisfies chkinf
[SourceDisksFiles]
;;; this blank section satisfies chkinf

[DestinationDirs]
FakeModemCopyFileSection=12
DefaultDestDir = 12

[STM32CDCCMP]
include=mdmcpq.inf
CopyFiles=FakeModemCopyFileSection
AddReg= STM32CDCCMP.AddReg

[STM32CDCCMP.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"

[STM32CDCCMP.Services]
AddService=usbser, 0x00000002, DriverService

[DriverService]
DisplayName=%DRIVER.SVC%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%¥usbser.sys

;------------------------------------------------------------------------------
;  String Definitions
;------------------------------------------------------------------------------

[Strings]
MICHELE     = "Michele"
DRIVER.SVC  = "STM32 CDC Composite Driver"
DESCRIPTION1= "STM32 CDC Composite Port 1"
DESCRIPTION2= "STM32 CDC Composite Port 2"
DESCRIPTION3= "STM32 CDC Composite Port 3"

I have a test today.Set the Virtual_Com_Port_ConfigDescriptor EP like:


  IAD_CDC_IF_DESC_SET( USB_CDC_CIF_NUM0, USB_CDC_DIF_NUM0, USB_ENDPOINT_IN(2), USB_ENDPOINT_OUT(1), USB_ENDPOINT_IN(1) ),
  IAD_CDC_IF_DESC_SET( USB_CDC_CIF_NUM1, USB_CDC_DIF_NUM1, USB_ENDPOINT_IN(2), USB_ENDPOINT_OUT(3), USB_ENDPOINT_IN(3) ),

  IAD_CDC_IF_DESC_SET( USB_CDC_CIF_NUM2, USB_CDC_DIF_NUM2, USB_ENDPOINT_IN(2), USB_ENDPOINT_OUT(4), USB_ENDPOINT_IN(4) ),
  IAD_CDC_IF_DESC_SET( USB_CDC_CIF_NUM3, USB_CDC_DIF_NUM3, USB_ENDPOINT_IN(2), USB_ENDPOINT_OUT(5), USB_ENDPOINT_IN(5) ),
  IAD_CDC_IF_DESC_SET( USB_CDC_CIF_NUM4, USB_CDC_DIF_NUM4, USB_ENDPOINT_IN(2), USB_ENDPOINT_OUT(6), USB_ENDPOINT_IN(6) ),

Then the PC can detector the virtual coms like: 

Transfer data as the style of demo.

I tested the first two coms,they worked ok. 

I will test the others,and change the transfer style to improve the transfer speed.

As all coms will work at the same time.

The way upon is not conform the CDC rules,but can be used by some special application.

Maybe the test way is not entire. What is your comment, or  some good methods?

Yangfeng

 

STM32F103 Dual CDC

https://github.com/x893/STM32F103-DualCDC



STM32F105实现的USB转双串口

(出处: 嵌入式以太网社区)

USB转双串口,核心技术就在于组合设备(USB Composite)的实现,组合设备的实现,其核心技术在于描述符的实现,下面我们先给出描述符:

__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END =
  {
    0x12,                       /*bLength */
    USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
    0x00,                       /*bcdUSB */
    0x02,
#ifdef DUAL_COM
    0xEF,                       /*bDeviceClass*/
    0x02,                       /*bDeviceSubClass*/
    0x01,                       /*bDeviceProtocol*/
#else
    0x00,                       /*bDeviceClass*/
    0x00,                       /*bDeviceSubClass*/
    0x00,                       /*bDeviceProtocol*/       
#endif
    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 */

 

注意:双串口需要全局定义DUAL_COM宏 配置描述符是重中之重

__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
{
  /*Configuration Descriptor*/
  0x09,   /* bLength: Configuration Descriptor size */
  USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
  USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
  0x00,
#ifdef DUAL_COM
  0x04,   /* bNumInterfaces: 4 interface */
#else
  0x02,   /* bNumInterfaces: 2 interface */
#endif
0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0x60, /* bmAttributes: self powered */ 0xFA, /* MaxPower 0 mA */ /*---------------------------------------------------------------------------*/ #ifdef DUAL_COM // IAD 0x08, // bLength: Interface Descriptor size 0x0B, // bDescriptorType: IAD 0x00, // bFirstInterface 0x02, // bInterfaceCount 0x02, // bFunctionClass: CDC 0x02, // bFunctionSubClass 0x01, // bFunctionProtocol 0x02, // iFunction #endif
/*Interface Descriptor */ 0x09, /* bLength: Interface Descriptor size */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ /* Interface descriptor type */ 0x00, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x01, /* bNumEndpoints: One endpoints used */ 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x01, /* bInterfaceProtocol: Common AT commands */ 0x00, /* iInterface: */ /*Header Functional Descriptor*/ 0x05, /* bLength: Endpoint Descriptor size */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x00, /* bDescriptorSubtype: Header Func Desc */ 0x10, /* bcdCDC: spec release number */ 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 */ CDC_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */ HIBYTE(CDC_CMD_PACKET_SZE), 0xFF, /* bInterval: */ /*---------------------------------------------------------------------------*/ /*Data class interface descriptor*/ 0x09, /* bLength: Endpoint Descriptor size */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ 0x01, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ 0x00, /* bInterfaceSubClass: */ 0x00, /* bInterfaceProtocol: */ 0x00, /* iInterface: */ /*Endpoint OUT Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ CDC_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_MAX_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */ /*Endpoint IN Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ CDC_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_MAX_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */ #ifdef DUAL_COM // IAD 0x08, // bLength: Interface Descriptor size 0x0B, // bDescriptorType: IAD 0x02, // bFirstInterface 0x02, // bInterfaceCount 0x02, // bFunctionClass: CDC 0x02, // bFunctionSubClass 0x01, // bFunctionProtocol 0x02, // iFunction /*Interface Descriptor */ 0x09, /* bLength: Interface Descriptor size */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ /* Interface descriptor type */ 0x02, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x01, /* bNumEndpoints: One endpoints used */ 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x01, /* bInterfaceProtocol: Common AT commands */ 0x00, /* iInterface: */ /*Header Functional Descriptor*/ 0x05, /* bLength: Endpoint Descriptor size */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x00, /* bDescriptorSubtype: Header Func Desc */ 0x10, /* bcdCDC: spec release number */ 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 */ CDC_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */ HIBYTE(CDC_CMD_PACKET_SZE), 0xFF, /* bInterval: */ /*---------------------------------------------------------------------------*/ /*Data class interface descriptor*/ 0x09, /* bLength: Endpoint Descriptor size */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ 0x03, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ 0x00, /* bInterfaceSubClass: */ 0x00, /* bInterfaceProtocol: */ 0x00, /* iInterface: */ /*Endpoint OUT Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ CDC_OUT_EP_EX, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_MAX_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */ /*Endpoint IN Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ CDC_IN_EP_EX, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_MAX_PACKET_SIZE), 0x00 /* bInterval: ignore for Bulk transfer */ #endif } ;

 

 

  1 /******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
  2 * File Name          : usb_desc.c
  3 * Author             : MCD Application Team
  4 * Version            : V3.1.1
  5 * Date               : 04/07/2010
  6 * Description        : Descriptors for Virtual Com Port Demo
  7 ********************************************************************************
  8 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  9 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
 10 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
 11 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
 12 * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
 13 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
 14 *******************************************************************************/
 15 
 16 /* Includes ------------------------------------------------------------------*/
 17 #include "usb_lib.h"
 18 #include "usb_desc.h"
 19 
 20 /* USB Standard Device Descriptor */
 21 const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
 22   {
 23     0x12,   /* bLength */
 24     USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */
 25     0x00,
 26     0x02,   /* bcdUSB = 2.00 */
 27             /* Multi-Interface Function Class Code : 0xEF 0x02 0x01 */   
 28     0xEF,   /* bDeviceClass    : Miscellaneous Device Class : CDC */
 29     0x02,   /* bDeviceSubClass : Common Class */
 30     0x01,   /* bDeviceProtocol : IAD : Interface Association Descriptor */
 31 
 32     0x40,   /* bMaxPacketSize0 */
 33     0xEB,
 34     0x03,   /* idVendor = 0x03EB */
 35     0x33,
 36     0x61,   /* idProduct = 0x6133 */
 37     
 38     0x00,
 39     0x02,   /* bcdDevice = 2.00 */
 40     1,      /* Index of string descriptor describing manufacturer */
 41     2,      /* Index of string descriptor describing product */
 42     3,      /* Index of string descriptor describing the device's serial number */
 43     0x01    /* bNumConfigurations */
 44   };
 45 
 46 const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
 47   {
 48     /*Configuation Descriptor*/
 49     0x09,   /* bLength: Configuation Descriptor size */
 50     USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
 51     VIRTUAL_COM_PORT_SIZ_CONFIG_DESC,       /* wTotalLength:no of returned bytes */
 52     0x00,
 53     0x04,   /* bNumInterfaces: 4 interface */
 54     0x01,   /* bConfigurationValue: Configuration value */
 55     0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
 56     0xC0,   /* bmAttributes: self powered */
 57     0x32,   /* MaxPower 100 mA */
 58 
 59     // IAD
 60     0x08,    // bLength: Interface Descriptor size
 61     0x0B,        // bDescriptorType: IAD
 62     0x00,    // bFirstInterface
 63     0x02,    // bInterfaceCount
 64     0x02,    // bFunctionClass: CDC
 65     0x02,    // bFunctionSubClass
 66     0x01,    // bFunctionProtocol 
 67     0x02,    // iFunction
 68     
 69     /*Interface Descriptor*/
 70     0x09,   /* bLength: Interface Descriptor size */
 71     USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
 72     /* Interface descriptor type */
 73     0x00,   /* bInterfaceNumber: Number of Interface */
 74     0x00,   /* bAlternateSetting: Alternate setting */
 75     0x01,   /* bNumEndpoints: One endpoints used */
 76     0x02,   /* bInterfaceClass: Communication Interface Class */
 77     0x02,   /* bInterfaceSubClass: Abstract Control Model */
 78     0x01,   /* bInterfaceProtocol: Common AT commands */
 79     0x00,   /* iInterface: */
80 /*Header Functional Descriptor*/ 81 0x05, /* bLength: Endpoint Descriptor size */ 82 0x24, /* bDescriptorType: CS_INTERFACE */ 83 0x00, /* bDescriptorSubtype: Header Func Desc */ 84 0x10, /* bcdCDC: spec release number */ 85 0x01,
86 /*Call Managment Functional Descriptor*/ 87 0x05, /* bFunctionLength */ 88 0x24, /* bDescriptorType: CS_INTERFACE */ 89 0x01, /* bDescriptorSubtype: Call Management Func Desc */ 90 0x00, /* bmCapabilities: D0+D1 */ 91 0x01, /* bDataInterface: 1 */

92 /*ACM Functional Descriptor*/ 93 0x04, /* bFunctionLength */ 94 0x24, /* bDescriptorType: CS_INTERFACE */ 95 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ 96 0x02, /* bmCapabilities */
 97     /*Union Functional Descriptor*/
 98     0x05,   /* bFunctionLength */
 99     0x24,   /* bDescriptorType: CS_INTERFACE */
100     0x06,   /* bDescriptorSubtype: Union func desc */
101     0x00,   /* bMasterInterface: Communication class interface */
102     0x01,   /* bSlaveInterface0: Data Class Interface */

103 /*Endpoint 2 Descriptor*/ 104 0x07, /* bLength: Endpoint Descriptor size */ 105 USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ 106 0x82, /* bEndpointAddress: (IN2) */ 107 0x03, /* bmAttributes: Interrupt */ 108 VIRTUAL_COM_PORT_INT_SIZE, /* wMaxPacketSize: */ 109 0x00, 110 0xFF, /* bInterval: */

111 /*Data class interface descriptor*/ 112 0x09, /* bLength: Endpoint Descriptor size */ 113 USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ 114 0x01, /* bInterfaceNumber: Number of Interface */ 115 0x00, /* bAlternateSetting: Alternate setting */ 116 0x02, /* bNumEndpoints: Two endpoints used */ 117 0x0A, /* bInterfaceClass: CDC */ 118 0x00, /* bInterfaceSubClass: */ 119 0x00, /* bInterfaceProtocol: */ 120 0x00, /* iInterface: */

121 /*Endpoint 3 Descriptor*/ 122 0x07, /* bLength: Endpoint Descriptor size */ 123 USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ 124 0x03, /* bEndpointAddress: (OUT3) */ 125 0x02, /* bmAttributes: Bulk */ 126 VIRTUAL_COM_PORT_DATA_SIZE, /* wMaxPacketSize: */ 127 0x00, 128 0x00, /* bInterval: ignore for Bulk transfer */

129 /*Endpoint 1 Descriptor*/ 130 0x07, /* bLength: Endpoint Descriptor size */ 131 USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ 132 0x81, /* bEndpointAddress: (IN1) */ 133 0x02, /* bmAttributes: Bulk */ 134 VIRTUAL_COM_PORT_DATA_SIZE, /* wMaxPacketSize: */ 135 0x00, 136 0x00, /* bInterval */ 137 138 // IAD 139 0x08, // bLength: Interface Descriptor size 140 0x0B, // bDescriptorType: IAD 141 0x02, // bFirstInterface 142 0x02, // bInterfaceCount 143 0x02, // bFunctionClass: CDC 144 0x02, // bFunctionSubClass 145 0x01, // bFunctionProtocol
1460x02, // iFunction

147 /*Interface Descriptor*/ 148 0x09, /* bLength: Interface Descriptor size */ 149 USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ 150 /* Interface descriptor type */ 151 0x02, /* bInterfaceNumber: Number of Interface */ 152 0x00, /* bAlternateSetting: Alternate setting */ 153 0x01, /* bNumEndpoints: One endpoints used */ 154 0x02, /* bInterfaceClass: Communication Interface Class */ 155 0x02, /* bInterfaceSubClass: Abstract Control Model */ 156 0x01, /* bInterfaceProtocol: Common AT commands */ 157 0x00, /* iInterface: */

158 /*Header Functional Descriptor*/ 159 0x05, /* bLength: Endpoint Descriptor size */ 160 0x24, /* bDescriptorType: CS_INTERFACE */ 161 0x00, /* bDescriptorSubtype: Header Func Desc */ 162 0x10, /* bcdCDC: spec release number */ 163 0x01,
164 /*Call Managment Functional Descriptor*/ 165 0x05, /* bFunctionLength */ 166 0x24, /* bDescriptorType: CS_INTERFACE */ 167 0x01, /* bDescriptorSubtype: Call Management Func Desc */ 168 0x00, /* bmCapabilities: D0+D1 */ 169 0x03, /* !! bDataInterface: */

170 /*ACM Functional Descriptor*/ 171 0x04, /* bFunctionLength */ 172 0x24, /* bDescriptorType: CS_INTERFACE */ 173 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ 174 0x02, /* bmCapabilities */

175 /*Union Functional Descriptor*/ 176 0x05, /* bFunctionLength */ 177 0x24, /* bDescriptorType: CS_INTERFACE */ 178 0x06, /* bDescriptorSubtype: Union func desc */ 179 0x02, /* !! bMasterInterface: Communication class interface */ 180 0x03, /* !! bSlaveInterface0: Data Class Interface */

181 /*Endpoint 2 Descriptor*/ 182 0x07, /* bLength: Endpoint Descriptor size */ 183 USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ 184 0x85, /* bEndpointAddress: (IN2) */ 185 0x03, /* bmAttributes: Interrupt */ 186 VIRTUAL_COM_PORT_INT_SIZE, /* wMaxPacketSize: */ 187 0x00, 188 0xFF, /* bInterval: */ 189 190 /*Data class interface descriptor*/ 191 0x09, /* bLength: Endpoint Descriptor size */ 192 USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ 193 0x03, /* bInterfaceNumber: Number of Interface */ 194 0x00, /* bAlternateSetting: Alternate setting */ 195 0x02, /* bNumEndpoints: Two endpoints used */ 196 0x0A, /* bInterfaceClass: CDC */ 197 0x00, /* bInterfaceSubClass: */ 198 0x00, /* bInterfaceProtocol: */ 199 0x00, /* iInterface: */

200 /*Endpoint 3 Descriptor*/ 201 0x07, /* bLength: Endpoint Descriptor size */ 202 USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ 203 0x06, /* bEndpointAddress: (OUT3) */ 204 0x02, /* bmAttributes: Bulk */ 205 VIRTUAL_COM_PORT_DATA_SIZE, /* wMaxPacketSize: */ 206 0x00, 207 0x00, /* bInterval: ignore for Bulk transfer */

208 /*Endpoint 1 Descriptor*/ 209 0x07, /* bLength: Endpoint Descriptor size */ 210 USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ 211 0x84, /* bEndpointAddress: (IN1) */ 212 0x02, /* bmAttributes: Bulk */ 213 VIRTUAL_COM_PORT_DATA_SIZE, /* wMaxPacketSize: */ 214 0x00, 215 0x00 /* bInterval */ 216 }; 217 218 /* USB String Descriptors */ 219 const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID] = 220 { 221 VIRTUAL_COM_PORT_SIZ_STRING_LANGID, 222 USB_STRING_DESCRIPTOR_TYPE, 223 0x09, 224 0x04 /* LangID = 0x0409: U.S. English */ 225 }; 226 227 const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR] = 228 { 229 VIRTUAL_COM_PORT_SIZ_STRING_VENDOR, /* Size of Vendor string */ 230 USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/ 231 /* Manufacturer: "STMicroelectronics" */ 232 'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0, 233 'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0, 234 'c', 0, 's', 0 235 }; 236 237 const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT] = 238 { 239 VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT, /* bLength */ 240 USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ 241 /* Product name: "STM32 Virtual COM Port" */ 242 'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'V', 0, 'i', 0, 243 'r', 0, 't', 0, 'u', 0, 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 244 'M', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0, ' ', 0, ' ', 0 245 }; 246 247 uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] = 248 { 249 VIRTUAL_COM_PORT_SIZ_STRING_SERIAL, /* bLength */ 250 USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ 251 'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0 252 }; 253 254 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
 1 ; 
 2 ; STMicroelectronics Comunication Device Class driver instalation file
 3 ; (C)2006 Copyright STMicroelectronics
 4 ;
 5 
 6 [Version] 
 7 Signature="$Windows NT$" 
 8 Class=Ports
 9 ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} 
10 Provider=%STM% 
11 LayoutFile=layout.inf
12 DriverVer=10/02/06
13 
14 [Manufacturer] 
15 %STM%=DeviceList
16 
17 [DestinationDirs] 
18 DefaultDestDir=12 
19 
20 [SourceDisksFiles]
21 
22 [SourceDisksNames]
23 
24 [DeviceList] 
25 %DESCRIPTION%=STMUSB, USB\VID_03EB&PID_6133&MI_00 
26 %DESCRIPTION%=STMUSB, USB\VID_03EB&PID_6133&MI_02 
27 ;------------------------------------------------------------------------------
28 ;  Windows 2000/XP Sections
29 ;------------------------------------------------------------------------------
30 
31 [STMUSB.nt] 
32 include=mdmcpq.inf
33 CopyFiles=DriverCopyFiles
34 AddReg=STMUSB.nt.AddReg 
35 
36 [DriverCopyFiles]
37 usbser.sys,,,0x20
38 
39 [STMUSB.nt.AddReg] 
40 HKR,,DevLoader,,*ntkern 
41 HKR,,NTMPDriver,,usbser.sys 
42 HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" 
43 
44 [STMUSB.nt.Services] 
45 AddService=usbser, 0x00000002, DriverService
46 
47 
48 [STMUSB.nt.HW]
49 include=mdmcpq.inf
50 
51 [DriverService] 
52 DisplayName=%DESCRIPTION% 
53 ServiceType=1
54 StartType=3
55 ErrorControl=1
56 ServiceBinary=%12%\usbser.sys 
57 
58 ;------------------------------------------------------------------------------
59 ;  String Definitions
60 ;------------------------------------------------------------------------------
61 
62 [Strings] 
63 STM="STMicroelectronics"
64 DESCRIPTION="STM32F10x DUAL CDC" 
posted @ 2012-10-24 13:49  IAmAProgrammer  阅读(14934)  评论(0编辑  收藏  举报