cancel
Showing results for 
Search instead for 
Did you mean: 

Whats the problem with USB Host HID

HSh..1
Associate II

Hello.

I have problem using STM32 USB Host HID. I`m stuck in the USBH_Process() function in usbh_core.c, or its better to say stuck in USBH_HID_Process() function in usbh_hid.c file. I am trying to connect a USB keyboard to my own designed stm32f407zgt6 board, code is generated through STM32CubeMX v5.2.1 with package software v1.24.2 and I work with IAR IDE v8. I`ve made a project just same as (https://www.youtube.com/watch?v=Co4ChSgVSek), but with different pins pack, every time I connect the keyboard the MCU gets the descriptors, but it never gets data from keyboard. I only used one keyboard model, also searched a lot about the problem. I`ve tried what pavel.a said in (https://community.st.com/s/question/0D50X00009XkZ4KSAV/usb-host), nothing changed, when I printf() the logs on uart, at first I get:

0693W00000BZsMjQAL.png 

after some "HOST_ENUMERATION"s it recognizes keyboard:

0693W00000BZsMGQA1.png 

and at last the process goes on like the:

0693W00000BZsNhQAL.png 

for ever "HOST_CLASS..." from USBH_Process() fuction in usbh_core.c and then "HID_GET_DATA" from USBH_HID_Process() function in usbh_hid.c.

Some place in USBH_HID_Process() function in the "HID_GET_DATA:" part of the switch_case, there is a line "HID_Handle->state = HID_POLL;", but right after this line the "HID_Handle->state" equals to "HID_GET_DATA" (see the forth picture) again very automatically.

0693W00000BZsSYQA1.png 

So the user defined void USBH_HID_EventCallback(USBH_HandleTypeDef *phost) function is never called to read the data.

Somebody please tell me whats going on here? I`ve also seen from my searchs that there would be a problem with boot type and request type of keyboards.

5 REPLIES 5

Hello @HSh..1​ ,

Take a look at the following training , it would be helpful.

Otherwise, Take a look at the example provided under our F4 Firmware package ( path: Projects\STM32F446ZE-Nucleo\Applications\USB_Host\HID_Standalone )

I hope this help you.

BeST Regards,

Walid

JMarq.1
Associate III

Hi, I was facing the same issue. My main loop (firmware is bare-metal programming, no OS) was lasting more than 18ms, whereas USB keyboard requires 10ms polling time (bInterval=0x0A in Endpoint Descriptor). So, as I was calling MX_USB_HOST_Process() inside the loop too late, the routine USBH_HID_SOFProcess() on HID_POLL state executed:

if (HID_Handle->state == HID_POLL)

{

if ((phost->Timer - HID_Handle->timer) >= HID_Handle->poll)

{

HID_Handle->state = HID_GET_DATA;

}

}

changing HID_Handle->state from HID_POLL to HID_GET_DATA all the time, being ignored the answer received from any PID IN request, although using a logic analyzer I see that the keyboard indeed answered them at 18ms polling interval.

To solve it, I changed if ((phost->Timer - HID_Handle->timer) >= 50) to accept a 50ms polling time for the time being, and now working in polling the keyboard using a timer interrupt. I'm not sure to being able to reduce main loop under 10ms or 8ms as preferred because HID standard mentions that usually keyboards are poll at 125Hz (8ms).

In conclusion, be aware that if you are calling MX_USB_HOST_Process() (i.e. USBH_Process(&hUsbHostFS)) later than the required poll interval specified by the USB keyboard in its endpoint descriptor, HAL USB host library will not trigger USBH_HID_EventCallback function.

Thank you @JMarq.1

I was looking at the F411E-DISCO USB Host example HID code and your point about servicing MX_USB_HOST_Process() in the main application loop often enough is important. I also noticed that if the HID device wanted bInterval of less than 10ms, then that was upward adjusted to 10ms. Nothing faster was offered by default.  Obviously this isn't intended for a gaming keyboard, nor should it be. The OTG_FS_IRQHandler() runs for about 4us every 1ms [SOF handling]. For the demo, the USBH_HID_EventCallback() only runs when there is new data (a boot protocol style keyboard report for instance).  The parsing of the keyboard report is lacking since it only ever looks at the first byte of six for key data. Again, this is probably not a huge issue for an HID device that isn't actually a keyboard (say, a card reader of some sort). Pushing the bInterval higher forces the buffering duty back onto the HID device somewhat, so make sure you do your testing to make sure the HID device isn't dropping data. As an example of "large data", a card reader that accepts QR codes can scan and send a code that has hundreds of bytes of data. Fortunately most such devices are also using an Arm Cortex MCU as well and have sufficient memory to do just that.

@Grant Bt Indeed, the HID examples in the ST Cube packages are very basic and users are expected to improve them for their real applications. If you wish to share your own demo application for higher performance or better reaction time, you are welcome.

 

I might do that. In my case performance won't be an issue, but the handling of the boot protocol key report only using one byte might be. I plan to allow for the "entire" ASCII character set from at least 0x00 to 0x7F to be available (by allowing the use of Shift and Ctrl), so when I get there I will fix-up the key report parsing as well.