Discussion:
Nugget: 2 of n : USB Control transfers using VISA
(too old to reply)
Intaris
2008-08-05 15:10:09 UTC
Permalink
For USB
Logging, I personally have found the (non-free) ?<a href="http://www.hhdsoftware.com/Products/home/usb-monitor.html" target="_blank">Device
Monitoring Studio</a>? (which seems to have been renamed to ?USB
Monitor?) to be of great help. Other, free programs are available
such as ?<a href="http://sourceforge.net/projects/usbsnoop/" target="_blank">Snoopy
Pro</a>?. These programs sit between the Operating system and the
device driver and records all communication.



In
the examples I will work through, I had the luxury of having a
pre-existing working driver for my target device which I could
already use in LabVIEW. This enabled me to use a USB logging
software to see exactly what was being sent to the device and what
was coming back. Since I could already control the device via
LabVIEW (Via DLL) I was relatively quickly able to pin-point which
commands were tied to which functions.


A
quick mention to the ?why? of this action if I already had a
driver. Apart from ?because I could?, I wanted the software to
run under Linux. The supplied DLL wouldn't do that..


A
sample log of a basic communication may look like the example shown
below. Entries 000050 and 000051 belong to a standard
request defined within the USB Specification used to get the Device
Descriptor (Table 9-3 on Page 250). The second pair (000052
and 000053) are custom device-specific requests which were the
target of my investigations. All data needed to implement this call
through VISA is presented in an easy-to-understand form.



000050:
Get Descriptor Request (DOWN), 09.11.2007 14:35:32.156 +33.156

Descriptor
Type: Device

Descriptor
Index: 0x0

Transfer
Buffer Size: 0x12 bytes




000051:
Control Transfer (UP), 09.11.2007 14:35:36.781 +4.625. Status:
0x00000000

Pipe
Handle: 0x88df4020

12
01 00 01 00 00 00 40 61 06 00 29 00 00 00 00
***@a..)....

00
01
..

Setup
Packet

80
06 00 01 00 00 12 00 .......

Recipient:
Device

Request
Type: Standard

Direction:
Device-&gt;Host

Request:
0x6 (GET_DESCRIPTOR)

Value:
0x100

Index:
0x0

Length:
0x12




000052:
Vendor-Specific Request (DOWN), 09.11.2007 14:35:36.781 +0.0

Destination:
Other

Reserved
Bits: 0

Request:
0x4

Value:
0x1c8

Get
0x8 bytes from the device




000053:
Control Transfer (UP), 09.11.2007 14:35:36.781 +0.0. Status:
0x00000000

Pipe
Handle: 0x88df4020

62
31 30 34 37 31 30 32
b1047102

Setup
Packet

C3
04 C8 01 00 00 08 00 Ã.È.....

Recipient:
Other

Request
Type: Vendor

Direction:
Device-&gt;Host

Request:
0x4 (Unknown)

Value:
0x1c8

Index:
0x0

Length:
0x8


The
data packets (in this case Device to Host) are shown in italicised
bold font. The setup Packet is not of interest for us at the
moment as VISA takes care of this when we give the correct
transmission parameters. The USB transmission parameters used to
initiate this transfer is shown at the bottom of each entry
(Recipient, Request type and so on). These seven parameters are
detailed enough for us to be able to implement the functionality we
require.



-Note-

I
personally got stuck at this point for quite a while trying to
implement this in LabVIEW. The information IS all in the USB
specification, but it required a lot of trial and error on my part to
get it working. I want to help others avoid thie trial and error
part by sharing with the community how I got this done.

-End
Note-.
Intaris
2008-08-05 15:40:06 UTC
Permalink
The key to understanding what these
seven values are is listed in Table 9-2 of Paragraph 9.3 of the USB
Specification document, reproduced here (hoping I don't get sued for
Copyright infringement).


Examining
the USB Logger output and Table 9-2 we can find all seven of our USB
parameters. Three of the parameters are actually bitmapped into a
single value ?bmRequestType?. The Direction of the request
(Command to device or request from device), What type of request it
is (Standard, Class, Vendor) and the intended recipient of the packet
(Device, Interface, Endpoint or Other). The other four parameters
are passed individually.

<img src="Loading Image...">

