cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 USB HOST cannot get line configuration of device

RPC
Associate III

Hi, I am trying to use a Nucleo-H745ZIQ to implement the USB CDC HOST functionality over the USB OTG FS port. 
I succeeded to do it and make it work if the device connected to my board is another STM32 board which is configured as an usb device, and the communication works alright.
The problem comes when I try to do the same with a modem. The modem has 1 configuration, and 4 interfaces. I increased the USBH_MAX_NUM_INTERFACES to match that and forced it to choose the CDC class from the device which is the Third interface and his CDC data class interface the fourth.
The problem is that it cannot get past the HOST_CLASS_REQUEST state on the state machine because I'm getting this result: CDC: Device Get Line Coding configuration failed. Does somebody knows which could be the problem?

The sections of code I've changed so far if anyone is interested to check:
Inside usbh_core.c:

  • Changed ltf_desc[0] for [2] because the interface I want to use is the third, cause its CDC.
    if (phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[2].bInterfaceClass)
    {
    phost->pActiveClass = phost->pClass[idx];
    break;
    }
  • Changed the USBH_MAX_NUM_INTERFACES from 2 to 4 adapted to the device because I read it on the descriptors.
    • USBH_ParseDevDesc(): device descriptor: idVendor = 5446, idProduct = 4422, bcdDevice = 256,iManufacturer=1, iProduct=2, iSerialNumber=3, bNumConfigurations=1
    • USBH_ParseCfgDesc(): Configuration descriptor: blength = 9, bDescriptorType = 2, wTotalLength = 141,bNumInterfaces=4, bConfigurationValue=1, iConfiguration=0, bmAttributes=224, bMaxPower=250


There's what I see about interfaces on the logs:

  • USBH_FindInterface(): bInterfaceClass = 224, ExpectedInterfaceClass= 2,bInterfaceSubClass= 1, Expected Subclass= 2,bInterfaceProtocol= 3, Expected Protocol= 1
  • USBH_FindInterface(): bInterfaceClass = 10, ExpectedInterfaceClass= 2,bInterfaceSubClass= 0, Expected Subclass= 2,bInterfaceProtocol= 0, Expected Protocol= 1
  • USBH_FindInterface(): bInterfaceClass = 2, ExpectedInterfaceClass= 2,bInterfaceSubClass= 2, Expected Subclass= 2,bInterfaceProtocol= 1, Expected Protocol= 1
  • USBH_FindInterface(): bInterfaceClass = 224, ExpectedInterfaceClass= 10,bInterfaceSubClass= 1, Expected Subclass= 0,bInterfaceProtocol= 3, Expected Protocol= 0
  • USBH_FindInterface(): bInterfaceClass = 10, ExpectedInterfaceClass= 10,bInterfaceSubClass= 0, Expected Subclass= 0,bInterfaceProtocol= 0, Expected Protocol= 0

 

If you need any further information or portion of code I can provide it.
Thank you very much in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
RPC
Associate III

I ended up finding the solution. Seems like the device I tried to connect had 3 endpoints per interface, but because of the define #define USBH_MAX_NUM_ENDPOINTS 2U always when reading the cfg info it read 2endpoints, seems like it is conditioned by that. Anyway, after that I only changed the USBH_CDC_InterfaceInit function to select directly the interface I wanted. Then doing the right assignation of the IN interrupt endpoint which was the first one and the rest assigned as bulk in/out.

Additionaly you will have to change the define of USB_CDC_CLASS to fit with your class.
I'm putting the cfg descriptor read for everybody who has the same issue to understand.
I hope this spares you lots of time of debugging.

bLength = 9"\t",
bDescriptorType = 4"\\004",
bInterfaceNumber = 2"\\002",
bAlternateSetting = 0"\\0",
bNumEndpoints = 3"\\003",
bInterfaceClass = 255"ÿ",
bInterfaceSubClass = 0"\\0",
bInterfaceProtocol = 0"\\0",
iInterface = 0"\\0",
"Ep_Desc ="{
{
bLength = 7"\\a",
bDescriptorType = 5"\\005",
bEndpointAddress = 133"\\205",
bmAttributes = 3"\\003",
wMaxPacketSize = 10,
bInterval = 32" "
},
{
bLength = 7"\\a",
bDescriptorType = 5"\\005",
bEndpointAddress = 132"\\204",
bmAttributes = 2"\\002",
wMaxPacketSize = 64,
bInterval = 0"\\0"
},
{
bLength = 7"\\a",
bDescriptorType = 5"\\005",
bEndpointAddress = 3"\\003",
bmAttributes = 2"\\002",
wMaxPacketSize = 64,
bInterval = 0"\\0"
}

}

View solution in original post

5 REPLIES 5
FBL
ST Employee

Hi @RPC 

 

> The modem has 1 configuration, and 4 interfaces

Check this post Solved: Can USB endpoints be shared between Interface desc... - STMicroelectronics Community

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

RPC
Associate III

Hello, @FBL, first of all thanks for you response.
Based on the post you shared with me, do you mean that if the device has 4 interfaces and my mcu has 2 interfaces, even If I only chose 2 of them, somewhat the endpoints of my mcu are being shared through all the 4 interfaces?
If so, is there a way to control that? Should I skip the first 2 interfaces in the USBH_ParseCfgDesc function ?

