Cypress Perform

Home > Design Support > Cypress Developer CommunityTM > Cypress Forums > USB Controllers > How to create descriptor with two interfaces ?

Bookmark and Share
Cypress Developer CommunityTM
Forums | Videos | Blogs | Training | Rewards Program | Community Components



How to create descriptor with two interfaces ?
Moderator:
RSKV

Post Reply
Follow this topic



How to create descriptor with two interfaces ?

Vytautas2 posted on 28 Feb 2012 6:32 AM PST
Top Contributor
36 Forum Posts

 Hi,

i would like to create descriptor with two interfaces, but attempt to do so causes that in device manager Windows display that device cannot start, and control center does not display anything. If with the same endpoints i write descriptor with one interface, then everything is ok. See sample descriptors below.

Thanks.

---------------

Two interfaces that do not work (device cannot start):

const uint8_t CyFxUSBHSConfigDscr[] =

{

// Configuration Descriptor Type

0x09,                           // Descriptor Size

CY_U3P_USB_CONFIG_DESCR,        // Configuration Descriptor Type

0x29,0x00,                      // Length of this descriptor and all sub descriptors

0x02,                           // Number of interfaces

0x01,                           // Configuration number

0x00,                           // COnfiguration string index

0x80,                           // Config characteristics - Bus powered

0x64,                           // Max power consumption of device (in 2mA unit)

 

// Interface Descriptor

0x09,                           // Descriptor size

CY_U3P_USB_INTRFC_DESCR,        // Interface Descriptor type

0x00,                           // Interface number

0x00,                           // Alternate setting number

0x01,                           // Number of end points

0xFF,                           // Interface class

0x00,                           // Interface sub class

0x00,                           // Interface protocol code

0x00,                           // Interface descriptor string index

 

// EP1 interrupt IN

0x07,                           // Descriptor size

CY_U3P_USB_ENDPNT_DESCR,        // Endpoint descriptor type

CY_FX_EP1_INT,            // Endpoint address and description

CY_U3P_USB_EP_INTR,             // Interrupt endpoint type

0x00,0x04,                      // Max packet size = 1024 bytes

0x01,                           // Servicing interval for data transfers

 

// Interface Descriptor

0x09,                           // Descriptor size

CY_U3P_USB_INTRFC_DESCR,        // Interface Descriptor type

0x00,                           // Interface number

0x00,                           // Alternate setting number

0x01,                           // Number of end points

0xFF,                           // Interface class

0x00,                           // Interface sub class

0x00,                           // Interface protocol code

0x00,                           // Interface descriptor string index

 

// EP2 isochronous IN

0x07,                           // Descriptor size

CY_U3P_USB_ENDPNT_DESCR,        // Endpoint Descriptor Type

CY_FX_EP2_ISO,            // Endpoint address and description

CY_U3P_USB_EP_ISO,              // Iso End point Type

    0x00,0x04,                      // Max packet size = 1024 bytes

0x01                            // Servicing interval for data transfers

};

 

---------------

One interface with two endpoints that work:

const uint8_t CyFxUSBHSConfigDscr[] =

{

// Configuration Descriptor Type

0x09,                           // Descriptor Size

CY_U3P_USB_CONFIG_DESCR,        // Configuration Descriptor Type

0x20,0x00,                      // Length of this descriptor and all sub descriptors

0x01,                           // Number of interfaces

0x01,                           // Configuration number

0x00,                           // COnfiguration string index

0x80,                           // Config characteristics - Bus powered

0x64,                           // Max power consumption of device (in 2mA unit)

 

// Interface Descriptor

0x09,                           // Descriptor size

CY_U3P_USB_INTRFC_DESCR,        // Interface Descriptor type

0x00,                           // Interface number

0x00,                           // Alternate setting number

0x02,                           // Number of end points

0xFF,                           // Interface class

0x00,                           // Interface sub class

0x00,                           // Interface protocol code

0x00,                           // Interface descriptor string index

 

// EP1 interrupt IN

0x07,                           // Descriptor size

CY_U3P_USB_ENDPNT_DESCR,        // Endpoint descriptor type

CY_FX_EP1_INT,            // Endpoint address and description

CY_U3P_USB_EP_INTR,             // Interrupt endpoint type

0x00,0x04,                      // Max packet size = 1024 bytes

0x01,                           // Servicing interval for data transfers

 

// EP2 isochronous IN

0x07,                           // Descriptor size

CY_U3P_USB_ENDPNT_DESCR,        // Endpoint Descriptor Type

CY_FX_EP2_ISO,            // Endpoint address and description

CY_U3P_USB_EP_ISO,              // Iso End point Type

    0x00,0x04,                      // Max packet size = 1024 bytes

0x01                            // Servicing interval for data transfers

};