The
second entry in the table is the ?bRequest? entry. Table 9-3 of
the USB Specification lists several standard request types. Tables
9_4 and 9_5 are also required in order to fully understand what is
going on here.

<img src="Loading Image...">

Table
9_4 lists the Byte values for each of the standard bRequest types.
In the case of the bRequest Types ?GET_DESCRIPTOR? or
?SET_DESCRIPTOR? an additional value is required as to what TYPE
of Descriptor is involved. These values are then listed in Table
9_5.<img src="Loading Image...">


<img src="Loading Image...">



We now have enough Information to
understand what the request listed in the USB log above is actually
for.


The
first three entries;




Recipient:
Device

Request
Type: Standard

Direction:
Device-&gt;Host


tell
us that we are sending a data packet to the device, making a request
for information from the device and that the request is a Standard
request.


The
following line


Request:
0x6 (GET_DESCRIPTOR)


tells
us that the standard Request being executed is a request for a
Descriptor. Looking at the entry in Table 9_3 for the Request
?GET_DESCRIPTOR? tells us what the last three values mean:


Value:
0x100

Index:
0x0

Length:
0x12


Value
represents ?Descriptor Type and Descriptor Index?.
The first 8 Bytes correspond to the value 1, which from Table 9_5
tells us is the DEVICE Descriptor. The second Byte is zero, telling
us that we want the Descriptor at index zero (Some Devices have
multiple instances of a certain type of descriptor).


Index
represents ?Zero or Language ID?. Since this value
is zero, we are requesting the default descriptor. Since Descriptors
may contain text which is language-dependent, a device can store many
different descriptors for different languages if required.


Length
represents the ?Descriptor Length?. Although we
are required to enter a value here, it can often happen that the
returned descriptor is longer than the requested length. Since the
length of the actual descriptor is contained within the header for
the actual descriptor (18 Bytes, 0x12 in Hexadecimal Paragraph
9.6.1, Table 9_8 on Page 261 and onwards of the USB Specification),
an initial request for 18 Bytes is normal which can then be followed
up with a request for the corrent length of descriptor.


This
is jsut a single example of a command which according to the USB
specification EVERY USB Device should respond to. As such it can be
used to test any early attempts to get USB communication up and
running.




I
have also implemented a couple of simple enums for the values of the
Standard Request Codes and the Descriptor Types as outlined in Tables
9_4 and 9_5.


Now
that we know what the various entries in our USB Log are for, we can
move over to implementing some communication in LabVIEW.
Message Edited by Intaris on 08-05-2008 10:18 AM


Table 9-4.png:
http://forums.ni.com/attachments/ni/170/346748/1/Table 9-4.png


Table 9-2.png:
http://forums.ni.com/attachments/ni/170/346748/2/Table 9-2.png


Table 9-3.pn
Intaris
2008-08-05 15:40:06 UTC
Permalink
If we now look at the Connection pane
of the respective VISA function we see all these values present also.

<img src="Loading Image...">



-
Note - I was initially very confused with the nomenclature ?Control
IN? and ?Control OUT?. I thought it counter-intuitive that the
function for sending requests to a device is called ?VISA USB
Control In? and not ?Out?. An example from NI
finally sorted me out (Which I unfortunately cannot locate at the
moment).

-
End of Note -


Assuming
we have implemented our RAW driver as outlined in the <a href="http://zone.ni.com/devzone/cda/tut/p/id/4478" target="_blank">NI
tutorial</a> above, we should be able to choose our device from a
VISA control. In the examples shown below, I have connected a second
mouse (Microsoft 2-Button mouse with scroll wheel) to my PC and have
run the Device driver wizard for VISA. Once this is completed, the
device is visible whenever I use a VISA control set to USB devices.


<img src="Loading Image...">
Once
we have done this, any devices configured for USB RAW communication
via the VISA Driver wizard should be visible.


<img src="Loading Image...">


The
first device shown here is a USB Spectrometer I have been
communicating with over USB, the second is the MS-Mouse (Vendor ID
0x045E, Product ID 0x0084).


We
can then use the VISA Open just like any other VISA resource to open
a handle to the device.


Now
all we need to do is wire up our request to the device for a device
descriptor and we're basically done.


