doynax
doynax

Reputation: 4455

Faster USB HID output

I'm attempting to speed up a rather sluggish bootloader. Currently I'm sending data on a single USB HID output endpoint, and as it's a low-speed device I'm apparently limited to one 8-byte packet per 10 ms interval for a whopping 800 bytes/second.

Is it possible to increase the reporting frequency somehow? Or to use multiple output endpoints in a single interface or as part of a composite device? Or perhaps to abuse the control endpoint to send additional data?

Better compression is always an alternative I suppose, but it's an area of diminishing returns, and redesigning the hardware to allow full-speed USB isn't really an option.

For the record I'd be happy with a Windows-only solution.

Upvotes: 2

Views: 7051

Answers (5)

th_in_gs
th_in_gs

Reputation: 549

I’m not sure about Windows, but most hosts will service an interrupt endpoint faster than what the spec requires - even down to 2ms/interrupt. Try changing your configuration descriptor to ask for a 2ms rate.

I believe this is actually allowed by the spec - the rate is a request that the host can comply with or not (I’ve read, for example, that some hosts will poll at 8ms even if 10ms is requested). You just can’t rely on any random host you plug into complying with your rate.

Edit: Hmm, no, the spec clearly says “ An endpoint for an interrupt pipe specifies its desired bus access period. […] Low-speed endpoints are limited to specifying only 10 ms to 255 ms.” Nevertheless, this has worked for me in practice…

Upvotes: 0

doynax
doynax

Reputation: 4455

I was able to speed up the upload by orders of magnitude by using SET_REPORT requests on the control endpoint, instead of declaring a separate interrupt out endpoint. That way you get all of the bandwidth available for control transfers.

Also using a larger report split into multiple segments helped reduce the number of SETUP packets needed.

Upvotes: 2

Roman Starkov
Roman Starkov

Reputation: 61462

The actual limit is 8 bytes every 10ms for low-speed devices, and 64 bytes every 1ms for high-speed devices, per interrupt-based endpoint.

So it seems that the first thing to try is switching to high-speed mode, if the hardware supports it. The next thing on the list is using multiple endpoints. If you really want to get the highest possible transfer rate, the HID class is a bad choice.

Upvotes: 0

Turbo J
Turbo J

Reputation: 7691

Or perhaps to abuse the control endpoint to send additional data?

You can use "Vendor specific requests" for that. The TI TUSB3410 Chip works that way AFAIK. Many USB stacks have the hooks for them already in place.

This requires a driver or libusb on the host side, however.

Upvotes: 2

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137438

Who says you are limited to an 8-byte packet per 10ms? I don't know the exact numbers off the top of my head, but I know you can send larger packets than that. I did an HID device and was using 64-byte packets. I think I could go larger, but that limit is probably hardware-specific. What hardware are you using?

Also, have you consulted USB in a NutShell?

Upvotes: 1

Related Questions