---------------

 




Re: How to create descriptor with two interfaces ?

Vytautas2 posted on 28 Feb 2012 07:01 AM PST
Top Contributor
36 Forum Posts

Second interface number mosl likely should be 1, but this causes that device is still not visible in control center and Windows start to work so slowly that you need to shut down the computer (USB disconnection does not help).

// Interface Descriptor

0x09,                           // Descriptor size

CY_U3P_USB_INTRFC_DESCR,        // Interface Descriptor type

0x01,                           // Interface number

 



Re: How to create descriptor with two interfaces ?

aasi posted on 28 Feb 2012 10:02 AM PST
Cypress Employee
1073 Forum Posts

 When you introduce multiple interface it usually gets bound to usbccgp.sys (composite class driver) and the device will show up like 2 separate interfaces (1 for each interface).

You're right the interface number is 1. I'm not sure if the current USB3 windows stack is capable of handling composite device. Have you tried connecting to the USB2.0 port to make sure it is not a PC specific issue?

Regards,

Anand



Re: How to create descriptor with two interfaces ?

Vytautas2 posted on 28 Feb 2012 10:45 AM PST
Top Contributor
36 Forum Posts

I connect to USB 2.0 port.



Re: How to create descriptor with two interfaces ?

aasi posted on 28 Feb 2012 11:18 AM PST
Cypress Employee
1073 Forum Posts

Have you made the modification for the multiple interface on the USB2.0 (high-speed) part?

Regards,

Anand



Re: How to create descriptor with two interfaces ?

Vytautas2 posted on 29 Feb 2012 11:26 PM PST
Top Contributor
36 Forum Posts

Above presented descriptors are for high speed (HS). Do I need to modify not only descriptor, but anything else in order to make 2 interfaces ?



Re: How to create descriptor with two interfaces ?

Vytautas2 posted on 01 Mar 2012 05:23 AM PST
Top Contributor
36 Forum Posts

After changing of PID Windows start to detect composite, so at this moment it seems that the problem is not in descriptor, but that before changing hw configuration you must either uninstall drivers and do other cleanup or change hw ids.



Re: How to create descriptor with two interfaces ?

Vytautas2 posted on 01 Mar 2012 06:41 AM PST
Top Contributor
36 Forum Posts

And maybe device class should be EF and config descriptor should have interface association descriptor similar to cyfxuvcinmem sample.



Re: How to create descriptor with two interfaces ?

aasi posted on 01 Mar 2012 07:46 PM PST
Cypress Employee
1073 Forum Posts

That is strange. multiple interface usually bind to usbccgp.sys and windows will expose each interface as a different device.

 

Even then when bound to cyusb3.sys it shouldn't slow down your PC. i.e. it will just show up as one device and you'll be able to access only the first interface without any side effects. Let me check if I'm able to replicate it.

Regards,

Anand



Re: How to create descriptor with two interfaces ?

Vytautas2 posted on 02 Mar 2012 11:50 PM PST
Top Contributor
36 Forum Posts

With simply adding two interfaces like I described at the beginning of the posts, Windows were unable to recognize device - assigned VID and PID to 0000.

After changing device class to EF and adding interface association descriptor Windows detected composite device and another device. Different USB tools now can get descriptors and show interfaces and endpoints that were defined.

Any attempt to install Cypress driver for that another detected device (composite device uses Microsoft drivers) makes that Windows hang.

 



Re: How to create descriptor with two interfaces ?

Vytautas2 posted on 02 Mar 2012 12:29 AM PST
Top Contributor
36 Forum Posts

Now I again tried descriptors with two interfaces from my first posts with changed PID. The result was that Windows detected composite and two other devices. For these two other devices I was able to install Cypress drivers and Control Center application also showed two devices where one device has interface 0 and another device has interface 1.

So I guess that my previously mentioned unrecognized device with 0000 ids was not related to descriptors, because sometimes I see it also when clicking reset button on dev board.

 



Re: How to create descriptor with two interfaces ?

MarSch posted on 02 Mar 2012 02:10 AM PST
Senior Member
17 Forum Posts

Hi,

I'm facing the same problems as the OP. I however need to have a single device with multiple interfaces.

I broke the problem down by using the cyfxbulklpautoenum example. The only one thing changed is that every endpoint has its own interface, ie. functionality should remain.

Modifications I made to the example are (for each of the 3 USB speeds):

  1. adding a second interface descriptor after the first endpoint descriptor
  2. change its index to 0x01
  3. changing the endpoint count for each interface descriptor to 0x01
  4. changing the configuration descriptor size appropriately (add 0x09)
  5. changing the interface count of the configuration descriptor to 0x02