The
picture below shows the values needed for a simple device descriptor
request using the Vis and controls I have implemented.


<img src="Loading Image...">


We
can see that we are doing basically the very same request as
originally recorded using the USB Logger program mentioned at the
beginning.


As
a reminder:


Recipient:
Device

Request
Type: Standard

Direction:
Device-&gt;Host

Request:
0x6 (GET_DESCRIPTOR)

Value:
0x100

Index:
0x0

Length:
0x12


The
?Index? value is not shown because the default value for the
?VISA USB Control In? VI is already zero.


The
result of this communication should now be available at the output
terminal of our VISA Control In VI. In order to format this into
something we might understand, the following code is used:






The
Constant ?USB _bDescriptor Type 1? is a Typedef representing the
data structure of the Device Descriptor as outlined in Table 9_8 of
Paragraph 9.6.1 of the USB Specification. The first two Bytes are
ignored as they contain information not required by the conversion
(Descriptor size and bDescriptor Type). We could incorporate these
two Bytes into our Typedef and do away with this step.


In
order to convert the received 16-bit values into a LV-Conform format,
we perform a Byte Swap on the values ?bcdUSB?, idVendor? and
?idProduct?.


In
the case of the MS Mouse, we get a data structure as follows:


<img src="Loading Image...">


We
see the Vendor ID (0x045E) and the Product ID (0x0084) are contained
within the Device Descriptor. This is actually the method used by
the OS to determine what has actually been attached to the computer.


We
also see some other information such as max Packet size (8).


Using
this nugget, we have enough information to request other device
information also, such as the ?Standard Configuration Decsriptor?
from the device. This is already implemented in one of the Vis
attached.


The
functionality highlighted in the USB Logger information at the
beginning of this nugget can now easily be implemented in LabVIEW.
The devi
Intaris
2008-08-05 15:40:07 UTC
Permalink
I forgot a picture in the last post : the result of formatting the device descriptor:<img src="Loading Image..."> I haven't gone into depth about the actual data structure of the varying descriptors in the USB spec.They can be found in Section 9.6 (Page 261 to 274) in the USB Spec.16-Bit numbers must be byte-swapped before LV can work with them.Shane.Message Edited by Intaris on 08-05-2008 10:34 AMMessage Edited by Intaris on 08-05-2008 10:35 AM


GET DEVICE DESCRIPTOR MS Mouse.png:
http://forums.ni.com/attachments/ni/170/346752/1/GET DEVICE DESCRIPTOR MS Mouse.png
tst
2008-08-05 18:40:05 UTC
Permalink
You almost make me WANT to do USB communication. :smileyvery-happy:
At least I know that when I do, I'll have where to start.
JoeLabView
2008-08-05 19:40:07 UTC
Permalink
This is excellent timing...&nbsp;
I am starting a USB project..&nbsp; Hope it's okay to ask "general" questions in this thread.&nbsp; I'll start new thread for specific ones..
Great Nugget! Many Thanks!
R
&nbsp;
Intaris
2008-08-06 07:40:05 UTC
Permalink
@Tst, @JoeLabViewGlad to help.Re: Questions, fire away.&nbsp; I think it's important to have general questions in the nugget thread, because I'm only one person with limited time, so I've certainly not covered everything of interest on the topic.&nbsp; That way, people reading the nugget also get the extra info for "free"***@JoeLabView: Congrats on your Zeal.Message Edited by Intaris on 08-06-2008 02:36 AM
Ben
2008-08-06 11:10:06 UTC
Permalink
Thanks Shane!
I will not be able to give this serious read today since it requires more than the 9 minutes I have available today. :smileysurprised:
Ben
dan_u
2008-08-06 11:40:07 UTC
Permalink
This insight to USB using VISA is just great! Thanks a lot for sharing.Too bad I don't have a project right now where I could use the information in this nugget :smileywink:Daniel
Ben
2008-08-08 13:10:07 UTC
Permalink
Hi Shane,
Well i cam back and read in detail. Al I am capable of saying at this time is that this is a Nugget who's day is yet to come.&nbsp;There will come a time when we point at this Nugget as often as we cite the "Simple Serial Read" example.
Give us time. We'll catch-up to you.&nbsp; :smileywink:
Ben

Loading...