Skip to main content
russdx
Associate III
September 30, 2012
Question

usb CDC control interface (can this be removed)

  • September 30, 2012
  • 22 replies
  • 3471 views
Posted on September 30, 2012 at 20:37

I have the CDC example running great :)

It pops up as 2 separate usb interfaces on my pc (0 and 1)

I have noticed to send and receive data over the usb i only need the second interface. the first *control* interface seams to be unused (i can uninstall it from my device manager and i can still send and receive data fine)

my question is can i remove this control/command interface 0  from the stm code so when i plug my board into my pc only the second interface 1 pops up. as this is the only one i need.

Im very new to the usb protocol so be kind if i have missed some thing obvious :)
    This topic has been closed for replies.

    22 replies

    tsuneo
    Associate II
    October 1, 2012
    Posted on October 01, 2012 at 05:09

    > It pops up as 2 separate usb interfaces on my pc (0 and 1)

    ??? I checked the source code of STM32_USB-FS-Device_Lib_V3.4.0 and STM32_USB-Host-Device_Lib_V2.1.0. Surely, the VCP projects on these libraries apply standard two-interface CDC. But I believe they don't pop up ''2 separate usb interfaces'' on Windows device manager. > my question is can i remove this control/command interface 0 from the stm code Windows and Linux accept this single-interface CDC (MacOSX doesn't). But I don't recommend it, because it is out of USB spec, and the support on OS may drop in future OS release.

    ===>Interface Descriptor<===
    bLength: 0x09
    bDescriptorType: 0x04
    bInterfaceNumber: 0x01
    bAlternateSetting: 0x00
    bNumEndpoints: 0x03
    bInterfaceClass: 0x02 -> This is Communications (CDC Control) USB Device Interface Class
    bInterfaceSubClass: 0x02
    bInterfaceProtocol: 0x01
    CAUTION: This may be an invalid bInterfaceProtocol
    iInterface: 0x00
    -> This is a Communications (CDC Control) USB Device Interface Class
    ===>Descriptor Hex Dump<===
    bLength: 0x05
    bDescriptorType: 0x24
    05 24 00 10 01 
    -> This is a Communications (CDC Control) USB Device Interface Class
    ===>Descriptor Hex Dump<===
    bLength: 0x04
    bDescriptorType: 0x24
    04 24 02 02 
    -> This is a Communications (CDC Control) USB Device Interface Class
    ===>Descriptor Hex Dump<===
    bLength: 0x05
    bDescriptorType: 0x24
    05 24 06 01 01 
    -> This is a Communications (CDC Control) USB Device Interface Class
    ===>Descriptor Hex Dump<===
    bLength: 0x05
    bDescriptorType: 0x24
    05 24 01 00 01 
    ===>Endpoint Descriptor<===
    bLength: 0x07
    bDescriptorType: 0x05
    bEndpointAddress: 0x82 -> Direction: IN - EndpointID: 2
    bmAttributes: 0x03 -> Interrupt Transfer Type
    wMaxPacketSize: 0x0008 = 0x08 bytes
    bInterval: 0x02
    ===>Endpoint Descriptor<===
    bLength: 0x07
    bDescriptorType: 0x05
    bEndpointAddress: 0x03 -> Direction: OUT - EndpointID: 3
    bmAttributes: 0x02 -> Bulk Transfer Type
    wMaxPacketSize: 0x0040 = 0x40 bytes
    bInterval: 0x00
    ===>Endpoint Descriptor<===
    bLength: 0x07
    bDescriptorType: 0x05
    bEndpointAddress: 0x83 -> Direction: IN - EndpointID: 3
    bmAttributes: 0x02 -> Bulk Transfer Type
    wMaxPacketSize: 0x0040 = 0x40 bytes
    bInterval: 0x00

    Tsuneo
    russdx
    russdxAuthor
    Associate III
    October 1, 2012
    Posted on October 01, 2012 at 09:34

    hey :)

    when i say 2 interfaces (i think thats the correct term?) i mean when i plug the board into the pc it pops up two (windows has found new hardware) boxes. I am used to working with FTDI devices that only pops up as one device. Actually all usb devices i have come across when you plug them into the pc they only pop up the new hardware box once. but this stm board has 2 one for the control interface and one for the data.

    my goal is to remove this control interface. so when my board is first plugged into a computer it just pops up the one 'found new hardware' thing and you just install the one winUSB driver.

    hope that makes sense?

    i forgot to mention that my project is streaming a very low res 128x32 image from the pc to the stm at around 60fps, i assume the cdc class i need to use for this. i will be using the bulk async transfer functions.

    thanks :)
    tsuneo
    Associate II
    October 1, 2012
    Posted on October 01, 2012 at 17:53

    > i mean when i plug the board into the pc it pops up two (windows has found new hardware) boxes.

    The VCP examples on above libraries pop up no ''New Hardware'' dialog, when this driver package is pre-installed. Plug-in installation finishes without user intervention, just with pop ups on bottom status bar. STM32 Virtual COM Port Driver http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/SW_DRIVER/stm32_vcp.zip > it just pops up the one 'found new hardware' thing and you just install the one winUSB driver. Sound like you are using your custom INF file, which assigns WinUSB to your CDC device. For WinUSB device, you may simplify CDC interfaces into vendor-specifc bulk one, by deleting the Communication interface. You'll need these tuning for other descriptors, too. (1) Config descriptor: wTotalLength - reduce to 32 bNumInterfaces - reduce to 1 (2) Data class interface descriptor bInterfaceNumber - from 1 to 0 bInterfaceClass - from 0x0A to 0xFF

    STM32_USB-FS-Device_Lib_V3.4.0\Project\Virtual_COM_Port\src\usb_desc.c
    const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
    {
    /*Configuration Descriptor*/
    0x09, /* bLength: Configuration Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
    VIRTUAL_COM_PORT_SIZ_CONFIG_DESC, /* wTotalLength */ // <---- 32
    0x00,
    0x02, /* bNumInterfaces: 2 interface */ // <---- 1
    0x01, /* bConfigurationValue: Configuration value */
    0x00, /* iConfiguration: */
    0xC0, /* bmAttributes: self powered */
    0x32, /* MaxPower 0 mA */
    /*Interface Descriptor*/
    // <--- delete all descriptors, which belong to Communication Interface
    /*Data class interface descriptor*/
    0x09, /* bLength: Endpoint Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
    0x01, /* bInterfaceNumber: Number of Interface */ // <---- 0
    0x00, /* bAlternateSetting: Alternate setting */
    0x02, /* bNumEndpoints: Two endpoints used */
    0x0A, /* bInterfaceClass: CDC */ // <---- 0xFF (vendor-specific)
    0x00, /* bInterfaceSubClass: */
    0x00, /* bInterfaceProtocol: */
    0x00, /* iInterface: */
    /*Endpoint 3 Descriptor*/
    0x07, /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
    0x03, /* bEndpointAddress: (OUT3) */
    0x02, /* bmAttributes: Bulk */
    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 */
    VIRTUAL_COM_PORT_DATA_SIZE, /* wMaxPacketSize: */
    0x00,
    0x00 /* bInterval */
    };

    After this change of the descriptors, you'll need to change your INF file. At [DeviceList] section, - Delete one of the line from two - Delete ''&MI_00'' (or ''&MI_01'') at the end of the line Lastly, the device instances on Windows should be deleted to refresh them into the new configuration descriptor set. Tsuneo
    russdx
    russdxAuthor
    Associate III
    October 1, 2012
    Posted on October 01, 2012 at 20:02

    Thanks Tsuneo :)

    Sorry i forgot to mention the example is a slightly modified version to use winUSB. it came from here. 

    http://www.youtube.com/watch?v=WR9Bv08tMg0

    I think i have a pretty good idea now how to tweak the code.

    thank you :)

    One quick question :), the reason i choose this winUSB example was because i read some where that the standard windows usb driver does not implement bulk isochronous transfers. my device needs to send 2048byte frames at 60fps, do i really need isochronous or could i get away with just bulk transfer. 

    or is this one to have a play and find out? :)
    russdx
    russdxAuthor
    Associate III
    October 1, 2012
    Posted on October 01, 2012 at 23:03

    deleted*

    tsuneo
    Associate II
    October 2, 2012
    Posted on October 02, 2012 at 06:22

    > i read some where that the standard windows usb driver does not implement bulk isochronous transfers.

    Ah, WinUSB doesn't support isochronous transfer.

    > do i really need isochronous or could i get away with just bulk transfer.

     

    I recommend you to stay in the bulk transfer, instead of isochronous.

    1) Full-speed bulk transfer reaches to ''2048byte frames at 60fps'' (120k bytes/s) easily

    To keep transfer speed, read 2048 bytes at a time, using libusb_bulk_transfer() on your PC application (libusb-Win32). Your firmware sends 2048 bytes frame, by splitting it into 32 packets (transactions) of 64 bytes.

    PC host controller (hardware) concatenates these packets into single transfer, and it passes to libusb_bulk_transfer(). As this process is done by the hardware, the timing overhead goes the least.

    2) Bulk transfer provides easier timing on your firmware than isochronous.

    Isochronous transfer gives just single chance per frame. When your firmware would miss this timing, it should wait until the next frame. On the other hand, bulk transfer gives many (30-50 times) chances per frame.

    Tsuneo

    russdx
    russdxAuthor
    Associate III
    October 2, 2012
    Posted on October 02, 2012 at 09:44

    Perfect :)

    the pc is sending the frames to the stm, im sure its the same process as you described :)

    Im using STM32_USB-Host-Device_Lib_V2.1.0 and have noticed the descriptor you edited above is not in the usb_desc.c but in the usbd_cdc_core.c file. i assume this does not matter as long as i edit it correct to chop out the control interface :)

    Thanks for all your help :)
    russdx
    russdxAuthor
    Associate III
    October 12, 2012
    Posted on October 12, 2012 at 23:39

    I have made the changes you suggested and now only one interface (0) is available :) and using USBlyer is all looks ok :)

    http://img194.imageshack.us/img194/6814/usbk.png

    but my libusb program does not seam to want to send data, it opens the device ok :) it also claims (the now interface 0) ok :) but when it comes to do a usb_bulk_write it fails with

    'libusb0-dll:err [_usb_reap_async] reaping request failed, win error: A device attached to the system is not functioning.'

    not quite sure whats going wrong here. it all works when i go back to the original 2 interface configuration (but libusb just connected to interface 1)
    russdx
    russdxAuthor
    Associate III
    October 12, 2012
    Posted on October 13, 2012 at 01:30

    i have also tried

    0x0A,   /* bInterfaceClass: CDC */ for CDC DATA

    tsuneo
    Associate II
    October 13, 2012
    Posted on October 13, 2012 at 17:23

    Sound like Windows get confused with new configuration, mixing up with the old config.

    For new configuration, assign another VID/PID at the device descriptor. For example of VID/PID = 0xFFF0/0x0001,

    /* USB Standard Device Descriptor */
    const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
    {
    0x12, /* bLength */
    USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
    0x00,
    0x02, /* bcdUSB = 2.00 */
    0x02, /* bDeviceClass: CDC */
    0x00, /* bDeviceSubClass */
    0x00, /* bDeviceProtocol */
    0x40, /* bMaxPacketSize0 */
    0x83, // <--- 0xF0
    0x04, /* idVendor = 0x0483 */ // <--- 0xFF
    0x40, // <--- 0x01
    0x57, /* idProduct = 0x7540 */ // <--- 0x00
    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 */
    };

    A new INF file should be generated for this VID/PID, too. Tsuneo