Dinosaur wrote:Can I do a .DoBulk with an Interface or is it always with a Device ?
I am getting zero bytes transferred, and a Stalled error. (with an Interface)
I'm not sure what you mean by "with an Interface" or "with a Device". Requests actually get sent to a Device and an End Point. By selecting an End Point (other than 0), you are indirectly selecting an Interface. The descriptors are laid out in a heirarchial fashion -- the U-HID descriptors were like this:
- Code: Select all
Device
Configuration 1
Interface 0, Alt Interface 0 (I/O)
HID Report
End Point 1, In, Interrupt, Max Pkt Size 8, Max Poll Interval 10 ms
Interface 1, Alt Interface 0 (Joystick/GamePad)
HID Report
End Point 2, In, Interrupt, Max Pkt Size 20, Max Poll Interval 10 ms
Interface 3, Alt Interface 0 (Keyboard)
HID Report
End Point 3, In, Interrupt, Max Pkt Size 16, Max Poll Interval 10 ms
Interface 4, Alt Interface 0 (Joystick)
HID Report
End Point 4, In, Interrupt, Max Pkt Size 8, Max Poll Interval 10 ms
There is an "undeclared" End Point 0 that belongs to the entire Device (and consequently all Interfaces) that Control Requests get sent to. Because End Point 0 belongs to the entire Device, a Control request may need an Index number depending on who the Recipient of the Control Request is. The Recipient of a Control Request can be a Device, Interface, End Point, or Other (that is part of what's embedded in the first byte of the Control Request, the Request Type). If the Recipient is an Interface or an End Point, the Index field of the Control Request must declare which Interface or End Point it is for.
Bulk, Interrupt, and Isochronous requests are directed at a specific Interface, and the Interface is selected implicitly by sending the Request to an End Point other than 0. A non-zero End Point always belongs exclusively to a specific Interface.
Dinosaur wrote:How does one know how many bytes a Device or Interface is capable of sending with a .DoBulk ?
It depends on the type of Interface. For example, a flash disk, like all mass storage devices, always transfers one sector (usually 512 bytes) at a time. In USB, though, the absolute maximum number of bytes that can be transferred by a Bulk End Point is 64. So to transfer a single 512 byte sector, USBUHCIL will divide the request into 8 separate bulk packets.
For HID devices like you're using, it is a combination of the Max Packet Size declared in the End Point Descriptor, and what is stored in the HID Report Descriptor that determines the number of bytes. The HID Report Descriptor for the I/O Interface (Interface 0) says you have 32 bits (4 bytes) of input (buttons) and 32 bits of output (LEDs).
In most HID devices I've seen, the total number of bytes declared in the End Point descriptor exactly matches the number of bytes described in the HID Report Descriptor, so I'm kind of surprised to see a max packet size of 8 for End Point 1 (I would expect it to be 4). The Stall error you're getting for the Bulk Request indicates that the Device doesn't like something about the Request, which could be somehow related to the number of bytes you're requesting (4 vs. 8). What's supposed to happen if you request too few bytes is the device will just send the number of bytes you requested, and if you request too many you will get a Short Packet error. It's not
supposed to Stall if you request the wrong number of bytes, but a lot of devices don't do what they're supposed to.
Unfortunately, the Stall error is the only way a Device has to tell you that it doesn't like something about a Request, but has no way of telling you exactly what it doesn't like about it. You're just supposed to "know" how to fix things and send it again.
Dinosaur wrote:Do I need the spec of a device to know what each byte of a .DoBulk means ?
For an HID device, that's in the HID Report Descriptor, and it actually goes down the bit level (not just the byte level).