cancel
Showing results for 
Search instead for 
Did you mean: 

usb CDC control interface (can this be removed)

russdx
Associate II
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 :)
22 REPLIES 22
tsuneo
Senior
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
russdx
Associate II
Posted on October 13, 2012 at 21:04

Ah yes good idea (i was using the same inf from before) i changed the vid/pid and created a new inf file and installed the device using this.

same problem, cant sent data :(

im starting to think the stm classes actually need this control interface?

i had a little play and i have noticed if i swap the control interface / data interface id numbers over then set the main config to say there is only 1 config. it just shows up as one device and works :)  

BUT USBlyer has a little moan that the configs are not correct (which is very true, there is 2 interfaces but im saying there is only 1)

seams to be the only way to get it to work, the second i remove this control interface completely it will not send data :(
tsuneo
Senior
Posted on October 14, 2012 at 11:59

Ah, I remember.

usb_claim_interface() of libusb puts Set_Interface request. Your trouble may be caused by the process of Set_Interface request of the ST USB device stack. Are you working on STM32_USB-FS-Device_Lib_V3.4.0, or STM32_USB-Host-Device_Lib_V2.1.0 ? For example of STM32_USB-FS-Device_Lib_V3.4.0, Set_Interface request is processed by Standard_SetInterface()

STM32_USB-FS-Device_Lib_V3.4.0\Libraries\STM32_USB-FS-Device_Driver\src\usb_core.c
/*******************************************************************************
* Function Name : Standard_SetInterface.
* Description : This routine is called to set the interface.
* Then each class should configure the interface them self.
* Input : None.
* Output : None.
* Return : - Return USB_SUCCESS, if the request is performed.
* - Return USB_UNSUPPORT, if the request is invalid.
*******************************************************************************/
RESULT Standard_SetInterface(void)
{
RESULT Re;
/*Test if the specified Interface and Alternate Setting are supported by
the application Firmware*/
Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0);
if (pInformation->Current_Configuration != 0)
{
if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0)
|| (pInformation->USBwValue1 != 0))
{
return USB_UNSUPPORT;

In this routine, (*pProperty->Class_Get_Interface_Setting)() callback is called. On the Virtual_COM_Port example, Virtual_Com_Port_Get_Interface_Setting() is the callback.

STM32_USB-FS-Device_Lib_V3.4.0\Project\Virtual_COM_Port\src\usb_prop.c
/*******************************************************************************
* Function Name : Virtual_Com_Port_Get_Interface_Setting.
* Description : test the interface and the alternate setting according to the
* supported one.
* Input1 : uint8_t: Interface : interface number.
* Input2 : uint8_t: AlternateSetting : Alternate Setting number.
* Output : None.
* Return : The address of the string descriptors.
*******************************************************************************/
RESULT Virtual_Com_Port_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
{
if (AlternateSetting > 0)
{
return USB_UNSUPPORT;
}
else if (Interface > 1) // <---- Interface no. 1 fails
{
return USB_UNSUPPORT;
}
return USB_SUCCESS;
}

Virtual_Com_Port_Get_Interface_Setting() returns USB_SUCCESS for interface number 0, but interface number 1 fails in USB_UNSUPPORT. After all, Standard_SetInterface fails. Tsuneo
russdx
Associate II
Posted on October 14, 2012 at 14:09

Hey :)

im using STM32_USB-Host-Device_Lib_V2.1.0 and neither of those methods exist, looks like they made some quite big changes in later versions.

i assume there is a similar method in this V2.1.0 library?

what your saying does sound like the problem :)
tsuneo
Senior
Posted on October 14, 2012 at 17:48

> im using STM32_USB-Host-Device_Lib_V2.1.0

OK, here is the Set_Interface process on the VCP example on STM32_USB-Host-Device_Lib_V2.1.0

