Recently, while testing USB communication with a device that used libusb drivers, we had a choice of using Java or C++ as a platform for developing the required test programs. Instead, we decided to spend some time on our preferred platform, LabVIEW from National Instruments.
|Figure 1: EZ USB FX2LP used in ZTEX USB FPGA 1.15 board|
The bindings table on the libusb wesite lists all the different languages that can use libusb drivers. Note that LabVIEW is not listed among them. There are several postings on the LabVIEW discussion groups that suggest creating wrapper dlls around the libusb dll and creating a VISA driver for the USB devices. Each of these approaches have their merits in application, performance, robustness and capabilities. The approach that is suggested in this write up and we used is a quick and simple method to get your communications tested.
The development board shown in the picture isa development platform from Ztex with an on-board Spartan 6 FPGA and a Cypress FX2LP 8051 core microcontroller for USB connectivity. For the sake of testing the USB communication, the FX2LP is configured in Slave FIFO mode, with the FPGA acting as a master. The overall configuration of the FX2LP is as follows:
- EP2, BULK, IN, 512, Quad Buffered
- EP6, BULK, OUT, 512, Dual Buffered
- Internal CLK, 30 Mhz, AUTOIN, WORLDWIDE
Solution: Use the DotNET Binding provided at the libusb website or here within the .NET container in LabVIEW.
|Figure 2: Adding the .NET constructor to a VI|
- Download and install the LibUSBDotNET C# USB Library from any of the above links.
- Drop a .NET constructor on the block diagram of a LabVIEW VI. Double click on the constructor and choose the libusbdotnet.dll from your installation folder
- The sequence for establishing a USB data connection to FX2LP using the .NET library is as follows:
- Find the device using the UsbDeviceFinder Constructor and the unique product ID and Vendor ID.
- Open a connection using the static function call "OpenUSB Device" in the UsbDevice Class
- Select the default configuration and claim the default interface
- Use the reference wire from previous step to open and obtain a handle to a read endpoint (EP2)
- Use the reference wire from step 3 to open and obtain a handle to a write end point (EP6)
- Note: Steps 2 to 5 use static function calls in LabVIEW. Browsing through a .NET constructor node will not expose these methods for use. Instead, drop a "Invoke Method" block on your diagram, right-click and navigate to SlectCLass->.NET-> Browse. and choose LibUsbDotNet.IUsbDevice. (figure 3)
|Figure 3: Calling a static function in LabVIEW|
- The following figure lays down the whole sequence of initiating a data connection to a USB device using a .NET binding for libusb drivers.
|Figure 4: Sequence of execution to open read and write endpoints for a USB connection|
- The read endpoint is used to receive data from the USB device. The "IN" is always with respect to the host, which in this case is the computer running this LabVIEW VI. Similarly, the write endpoint is used to send data to the device. This is the "OUT" endpoint. This idea is depicted in the following figure
|Figure 5: Write to and Read from USB Device|
- A command does not use the EP6 write endpoint. To send a vendor command to the device, use the IUsbDevice reference to invoke the ControlTransfer method. The UsbSetupPacket constructor has to be called first to generate the setupPacket to be sentout as shown in figure 6. Note that the control command request number (66 in this case) should be configured in the FX2LP.
|Figure 6: Sending a control command to USB device|
- Following the best practices of any software application development, do not forget to close the opened references before the program terminates. (See Figure 7)
|Figure 7: Close USB Device references|
The scientists and engineers at Wakefield Engineering hope this article helps you in optimizing the development time for your usblib devices