cancel
Showing results for 
Search instead for 
Did you mean: 

USB HID driver fails right at end of enumeration

ANeed.1
Associate

Hi all,

I'm trying to write my own bare-metal USB HID driver for a personal project, on an STM32F042 microcontroller. The hardware is a custom PCB, with a USB Type-C in a USB 2.0 setup.

The project is a keyboard, but for now I've defined the device as a mouse HID device in the Interface descriptor. I've been able to successfully transmit all requested descriptors, set the given address, etc. Right at the end of HID enumeration the host sends a Get Descriptor request for the Report descriptor, and an HID-specific request of SET_IDLE. I'm getting both of these, and am expecting the host to start sending Get Report requests to EP0, at which point I would send the report from EP1 - Interrupt IN (or NAK if there is no change in data). But instead of a Get Report, the host immediately resets the device, enumerates again then resets, and so on.

I'm doing the testing on a Debian machine. This is the output of `tail -f /var/log/syslog`:

0693W000005C0aIQAS.png 

As you can see, the host gets the string descriptors, and identifies the device as an HID Mouse device. But I resets right at the end (I'm almost positive the mtp-probe stuff has no effect).

Here is the output from the serial debug output:

0693W000005C0baQAC.pngThe format of the printouts is:

  • `>` - the start of a USB interrupt
  • `EPn` - the EP that the interrupt is related to
  • `IN`/`OUT` - direction of successful EP transaction (`OUT` can also mean both TX/RX)
  • The next bit shows the reason for the interrupt, usually `CTR` (correct transfer) or `RESET`
  • In the case of a `CTR`, `RX` indicates the EP had a correct `OUT`/`SETUP`transaction, and `TX` an`IN` transaction.
  • Then `SETUP` if the transaction was a `SETUP`. The string of numbers is the contents of the `SETUP` request. Then, the description of the request (Get Descriptor, Set Address, etc.), followed by the descriptor in the case of Get Descriptor.

We can see the device proceed through enumeration, get to the Get Descriptor, Report request then immediately `RESET`.

I've been stuck at this stage, trying to debug, for probably 20-30 hours at this point. I just can't seem to figure it out. Software USB analyzers aren't any help since I'm not getting past enumeration. I'm trying to prevent the need to buy a $400 Beagle 12. Perhaps there is a way to get Linux to spit more information about why the HID driver is resetting the device? Has anyone encountered this before?

My software (and hardware) can be found at https://github.com/anthonyneedles/QAZ

The relevant files are src/usb.c, src/usb.h and src/usb_descriptors.h

Thanks for any help that I can get, this has been frustrating to debug.

3 REPLIES 3
Pavel A.
Evangelist III

> Perhaps there is a way to get Linux to spit more information about why the HID driver is resetting the device?

Yes definitely there is. Linux USB host stack is opensource, like the rest of it, so you're free to insert more debug prints where it takes the decision to reset.

> I'm trying to prevent the need to buy a $400 Beagle 12.

So all this is because you want to make a keyboard cheaply? You have earned an valuable experience already: developer's time is expensive too.

-- pa

Try to imitate an existing HID device, i.e. use the entire set of descriptors from a real mouse or keyboard.

JW

The last log record was CTR TX. Was it a control request?

-- pa