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
3 REPLIES 3
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()?

Robmar
Senior III

    What a mess ST USB code is!  They've not updated it in 9 years, since 2015.

To select the required interface, Mouse or Keyboard for example for an HID, set the existing Protocol parameter on the call to USBH_FindInterface(...) in USBH_HID_InterfaceInit(..), this is the correct way, although the ST code does not allow the value to be passed in unmodified by the client app.

Protocol is set to 0xff by default which forces it to take the first device in the selected class.

Protocol can be set as follows = :-

#define HID_BOOT_CODE 0x01U

#define HID_KEYBRD_BOOT_CODE 0x01U

#define HID_MOUSE_BOOT_CODE 0x02U

As more powerful and lower cost ESP and Raspberry Pi industrial boards are rapidly eroding ST's MCU market, ST staff are sleeping on the job, especially the MCU division manager, IMHO.