I would expect that the device comes up similar to the original cyfxbulklpautoenum firmware, however with each endpoint in its own interface.

With the above steps it should be no problem to reproduce this issue. I also attached the modified project.

Regards,

/Markus

 



Re: How to create descriptor with two interfaces ?

Vytautas2 posted on 02 Mar 2012 02:23 AM PST
Top Contributor
36 Forum Posts

As I understood from all googling about composite devices, two interfaces usually mean that in Windows device manager we will see composite device and two other devices that corespond to each interface.

If you need one device, then most likely you will need to use device class 0xEF and USB Interface Association Descriptor, but I'm not sure if it will do what you need.

http://msdn.microsoft.com/en-us/library/windows/hardware/ff540054(v=vs.85).aspx

http://www.microsoft.com/taiwan/whdc/archive/iad.mspx

 



Re: How to create descriptor with two interfaces ?

heha posted on 21 Mar 2012 09:02 AM PST

1 Forum Post

usbccgp.sys hangs Windows to death when a descriptor is malformed?

Yes, it's true. Even for full-speed and low-speed devices. So double-check your descriptors:

  • The first Configuration Descriptor has ID #1
  • The first Interface Descriptor has ID #0 and are contiguous numbered. The Interface count in Configuration Descriptor must be set correctly.
  • The first Alternate Setting has ID #0 and are contiguous numbered

Problems arise when you change your single-interface USB device into a multi-interface (multi-function) while keeping your USB VID+PID pair! Even when your change or add some more USB interface with the same VID+PID pair, problems occur.

The Windows behaviour of assigning a driver is as follows:

  • If the VID+PID is already known, Windows loads the known driver regardless whether it's a multi-function device or not. (I.e. when you loaded a driver before for the non-multifunction device with PnP ID e.g. USB\VID_16C0&PID_06B3, that driver is always used.) As a consequence, your driver will fail (typically with a blue screen) when it is surprisingly bound to the - now - multifunction USB device.
  • If VID+PID is not known, Windows tries to load a Class Driver. This is "usbccgp.sys" for the top of multifunction devices which is a very special class (not USB\Class_00).
  • Windows remembers the Class-Driver-To-VID+PID(+MI)-binding for the next plug-in event persistently, probably for performance purposes. Therefore, when you swap your Interfaces keeping VID+PID, you earn errors. But you can get rid easily by uninstalling your device in Device Manager. This will remove the memorized bindings.
  • "usbccgp.sys" itself retries the enumeration process for the child devices in the same way, i.e. preferes VID+PID+MI bindings over USB Class bindings.
  • In case of no match, no driver is loaded, and the entry is marked in Device Manager.

So you may conclude:

  • VID+PID, and MI numbers (like USB\VID_16C0&PID_06B3&REV_4621&MI_00) have precedence, allowing manufacturers to deliver their own multifunction device drivers (replacing "usbccgp.sys")
  • USB CLASS bindings (like USB\Class_07) have less precedence, allowing manufacturers to deliver their own specialized device driver replacing one of the system-supplied class drivers (like "usbprint.sys")
  • REV numbers don't matter Windows, so manufacturers are free to (mis)use this entry, and there is no option to get more possible USB device bindings "for free" using the REV number as an extra binding criterion

An example: This INF file snippet is wrong because you have no control whether your driver is bound to the Interface #0 or the entire USB device (except your driver is very smart and can handle this):

  • %DevDesc%=Dev,USB\VID_16C0&PID_06B3&REV_4621&MI_00
    %DevDesc%=Dev,USB\VID_16C0&PID_06B3&REV_4620
     

(Windows will work as expected most of the time, but users are able to bind multi-function devices to entire devices, and produce overwhelming trouble with your support.)

 

As a result:

If you change your single-interface USB device to multi-interface and vice versa keeping VID+PID, make sure that you cleaned your Device Manager entries beforehand. Or at least before you plug your changed device. Google for devmgr_show_nonpresent_devices and devmgr_show_details to get a clue.

Better you change VID+PID too, providing you have a free pair available.

If you are in doubt offering a single-interface or multi-interface USB device, simply decide to multi-interface at the first step, and implement an extra HID or CDC interface to make usbccgp.sys happy. It's useful for debugging purposes later. At least two childs are needed.

Note that CDC interface (which is itself a composite USB device by design and handled in a special way by usbccgp.sys) will not run properly in elsewhere-multifunction devices on Windows 2000 and earlier.






ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". CYPRESS SEMICONDUCTOR AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY CYPRESS SEMICONDUCTOR. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM CYPRESS SEMICONDUCTOR.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms and Conditions of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms and Conditions of this site. Cypress Semiconductor and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.