cancel
Showing results for 
Search instead for 
Did you mean: 

USB Library with device having multiple interfaces

djump
Associate
Posted on October 22, 2016 at 04:27

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. #!stm32-!usb-!library-!interfaces
2 REPLIES 2
Mateusz Kramarczyk
Associate
Posted on March 28, 2017 at 20:33

Hi,

I know this is and old topic but can you share what changes you made in USB_XXX_InterfaceInit?

I have similar issue to yours (but in HID class) only the one interface is working whereas I use USB dongle with HID keyboard and mouse.

Jona
Associate III

Thank you for posting this. I just ran into the same thing! Kind of hard to believe usbh_core.c would be implemented that way.

Since I am doing this prior to using the same code in any other usbh_***.c functions, like CDC, I am wondering where SetCoding and GetCoding calls are?

Also, why is it not OK to start with the 0th interface USBH_FindInterface()?