FBL
ST Employee

Hi @RPC 


@RPC wrote:

Hello, @FBL, first of all thanks for you response.
Based on the post you shared with me, do you mean that if the device has 4 interfaces and my mcu has 2 interfaces, even If I only chose 2 of them, somewhat the endpoints of my mcu are being shared through all the 4 interfaces?


Do you mean 2 separate Instances?   To communicate with a single modem, it would not be feasible due to USB protocol constraints. On the other hand, total of 9 IN endpoints exceeds the available 8 IN endpoints.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

RPC
Associate III

I mean 2 interfaces. The CDC CLASS with bInterfaceClass=0x02U and the Data interface class:0x0AU.
As shown on the above trace, the device has 4 interfaces, and I'm selecting only 2 of them. I can show you another trace to clarify:

  • USBH_ParseCfgDesc(): Configuration descriptor: blength = 9, bDescriptorType = 2, wTotalLength = 141,bNumInterfaces=4, bConfigurationValue=1, iConfiguration=0, bmAttributes=224, bMaxPower=250
  • USBH_ParseInterfaceDesc(): Interface descriptor: blength = 9, bDescriptorType = 4, bInterfaceNumber = 0,bAlternateSetting=0, bNumEndpoints=1, bInterfaceClass=224, bInterfaceSubClass=1, bInterfaceProtocol=3, iInterface = 4
    USBH_ParseEPDesc(): Endpoint descriptor: blength = 7, bDescriptorType = 5, bEndpointAddress=130, bmAttributes=3, wMaxPacketSize=8, bInterval=32


  • USBH_ParseInterfaceDesc(): Interface descriptor: blength = 9, bDescriptorType = 4, bInterfaceNumber = 1,bAlternateSetting=0, bNumEndpoints=2, bInterfaceClass=10, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface = 5
    USBH_ParseEPDesc(): Endpoint descriptor: blength = 7, bDescriptorType = 5, bEndpointAddress=129, bmAttributes=2, wMaxPacketSize=64, bInterval=0
    USBH_ParseEPDesc(): Endpoint descriptor: blength = 7, bDescriptorType = 5, bEndpointAddress=1, bmAttributes=2, wMaxPacketSize=64, bInterval=0
  • USBH_ParseInterfaceDesc(): Interface descriptor: blength = 9, bDescriptorType = 4, bInterfaceNumber = 2,bAlternateSetting=0, bNumEndpoints=1, bInterfaceClass=2, bInterfaceSubClass=2, bInterfaceProtocol=1, iInterface = 7
    USBH_ParseEPDesc(): Endpoint descriptor: blength = 7, bDescriptorType = 5, bEndpointAddress=132, bmAttributes=3, wMaxPacketSize=10, bInterval=32
  • USBH_ParseInterfaceDesc(): Interface descriptor: blength = 9, bDescriptorType = 4, bInterfaceNumber = 3,bAlternateSetting=0, bNumEndpoints=2, bInterfaceClass=10, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface = 8
    USBH_ParseEPDesc(): Endpoint descriptor: blength = 7, bDescriptorType = 5, bEndpointAddress=131, bmAttributes=2, wMaxPacketSize=64, bInterval=0
    USBH_ParseEPDesc(): Endpoint descriptor: blength = 7, bDescriptorType = 5, bEndpointAddress=2, bmAttributes=2, wMaxPacketSize=64, bInterval=0

 

Here I show every interface with its endpoints And I'm selecting the bold style ones.

RPC
Associate III

I ended up finding the solution. Seems like the device I tried to connect had 3 endpoints per interface, but because of the define #define USBH_MAX_NUM_ENDPOINTS 2U always when reading the cfg info it read 2endpoints, seems like it is conditioned by that. Anyway, after that I only changed the USBH_CDC_InterfaceInit function to select directly the interface I wanted. Then doing the right assignation of the IN interrupt endpoint which was the first one and the rest assigned as bulk in/out.

Additionaly you will have to change the define of USB_CDC_CLASS to fit with your class.
I'm putting the cfg descriptor read for everybody who has the same issue to understand.
I hope this spares you lots of time of debugging.

bLength = 9"\t",
bDescriptorType = 4"\\004",
bInterfaceNumber = 2"\\002",
bAlternateSetting = 0"\\0",
bNumEndpoints = 3"\\003",
bInterfaceClass = 255"ÿ",
bInterfaceSubClass = 0"\\0",
bInterfaceProtocol = 0"\\0",
iInterface = 0"\\0",
"Ep_Desc ="{
{
bLength = 7"\\a",
bDescriptorType = 5"\\005",
bEndpointAddress = 133"\\205",
bmAttributes = 3"\\003",
wMaxPacketSize = 10,
bInterval = 32" "
},
{
bLength = 7"\\a",
bDescriptorType = 5"\\005",
bEndpointAddress = 132"\\204",
bmAttributes = 2"\\002",
wMaxPacketSize = 64,
bInterval = 0"\\0"
},
{
bLength = 7"\\a",
bDescriptorType = 5"\\005",
bEndpointAddress = 3"\\003",
bmAttributes = 2"\\002",
wMaxPacketSize = 64,
bInterval = 0"\\0"
}

}