Ports and Interfaces > USB

USB Communication protocol

(1/2) > >>

Limited_Atonement:
I read much of the chapter 9 standard, and I thought I got it, but some well-respected code I also read seems to disagree with what I see in the standard.  In Table 9-2 (p248 in section 9.3), we see bmRequestType which specifies (among other things) Host-to-device or Device-to-host.  Furthermore, bRequest is a particular request being made of a device "when the [bmRequestType (they really should add this to the standard)] bits are reset to zero".

The code I read recently is the WinUSB firmware and Windows code at http://www.lvr.com/winusb.htm.  It is in cahoots with the USB code from Microchip.  The former seems to use the bRequest field to designate device-to-host or vice versa.  In the firmware, concerning bmRequestType, vide
"usb_device.c" line 1314
"usb_ch9.h" lines 391-392
    et allii...
and for bRequest, see
"main.c" lines 1356-1375
In the host-side application (C#), see
"winusbdevice.cs" line 85 and line 157
(I think that's right...I may have modified this file and got the line numbers off, anyway, it's in the methods "Do_Control_Write_Transfer();" and "Do_Control_Read_Transfer();" and the code says, "setupPacket.Request = 2;" and "setupPacket.Request = 1;".


Please let me know what you think, or if I'm reading this wrong.  What I would like to do is define some custom commands using the bRequest (say, request some action from the device using this parameter), and use the wValue and wIndex as four more bytes of parameter.  If bRequest is the way to get the device to send data vs expect data, then what does the upper bit of bmRequestType mean?  How can I use more than the bottom two bits of bRequest?  Should I just divide the thing in half, and have the first 128 commands be various read commands, and the second 128 be various write commands or something like that?

Thanks for your time.

Jan Axelson:
Bit 7 of bmRequest specifies the direction of the Data stage's data packet.

bRequest identifies the request.

Typically, the direction of a request's Data stage is always IN or always OUT. So once the device has identified the request, it knows the direction of the Data stage. bmRequest is a way to provide this information without having to know what the request is. For example, if a device ACKs a Setup packet and then determines that the request isn't supported, bmRequest tells the device whether to expect an IN or OUT Data packet to STALL.

For vendor-defined control requests, you can assign any bRequest value to any request you define and you can define wIndex and wValue for the request any way you want.

Jan

Limited_Atonement:
So, in the example that I cited, bRequest is being used redundantly in the custom protocol?  Rather than using bRequest == 1 means device-to-host (or vice versa), it is equally valid (perhaps more valid) to just check bit seven of bmRequestType, right?

Thanks for your answer.

Jan Axelson:
bRequest = 1 means the host is sending control request #1 as defined by the USB spec or a class or vendor driver, depending on where the request is directed. If request #1 has a defined direction, device firmware might not bother checking the direction bit in bmRequestType.

If a driver supports only two requests, one in each direction, I suppose device firmware could check only bmRequest to find out which request the host has sent. That would cause problems if the software is ever updated to support more requests, however.

Jan

Bret:
There are a couple of different "levels" of concern here.  One is how the device responds to a control request, and the other is how the request is issued from the software that is controlling the device to the host driver, which is responsible for processing the transaction.

The host driver needs to know whether the control request has a data stage or not, and if so, which direction and how many bytes the data stage is supposed to have.  Particularly with a vendor-specific control request, there is no way the host driver will know this "automatically".  Either there must be an external protocol that defines the direction and size of the data stage to the host driver (in addition to the memory address where the data is to be stored or retrieved), or bmRequestType AND wLength MUST be complete and correct in the request, even if the device itself doesn't care (because it can determine what it needs solely from bRequest).  A custom device/protocol can do pretty much anything it wants to with bRequest, wValue, and wIndex, but bmRequestType and wLength have to work just like the specs say or you'll get yourself into trouble.

Navigation

[0] Message Index

[#] Next page

Go to full version