AnsweredAssumed Answered

USB Library with device having multiple interfaces

Question asked by Jump.Dennis on Oct 22, 2016
Latest reply on Mar 28, 2017 by leoha
I am not sure if this is a bug fix or an enhancement.
I am developing on a proprietary board using the STM32F7 series processor. I have a device connected via USB using the USB Host Library.
This particular device has more than just a CDC interface and the CDC is NOT the first one in the descriptor list.
The USB Library source file usbh_core.c has code which should be looking through all of the interfaces, but only looks at the first.
To fix this, I changed this:
case HOST_CHECK_CLASS:
 
    if (phost->ClassNumber == 0)
    {
        USBH_UsrLog("No Class has been registered.");
    }
    else
    {
        phost->pActiveClass = NULL;
 
        for (idx = 0; idx < USBH_MAX_NUM_SUPPORTED_CLASS; idx++)
        {
            if ((phost->pClass [ idx ]->ClassCode == phost->device.CfgDesc.Itf_Desc [ 0 ].bInterfaceClass))
            {
                phost->pActiveClass = phost->pClass [ idx ];
            }
        }
to this:
case HOST_CHECK_CLASS:
 
    if (phost->ClassNumber == 0)
    {
        USBH_UsrLog("No Class has been registered.");
    }
    else
    {
        phost->pActiveClass = NULL;
 
        for (idx = 0; idx < USBH_MAX_NUM_SUPPORTED_CLASS; idx++)
        {
            for (int infx = 0; infx < USBH_MAX_NUM_INTERFACES; infx++)
            {
                if ((phost->pClass [ idx ]->ClassCode == phost->device.CfgDesc.Itf_Desc [ infx ].bInterfaceClass))
                {
                    phost->pActiveClass = phost->pClass [ idx ];
                    break;
                }
            }
        }
This picks up all of the interfaces in the descriptor.
I also modified usbh_cdc.c in the 
static USBH_StatusTypeDef USBH_CDC_InterfaceInit(USBH_HandleTypeDef *phost)
function to return separate notification and data interfaces. Worked out well in the long run.
You should also change the SetLineCoding and GetLineCoding functions - and maybe a couple of others - so that the "0" interface is not the default interface. Use the current interface.
I spent a week wondering why everything worked great over the base/notification interface but terrible on the data interfaces.
Discovered the problem tonight.
In usbh_core.c
uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost, uint8_t Class, uint8_t SubClass, uint8_t Protocol, int8_t startWith)
{
    USBH_InterfaceDescTypeDef *pif;
    USBH_CfgDescTypeDef *pcfg;
    int8_t if_ix = startWith; //0; <-- was searching from the first interface for the associated data interface - should start from current interface
So, references to this function need an extra parameter for setting a starting index. The bug here is that the function was always returning the data interface for the first interface when I needed it from the next interface pair after the first.
Hope this helps people who are using USB devices with multiple interfaces or fixes a bug in the library.


Outcomes