STM32_USB-Host-Device_Lib_V2.1.0\Project\USB_Device_Examples\VCP\inc\usbd_conf.h
#define USBD_ITF_MAX_NUM 1
STM32_USB-Host-Device_Lib_V2.1.0\Libraries\STM32_USB_Device_Library\Class\cdc\src\usbd_cdc_core.c
/**
* @brief usbd_cdc_Setup
* Handle the CDC specific requests
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t usbd_cdc_Setup (void *pdev, 
USB_SETUP_REQ *req)
{
uint16_t len=USB_CDC_DESC_SIZ;
uint8_t *pbuf=usbd_cdc_CfgDesc + 9;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
...
...
/* Standard Requests -------------------------------*/
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
...
... 
case USB_REQ_SET_INTERFACE :
if ((uint8_t)(req->wValue) < 
USBD_ITF_MAX_NUM
) // <---- Interface no. 1 fails
{
usbd_cdc_AltSet = (uint8_t)(req->wValue);
}
else
{
/* Call the error management function (command will be nacked */
USBD_CtlError (pdev, req); // <---- STALL is returned to Set_Interface
}
break;
}
}
return USBD_OK;
}

Set_Interface fails at interface No. 1, too On the libusb side, usb_claim_interface() fails, and subsequent bulk endpoint access also fails. I believe this is the scenario of your trouble. > i had a little play and i have noticed if i swap the control interface / data interface id numbers Increase USBD_ITF_MAX_NUM value from 1 to 2, and you don't need such a trick.

STM32_USB-Host-Device_Lib_V2.1.0\Project\USB_Device_Examples\VCP\inc\usbd_conf.h
#define USBD_ITF_MAX_NUM 1 // <---- 2

As of single-interface configuration, Did you change bInterfaceNumber from 0x01 to 0x00?

/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */ // <---- 0x00

Tsuneo
russdx
Associate II
Posted on October 14, 2012 at 19:20

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6bw&d=%2Fa%2F0X0000000brn%2F8R0t4EZmDvNoC95.rOLFrRCRTMtkr.pK9USky7M5wcg&asPdf=false
russdx
Associate II
Posted on October 14, 2012 at 23:38

using the ''correct'' cdc data interface only descriptor here is what happens (capturing the usb data using usblyzer)

this is just cdc data interface (does not work :()

http://imageshack.us/a/img838/407/usbcoms.png

this is cdc data + control (works)

http://imageshack.us/a/img31/4874/usbcomsgood.png

both of them are identical until it tries to send the data at this point it fails on the cdc data only version.
tsuneo
Senior
Posted on October 15, 2012 at 03:32

On the failed sniffer log, ''Unsuccessful (Device not Responding)'' error suggests that the endpoint is not opened (enabled). The endpoints are opened at usbd_cdc_Init() using DCD_EP_Open(), and they are closed at usbd_cdc_DeInit() using DCD_EP_Close(), on usbd_cdc_core.c

Possible causes are,

a) usbd_cdc_Init() is not called.

or

b) The endpoint is accidentally closed by some error, not shown in the sniffer log.

Please take full sniffer log, starting from device plug-in, up to the bulk transfer error.

Do you see any error on full log, before the bulk transfer fails?

Tsuneo

russdx
Associate II
Posted on October 15, 2012 at 18:57

here are the logs from a reset on the device

good (control+data interfaces)

http://img528.imageshack.us/img528/7451/usbfullgood.png

bad (just data interface)

http://img38.imageshack.us/img38/8928/usbfullbad.png

(the area in red on the bad caputure can be ignored its because i forgot to swap the VID over in my test program and it couldnt find the device oops)

to me the logs looks identical they both do exactly the same thing, just the one without the cdc control interface again refuses to send data :(

i must admit even though this is not working at the moment i am learning A LOT about the usb stack and how it all works, some thing i wouldn't of done if it had worked first time!
tsuneo
Senior
Posted on October 16, 2012 at 05:02

On the sniffer logs, either succeeded or failed, no Set_Configuration is seen on enumeration.

This request is required on the device side, to finish enumeration.

Also, the bulk endpoints are opened in the process of this request by usbd_cdc_Init()

On the host app, is usb_set_configuration() called after the reset?

I rather wonder why the succeeded case would work ;)

Tsuneo