USB Driver: HID Set Report / how to read data from ep0?

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

flabbergast
Posts: 71
Joined: Sat Aug 22, 2015 1:22 pm

Re: USB Driver: HID Set Report / how to read data from ep0?

Post by flabbergast »

So - I was checking the state of usbp->receiving in the debugger, breakpoints triggered in requests_hook_cb whenever there's a HOST2DEV SET_REPORT or SET_IDLE request received. Both are issued once during a keyboard enumeration, and then 2 SET_REPORTs in quick succession whenever I hit caps lock.

Now during the single SET_IDLE or SET_REPORT, usbp->receiving was 0 (as it should be), but for the 2 SET_REPORTs in quick succession, usbp->receiving was 1 in the callback.

Do I correctly understand that usbp->receiving is set by hardware stack events, or is it also a part of the state machine in hal/src/usb.c?

If yes, then the state machine in usb.c does not agree with the hardware side, because during the callback usbp->ep0state is USB_EP0_WAITING_SETUP.

Thanks for the help, and sorry to bug with such an obscure things...
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: USB Driver: HID Set Report / how to read data from ep0?

Post by Giovanni »

usbp->receiving is handled in software.

Note that EP0 is handled differently from other endpoints, you must not transmit or receive on it.

You need to hook usbp->config->requests_hook_cb and intercept message you need to decode. Exchanging data is done using usbSetupTransfer(), see the function default_handler() for examples.

Giovanni
flabbergast
Posts: 71
Joined: Sat Aug 22, 2015 1:22 pm

Re: USB Driver: HID Set Report / how to read data from ep0?

Post by flabbergast »

First of all, thanks for all the help, it kept me going!

I understand that ep0 is handled differently, and I did not explicitly send or receive data over it, except by using usbSetupTransfer in requests_hook_cb.

As you probably suspected, the error was in my code, and at a different place than I was looking for it.

The actual problem turned out to be that my requests_hook_cb did not respond properly to a SETUP / GET_REPORT request for the second interface (which appears from the host at the end of the enumeration procedure), i.e. it did not do usbSetupTransfer (this was missing in my code), and left handling to the default handler which of course did not react properly, since it's not its job. This led to the fact that usbp->receiving variable was never cleared (so it stayed at 1), and hence all the subsequent control transfers did not work properly (i.e. calls to usbStartReceiveI failed) - and the only control transfers that were happening after that point are actually just the SET_REPORT ones - which is where I detected the trouble.

Other transfers (like "typing" keys on the board) worked of course normally, which confused me.

If you are interested, here is the commit that solves my problem (3 lines added to usb_main.c), and here is the whole usb_requests_hook_cb function which is now hopefully correct.

Once more, thanks for the help - I think I understand the stack and LLD slightly better now, and hopefully I'll be able to proceed without bugging you so much.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: USB Driver: HID Set Report / how to read data from ep0?

Post by Giovanni »

NP, I didn't help you that much :)

Giovanni
Post Reply