Skip to main content
Graduate II
August 29, 2024
Solved

STM32 USB HOST cannot get line configuration of device

  • August 29, 2024
  • 2 replies
  • 2199 views

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.

    This topic has been closed for replies.
    Best answer by RPC

    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"
    }

    }

    2 replies

    Technical Moderator
    August 30, 2024

    Hi @RPC 

     

    > The modem has 1 configuration, and 4 interfaces

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

    RPCAuthor
    Graduate II
    September 3, 2024

    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 ?

    Technical Moderator
    September 3, 2024

    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.

    RPCAuthorAnswer
    Graduate II
    September 17, 2024

    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"
    }

    }