LibUsbDotNet 2.2.8
Read Isochronous (Async Transfer Queue)
|
To use this example with the benchmark firmware, ensure IS_BENCHMARK_DEVICE is defined at the top of the source file.
-
Opens a USB device by vendor and product id.
-
Opens a UsbEndpointReader class for reading.
-
Creates a UsbTransferQueue class.
-
Submits transfers until TRANFER_MAX_OUTSTANDING_IO is reached then waits for the oldest transfer to complete.
-
Displays information on the completed transfer and repeats the above step until TRANSFER_COUNT is reached.
#define IS_BENCHMARK_DEVICE using System; using LibUsbDotNet; using LibUsbDotNet.Info; using LibUsbDotNet.Main; namespace Examples { internal class ReadIsochronous { #region SET YOUR USB Vendor and Product ID! public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(1234, 1); #endregion /// <summary>Use the first read endpoint</summary> public static readonly byte TRANFER_ENDPOINT = UsbConstants.ENDPOINT_DIR_MASK; /// <summary>Number of transfers to sumbit before waiting begins</summary> public static readonly int TRANFER_MAX_OUTSTANDING_IO = 3; /// <summary>Number of transfers before terminating the test</summary> public static readonly int TRANSFER_COUNT = 30; /// <summary>Size of each transfer</summary> public static int TRANFER_SIZE = 4096; private static DateTime mStartTime = DateTime.MinValue; private static double mTotalBytes = 0.0; private static int mTransferCount = 0; public static UsbDevice MyUsbDevice; public static void Main(string[] args) { ErrorCode ec = ErrorCode.None; try { // Find and open the usb device. UsbRegDeviceList regList = UsbDevice.AllDevices.FindAll(MyUsbFinder); if (regList.Count == 0) throw new Exception("Device Not Found."); UsbInterfaceInfo usbInterfaceInfo = null; UsbEndpointInfo usbEndpointInfo = null; // Look through all conected devices with this vid and pid until // one is found that has and and endpoint that matches TRANFER_ENDPOINT. // foreach (UsbRegistry regDevice in regList) { if (regDevice.Open(out MyUsbDevice)) { if (MyUsbDevice.Configs.Count > 0) { // if TRANFER_ENDPOINT is 0x80 or 0x00, LookupEndpointInfo will return the // first read or write (respectively). if (UsbEndpointBase.LookupEndpointInfo(MyUsbDevice.Configs[0],TRANFER_ENDPOINT, out usbInterfaceInfo, out usbEndpointInfo)) break; MyUsbDevice.Close(); MyUsbDevice = null; } } } // If the device is open and ready if (MyUsbDevice == null) throw new Exception("Device Not Found."); // If this is a "whole" usb device (libusb-win32, linux libusb-1.0) // it exposes an IUsbDevice interface. If not (WinUSB) the // 'wholeUsbDevice' variable will be null indicating this is // an interface of a device; it does not require or support // configuration and interface selection. IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice; if (!ReferenceEquals(wholeUsbDevice, null)) { // This is a "whole" USB device. Before it can be used, // the desired configuration and interface must be selected. // Select config #1 wholeUsbDevice.SetConfiguration(1); // Claim interface #0. wholeUsbDevice.ClaimInterface(usbInterfaceInfo.Descriptor.InterfaceID); } // open read endpoint. UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader( (ReadEndpointID) usbEndpointInfo.Descriptor.EndpointID, 0, (EndpointType) (usbEndpointInfo.Descriptor.Attributes & 0x3)); if (ReferenceEquals(reader, null)) { throw new Exception("Failed locating read endpoint."); } reader.Reset(); // The benchmark device firmware works with this example but it must be put into PC read mode. #if IS_BENCHMARK_DEVICE int transferred; byte[] ctrlData=new byte[1]; UsbSetupPacket setTestTypePacket = new UsbSetupPacket((byte) (UsbCtrlFlags.Direction_In | UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.RequestType_Vendor), 0x0E,0x01,usbInterfaceInfo.Descriptor.InterfaceID,1); MyUsbDevice.ControlTransfer(ref setTestTypePacket,ctrlData, 1, out transferred); #endif TRANFER_SIZE -= (TRANFER_SIZE%usbEndpointInfo.Descriptor.MaxPacketSize); UsbTransferQueue transferQeue = new UsbTransferQueue(reader, TRANFER_MAX_OUTSTANDING_IO, TRANFER_SIZE, 5000, usbEndpointInfo.Descriptor.MaxPacketSize); do { UsbTransferQueue.Handle handle; // Begin submitting transfers until TRANFER_MAX_OUTSTANDING_IO has benn reached. // then wait for the oldest outstanding transfer to complete. // ec = transferQeue.Transfer(out handle); if (ec != ErrorCode.Success) throw new Exception("Failed getting async result"); // Show some information on the completed transfer. showTransfer(handle, mTransferCount); } while (mTransferCount++ < TRANSFER_COUNT); // Cancels any oustanding transfers and free's the transfer queue handles. // NOTE: A transfer queue can be reused after it's freed. transferQeue.Free(); Console.WriteLine("\r\nDone!\r\n"); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine((ec != ErrorCode.None ? ec + ":" : String.Empty) + ex.Message); } finally { if (MyUsbDevice != null) { if (MyUsbDevice.IsOpen) { // If this is a "whole" usb device (libusb-win32, linux libusb-1.0) // it exposes an IUsbDevice interface. If not (WinUSB) the // 'wholeUsbDevice' variable will be null indicating this is // an interface of a device; it does not require or support // configuration and interface selection. IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice; if (!ReferenceEquals(wholeUsbDevice, null)) { // Release interface #0. wholeUsbDevice.ReleaseInterface(0); } MyUsbDevice.Close(); } MyUsbDevice = null; } // Wait for user input.. Console.ReadKey(); // Free usb resources UsbDevice.Exit(); } } private static void showTransfer(UsbTransferQueue.Handle handle, int transferIndex) { if (mStartTime == DateTime.MinValue) { mStartTime = DateTime.Now; Console.WriteLine("Synchronizing.."); return; } mTotalBytes += handle.Transferred; double bytesSec = mTotalBytes/(DateTime.Now - mStartTime).TotalSeconds; Console.WriteLine("#{0} complete. {1} bytes/sec ({2} bytes) Data[1]={3:X2}", transferIndex, Math.Round(bytesSec, 2), handle.Transferred, handle.Data[1]); } } }
#Define IS_BENCHMARK_DEVICE Imports System Imports LibUsbDotNet Imports LibUsbDotNet.Info Imports LibUsbDotNet.Main Namespace Examples Friend Class ReadIsochronous #Region "SET YOUR USB Vendor and Product ID!" Public Shared MyUsbFinder As New UsbDeviceFinder(1234, 1) #End Region ''' <summary>Use the first read endpoint</summary> Public Shared ReadOnly TRANFER_ENDPOINT As Byte = UsbConstants.ENDPOINT_DIR_MASK ''' <summary>Number of transfers to sumbit before waiting begins</summary> Public Shared ReadOnly TRANFER_MAX_OUTSTANDING_IO As Integer = 3 ''' <summary>Number of transfers before terminating the test</summary> Public Shared ReadOnly TRANSFER_COUNT As Integer = 30 ''' <summary>Size of each transfer</summary> Public Shared TRANFER_SIZE As Integer = 4096 Private Shared mStartTime As DateTime = DateTime.MinValue Private Shared mTotalBytes As Double = 0 Private Shared mTransferCount As Integer = 0 Public Shared MyUsbDevice As UsbDevice Public Shared Sub Main(args As String()) Dim ec As ErrorCode = ErrorCode.None Try ' Find and open the usb device. Dim regList As UsbRegDeviceList = UsbDevice.AllDevices.FindAll(MyUsbFinder) If regList.Count = 0 Then Throw New Exception("Device Not Found.") End If Dim usbInterfaceInfo As UsbInterfaceInfo = Nothing Dim usbEndpointInfo As UsbEndpointInfo = Nothing ' Look through all conected devices with this vid and pid until ' one is found that has and and endpoint that matches TRANFER_ENDPOINT. ' For Each regDevice As UsbRegistry In regList If regDevice.Open(MyUsbDevice) Then If MyUsbDevice.Configs.Count > 0 Then ' if TRANFER_ENDPOINT is 0x80 or 0x00, LookupEndpointInfo will return the ' first read or write (respectively). If UsbEndpointBase.LookupEndpointInfo(MyUsbDevice.Configs(0), TRANFER_ENDPOINT, usbInterfaceInfo, usbEndpointInfo) Then Exit For End If MyUsbDevice.Close() MyUsbDevice = Nothing End If End If Next ' If the device is open and ready If MyUsbDevice Is Nothing Then Throw New Exception("Device Not Found.") End If ' If this is a "whole" usb device (libusb-win32, linux libusb-1.0) ' it exposes an IUsbDevice interface. If not (WinUSB) the ' 'wholeUsbDevice' variable will be null indicating this is ' an interface of a device; it does not require or support ' configuration and interface selection. Dim wholeUsbDevice As IUsbDevice = TryCast(MyUsbDevice, IUsbDevice) If Not ReferenceEquals(wholeUsbDevice, Nothing) Then ' This is a "whole" USB device. Before it can be used, ' the desired configuration and interface must be selected. ' Select config #1 wholeUsbDevice.SetConfiguration(1) ' Claim interface #0. wholeUsbDevice.ClaimInterface(usbInterfaceInfo.Descriptor.InterfaceID) End If ' open read endpoint. Dim reader As UsbEndpointReader = MyUsbDevice.OpenEndpointReader(DirectCast(usbEndpointInfo.Descriptor.EndpointID, ReadEndpointID), 0, DirectCast((usbEndpointInfo.Descriptor.Attributes And &H3), EndpointType)) If ReferenceEquals(reader, Nothing) Then Throw New Exception("Failed locating read endpoint.") End If reader.Reset() ' The benchmark device firmware works with this example but it must be put into PC read mode. #If IS_BENCHMARK_DEVICE Then Dim transferred As Integer Dim ctrlData As Byte() = New Byte(0) {} Dim setTestTypePacket As New UsbSetupPacket(CByte((UsbCtrlFlags.Direction_In Or UsbCtrlFlags.Recipient_Device Or UsbCtrlFlags.RequestType_Vendor)), &He, &H1, usbInterfaceInfo.Descriptor.InterfaceID, 1) MyUsbDevice.ControlTransfer(setTestTypePacket, ctrlData, 1, transferred) #End If TRANFER_SIZE -= (TRANFER_SIZE Mod usbEndpointInfo.Descriptor.MaxPacketSize) Dim transferQeue As New UsbTransferQueue(reader, TRANFER_MAX_OUTSTANDING_IO, TRANFER_SIZE, 5000, usbEndpointInfo.Descriptor.MaxPacketSize) Do Dim handle As UsbTransferQueue.Handle ' Begin submitting transfers until TRANFER_MAX_OUTSTANDING_IO has benn reached. ' then wait for the oldest outstanding transfer to complete. ' ec = transferQeue.Transfer(handle) If ec <> ErrorCode.Success Then Throw New Exception("Failed getting async result") End If ' Show some information on the completed transfer. showTransfer(handle, mTransferCount) Loop While System.Math.Max(System.Threading.Interlocked.Increment(mTransferCount),mTransferCount - 1) < TRANSFER_COUNT ' Cancels any oustanding transfers and free's the transfer queue handles. ' NOTE: A transfer queue can be reused after it's freed. transferQeue.Free() Console.WriteLine(vbCr & vbLf & "Done!" & vbCr & vbLf) Catch ex As Exception Console.WriteLine() Console.WriteLine((If(ec <> ErrorCode.None, ec & ":", [String].Empty)) & ex.Message) Finally If MyUsbDevice IsNot Nothing Then If MyUsbDevice.IsOpen Then ' If this is a "whole" usb device (libusb-win32, linux libusb-1.0) ' it exposes an IUsbDevice interface. If not (WinUSB) the ' 'wholeUsbDevice' variable will be null indicating this is ' an interface of a device; it does not require or support ' configuration and interface selection. Dim wholeUsbDevice As IUsbDevice = TryCast(MyUsbDevice, IUsbDevice) If Not ReferenceEquals(wholeUsbDevice, Nothing) Then ' Release interface #0. wholeUsbDevice.ReleaseInterface(0) End If MyUsbDevice.Close() End If MyUsbDevice = Nothing End If ' Wait for user input.. Console.ReadKey() ' Free usb resources UsbDevice.[Exit]() End Try End Sub Private Shared Sub showTransfer(handle As UsbTransferQueue.Handle, transferIndex As Integer) If mStartTime = DateTime.MinValue Then mStartTime = DateTime.Now Console.WriteLine("Synchronizing..") Return End If mTotalBytes += handle.Transferred Dim bytesSec As Double = mTotalBytes / (DateTime.Now - mStartTime).TotalSeconds Console.WriteLine("#{0} complete. {1} bytes/sec ({2} bytes) Data[1]={3:X2}", transferIndex, Math.Round(bytesSec, 2), handle.Transferred, handle.Data(1)) End Sub End Class End Namespace
-
Create a new console application in your favorite designer.
-
Verify your project references:
System.dll
LibUsbDotNet.dll
-
Add/edit the main class. Copy/Paste code from one of the examples above.