2020-04-27 05:38 AM
I'm using an STM32F722 to implement a USB Host (FS) for HID class so that I can connect a mouse to my custom board. To rule out any soldering problems, I bridged both ESD and overcurrent protection.
Over the past couple of days, I've been testing USB with three different Logitech mice:
Mouse #1 results in HOST_ABORT_STATE. The corresponding (disabled) error log message reads "Device not responding Please unplug."
Mouse #2 works like a charm, after about 1 second after power-on I get a call to USBH_HID_EventCallback.
Mouse #3, received just today, doesn't fail, but it doesn't call USBH_HID_EventCallback either. It remains seemingly forever in state ENUM_GET_SERIALNUM_STR / CMD_SEND.
This is a pretty bad test result. All of these mice work perfectly fine with my PC.
I don't even know how to debug this. Could this be an electrical problem? (But then again, the STM32 is directly connected to the USB connector, together with 5V and GND.)
How can I approach this problem? What is the USB library waiting for in case #3? Can single-stepping through the USB library mess with signal timing?
Solved! Go to Solution.
2020-04-28 09:31 AM
Thanks for your answers, Jan and Pavel. I did apply the linked patch, but it didn't help.
But last night, right before falling asleep, I had an idea: Wasn't the state I saw the final state in that state machine? And doesn't USBH_IDLE just mean that the USB device is not sending any data? Which makes sense, since I put the mouse upside down so that I can confirm the LED lights up.
And sure enough, once I actually start moving the mouse, I'm immediately in the callback. Tada!
Jan and Pavel, I absolutely don't doubt your assessment of the USB library. Even now, mouse #1 doesn't work at all, although it should. But for my little hobby project, this result now is good enough.
My apologies for this easy answer. :smiling_face_with_smiling_eyes:
2020-04-27 10:22 AM
It seems I've been lucky previously, because now even mouse #2 will not work.
The code loops endlessly in USBH_HID_Process(), entering the HID_POLL case.
static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
{
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
switch (HID_Handle->state)
{
//...
case HID_POLL:
if (USBH_LL_GetURBState(phost, HID_Handle->InPipe) == USBH_URB_DONE)
{
XferSize = USBH_LL_GetLastXferSize(phost, HID_Handle->InPipe);
if ((HID_Handle->DataReady == 0U) && (XferSize != 0U))
{
USBH_HID_FifoWrite(&HID_Handle->fifo, HID_Handle->pData, HID_Handle->length);
HID_Handle->DataReady = 1U;
USBH_HID_EventCallback(phost);
}
}
else
{
/* IN Endpoint Stalled */
if (USBH_LL_GetURBState(phost, HID_Handle->InPipe) == USBH_URB_STALL)
{
/* Issue Clear Feature on interrupt IN endpoint */
if (USBH_ClrFeature(phost, HID_Handle->ep_addr) == USBH_OK)
{
/* Change state to issue next IN token */
HID_Handle->state = HID_GET_DATA;
}
}
}
break;
// ...
}
return status;
}
Function USBH_LL_GetURBState(phost, HID_Handle->InPipe) always returns URB_IDLE, while the code is waiting for URB_DONE. Interestingly, USB_STALL is also a possible return value, but I've never observed it.
2020-04-27 11:17 AM
> How can I approach this problem?
Don't expect this to be solved easily,
Start with getting a bus analyzer (some LAs and oscilloscopes can analyze USB) and acquiring a deep understanding of all aspects of the protocol and the OTG module in STM32.
USB is a very complex interface, The particular OTG IP in STM32 is a complex implementation with historical layers and poor documentation. The Cube stuff is not famous for being bug-free and comprehensive; it's mostly a "somehow it works" example rather than production-ready code (there are third party libraries out there, mostly paid, for a reason).
Do expect unsolvable cases. Not all mice are standard HID class, there are beasts out there containing a hub and several devices, some require vendor specific drivers. Cheap noname mice (and keyboards) generally tend to have higher chance to work than the brand stuff, which often tries to be fancy.
If you want to try some shortcuts - and you may be lucky - try to answer these questions: do the devices enumerate at all? If yes, are they HID class? Are they LS or FS? Did you research the known bugs in Cube (mainly on this forum, e.g. my January 14, 2019 post in https://community.st.com/s/question/0D50X00009XkZ4KSAV/usb-host especially the part which links to my other post https://community.st.com/s/question/0D50X00009yEQJZSA4/f4-otg-otghfir-handling ) and check whether they were fixed/fixed them yourself?
JW
2020-04-27 12:09 PM
The ST mouse example is simplistic and works only with older IBM, Microsoft and compatible mice.
When we did a project involving USB mice, we found that many new cheap mice even do not support "boot" (legacy) mode,
and many send reports in format that requires understanding the HID report descriptor (for example, X/Y coordinates can be 12 or 16 bits wide).
Also, as Jan noted, some mice are multifunction or have multiple reports - but from our experience, extra functions and collections can be ignored).
This is in addition to deficiencies in the "state machine" in ST examples.
If you do this as a commercial project, consider using a "serious" USB library.
-- pa
2020-04-28 09:31 AM
Thanks for your answers, Jan and Pavel. I did apply the linked patch, but it didn't help.
But last night, right before falling asleep, I had an idea: Wasn't the state I saw the final state in that state machine? And doesn't USBH_IDLE just mean that the USB device is not sending any data? Which makes sense, since I put the mouse upside down so that I can confirm the LED lights up.
And sure enough, once I actually start moving the mouse, I'm immediately in the callback. Tada!
Jan and Pavel, I absolutely don't doubt your assessment of the USB library. Even now, mouse #1 doesn't work at all, although it should. But for my little hobby project, this result now is good enough.
My apologies for this easy answer. :smiling_face_with_smiling_eyes:
2020-04-28 09:32 AM
(I keep selecting my own answers as best. -- Maybe I shouldn't post here so quickly. =) )
2020-04-28 11:36 AM
> I keep selecting my own answers as best. --
That's perfectly OK. We all learn from others' successes and failures.
> Maybe I shouldn't post here so quickly.
That's perfectly OK too; discussing the problem - even with teddy bear or rubber duck - is a perfectly valid debugging technique.
There are only two kinds of programmers - those who make errors, and those who don't admit it.
JW