Example #1
0
        public Form1()
        {
            InitializeComponent();

            // This is how you call FindModules to get the names of all the connected modules
            string[] moduleNames = QuickUsb.FindModules();
            listBox1.Items.AddRange(moduleNames);
            listBox1.SelectedIndex = 0;
        }
Example #2
0
        public void FindModulesTest()
        {
            string expected = "QUSB";

            string[] actual;
            actual = QuickUsb.FindModules();
            for (int k = 0; k < actual.Length; ++k)
            {
                Assert.AreEqual(expected, actual[k].Split('-')[0]);
            }
        }
Example #3
0
        void StartAcquisition()
        {
            // Query connected modules
            nameList = QuickUsb.FindModules();
            if (nameList.Length == 0)
            {
                return;
            }

            // Open the first module
            qusb = new QuickUsb(nameList[0]);
            qusb.Open(nameList[0]);

            // Allocate buffers
            for (int k = 0; k < NumBuffers; ++k)
            {
                BufferArray.Add(Marshal.AllocHGlobal(FrameByteSize));
                BulkStream[k] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(QuickUsb.BulkStream)));
            }

            QueryPerformanceFrequency(out freq);
            QueryPerformanceCounter(out tStart);

            aquiring       = true;
            timer1.Enabled = true;

            // Issue a new transaction
            qResult = qusb.ReadBulkDataAsync(
                BufferArray[0],
                FrameByteSize,
                BulkStream[0],
                cbDelegate,
                IntPtr.Zero);

            if (!qResult)
            {
                toolStripStatusLabel1.Text = "Error: Unable to issue data read";
                qusb.Close();
                return;
            }
        }
Example #4
0
        private void bStart_Click(object sender, EventArgs e)
        {
            string[] modules = QuickUsb.FindModules();
            if (modules.Length == 0)
            {
                return;
            }
            bStart.Enabled = false;
            bStop.Enabled  = true;
            quit           = false;

            testRead            = rbRead.Checked;
            testPackSize        = (int)nPacketSize.Value * (int)Math.Pow((double)1024, (double)cbPacketSizeUnit.SelectedIndex);
            updateTimer.Enabled = true;

            rbSync.Enabled        = false;
            rbStreaming.Enabled   = false;
            rbAsync.Enabled       = false;
            rbAsyncLegacy.Enabled = false;

            testThread = new Thread(performTest);
            totalBytes = 0;
            testThread.Start();
        }
Example #5
0
        private double MeasureThroughput(int count)
        {
            // Open the module
            string[] modules = QuickUsb.FindModules();
            if (modules.Length == 0)
            {
                return(0.0f);
            }
            QuickUsb qusb = new QuickUsb(modules[0]);

            // Perform throughput test
            int    transBytes;
            long   startTime, stopTime;
            double duration;
            double throughput;

            int dataSize = 0;

            byte[] data = null;
            uint   size;

            QuickUsb.Error qusbError;

            // Check for modification to configuration parameters
            if (dataSize != testPackSize)
            {
                dataSize = testPackSize;
                data     = new byte[dataSize];
            }

            // Start timing
            transBytes = 0;
            QueryPerformanceCounter(out startTime);

            // Perform the test
            for (int k = 0; k < count; ++k)
            {
                // Perform the data R/W
                size = (uint)dataSize;
                if (rbRead.Checked)
                {
                    if (!qusb.ReadData(data, ref size))
                    {
                        // Error
                        MessageBox.Show("QuickUsbReadData() failed!", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        transBytes = 0;
                        size       = 0;
                        return(0.0f);
                    }
                    else if ((int)size != dataSize)
                    {
                        // Error
                        MessageBox.Show(String.Format("QuickUsbReadData() did not read correct amount of data ({0} of {1} bytes)!", size, dataSize), "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        transBytes = 0;
                        size       = 0;
                        return(0.0f);
                    }
                }
                else
                {
                    if (!qusb.WriteData(data, size))
                    {
                        qusbError = qusb.LastError();
                        // Error
                        MessageBox.Show("QuickUsbWriteData() failed!", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        transBytes = 0;
                        size       = 0;
                        return(0.0f);
                    }
                }
                transBytes += (int)size;
            }

            // Calculate the throughput
            QueryPerformanceCounter(out stopTime);
            duration = (double)(stopTime - startTime) / (double)freq;

            qusb.Close();

            throughput = ((double)(transBytes) / (1024.0f * 1024.0f * (double)duration));

            return(throughput);
        }
Example #6
0
        private void performTest()
        {
            // Open the module
            string[] modules = QuickUsb.FindModules();
            if (modules.Length == 0)
            {
                return;
            }
            qusb = new QuickUsb(modules[0]);
            qusb.Open(modules[0]);

            int  k, transBytes = 0;
            bool transOk;

            // Async Variables
            QuickUsb.BulkStream[] pBulkStream = null;
            ushort[][]            pDataBuffer = null;
            AsyncBulkStreamTag[]  asyncTag    = null;
            GCHandle[]            hAsyncTag   = null;

            // Legacy Async Variables
            int issuedTrans = 0, nextToComplete = 0;

            IntPtr[] bufferArray = null;
            byte[]   transId     = null;

            // Streaming Variables
            bool streaming = false;

            int dataSize   = 0;
            int numBuffers = 0;

            byte[] data = null;
            uint   size, bytesTransferred;

            QuickUsb.Error qusbError;

            // Start timing
            QueryPerformanceCounter(out startTime);

            // Perform the test
            do
            {
                // Check for modification to configuration parameters
                if (dataSize != testPackSize || numBuffers != (int)nNumBuffers.Value)
                {
                    dataSize   = testPackSize;
                    numBuffers = (int)nNumBuffers.Value;

                    if (rbSync.Checked)
                    {
                        data = new byte[dataSize];
                    }

                    if (rbAsync.Checked)
                    {
                        // Wait for all issued transactions to complete
                        while (issuedTrans > 0)
                        {
                            if (!qusb.BulkWait(pBulkStream[nextToComplete], false))
                            {
                            }
                            else
                            {
                                transOk = true;
                                --issuedTrans;
                                if (++nextToComplete == pBulkStream.Length)
                                {
                                    nextToComplete = 0;
                                }
                            }
                        }

                        // Free memories
                        if (hAsyncTag != null)
                        {
                            for (k = 0; k < hAsyncTag.Length; ++k)
                            {
                                hAsyncTag[k].Free();
                            }
                        }

                        // Allocate memories
                        pDataBuffer = new ushort[numBuffers][];
                        pBulkStream = new QuickUsb.BulkStream[numBuffers];
                        asyncTag    = new AsyncBulkStreamTag[numBuffers];
                        hAsyncTag   = new GCHandle[numBuffers];
                        for (k = 0; k < numBuffers; ++k)
                        {
                            pBulkStream[k]       = new QuickUsb.BulkStream();
                            pDataBuffer[k]       = new ushort[dataSize / 2];
                            asyncTag[k]          = new AsyncBulkStreamTag();
                            hAsyncTag[k]         = GCHandle.Alloc(asyncTag[k], GCHandleType.Pinned);
                            asyncTag[k].shutdown = 0;
                        }

                        // Reset varaibles
                        issuedTrans    = 0;
                        nextToComplete = 0;

                        // Issue new transactions
                        while (issuedTrans != numBuffers)
                        {
                            if (!qusb.ReadBulkDataAsync(pDataBuffer[nextToComplete], (uint)dataSize, pBulkStream[nextToComplete], AsyncCompletionRoutineDelegate, GCHandle.ToIntPtr(hAsyncTag[nextToComplete])))
                            {
                            }
                            else
                            {
                                ++issuedTrans;
                                if (++nextToComplete == numBuffers)
                                {
                                    nextToComplete = 0;
                                }
                            }
                        }
                    }

                    if (rbAsyncLegacy.Checked)
                    {
                        // Wait for all issued transactions to complete
                        while (issuedTrans > 0)
                        {
                            if (!qusb.AsyncWait(out bytesTransferred, transId[nextToComplete], false))
                            {
                            }
                            else
                            {
                                transOk = true;
                                --issuedTrans;
                                if (++nextToComplete == transId.Length)
                                {
                                    nextToComplete = 0;
                                }
                            }
                        }

                        // Free old memories
                        if (bufferArray != null)
                        {
                            for (k = 0; k < bufferArray.Length; ++k)
                            {
                                Marshal.FreeHGlobal(bufferArray[k]);
                            }
                        }

                        // Allocate memories
                        transId     = new byte[numBuffers];
                        bufferArray = new IntPtr[numBuffers];
                        for (k = 0; k < bufferArray.Length; ++k)
                        {
                            bufferArray[k] = Marshal.AllocHGlobal(dataSize);
                        }

                        // Reset varaibles
                        issuedTrans    = 0;
                        nextToComplete = 0;
                    }

                    if (rbStreaming.Checked)
                    {
                        // Stop the stream if one is running
                        if (streaming)
                        {
                            if (!qusb.StopStream(streamID, false))
                            {
                            }
                        }

                        // Restart the stream with new parameters
                        if (!qusb.ReadBulkDataStartStream(IntPtr.Zero, (uint)numBuffers, (uint)dataSize, StreamCompletionRoutineDelegate, IntPtr.Zero, out streamID, 4, 2))
                        {
                        }
                    }
                }

                // Perform the data R/W
                size    = (uint)dataSize;
                transOk = false;
                if (testRead)
                {
                    // Synchronous data read
                    if (rbSync.Checked)
                    {
                        if (!qusb.ReadData(data, ref size))
                        {
                            qusbError = qusb.LastError();
                            // Error
                            MessageBox.Show(String.Format("QuickUsbReadData() failed! - {0}", qusbError.ToString()), "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            quit       = true;
                            transBytes = 0;
                            size       = 0;
                        }
                        else if ((int)size != dataSize)
                        {
                            // Error
                            MessageBox.Show(String.Format("QuickUsbReadData() did not read correct amount of data ({0} of {1} bytes)!", size, dataSize), "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            quit       = true;
                            transBytes = 0;
                            size       = 0;
                        }
                        else
                        {
                            transOk     = true;
                            totalBytes += size;
                        }
                    }

                    // Asynchronous data read
                    else if (rbAsync.Checked)
                    {
                        transOk = true;
                        lock (testThread)
                        {
                            size        = (uint)streamBytes;
                            streamBytes = 0;
                        }
                    }

                    // Legacy asynchronous data read
                    else if (rbAsyncLegacy.Checked)
                    {
                        // First wait on the next transaction to complete
                        bytesTransferred = 0;
                        if (issuedTrans > 0)
                        {
                            if (!qusb.AsyncWait(out bytesTransferred, transId[nextToComplete], false))
                            {
                                qusbError = qusb.LastError();
                                // Error
                                MessageBox.Show("Error", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                quit       = true;
                                transBytes = 0;
                                size       = 0;
                            }
                            else
                            {
                                transOk = true;
                                --issuedTrans;
                            }
                        }

                        // Issue new transactions
                        while (issuedTrans != numBuffers && !quit)
                        {
                            if (!qusb.ReadDataAsync(bufferArray[nextToComplete], ref size, out transId[nextToComplete]))
                            {
                                qusbError = qusb.LastError();
                                // Error
                                MessageBox.Show("Error", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                quit       = true;
                                transBytes = 0;
                                size       = 0;
                            }
                            else
                            {
                                ++issuedTrans;
                                if (++nextToComplete == numBuffers)
                                {
                                    nextToComplete = 0;
                                }
                            }
                        }

                        if (transOk)
                        {
                            size = bytesTransferred;
                        }
                    }

                    // Streaming data read
                    else if (rbStreaming.Checked)
                    {
                        transOk = true;
                        lock (testThread)
                        {
                            size        = (uint)streamBytes;
                            streamBytes = 0;
                        }

                        // Nothing to do here
                        Thread.Sleep(250);
                    }
                }
                else if (rbSync.Checked)
                {
                    // Sychronous data write
                    if (!qusb.WriteData(data, size))
                    {
                        qusbError = qusb.LastError();
                        // Error
                        MessageBox.Show("QuickUsbWriteData() failed!", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        quit       = true;
                        transBytes = 0;
                        size       = 0;
                    }
                    else
                    {
                        transOk     = true;
                        totalBytes += size;
                    }
                }

                if (transOk)
                {
                    transBytes += (int)size;
                }
            } while (!quit);

            if (rbAsync.Checked)
            {
                // Wait for all issued transactions to complete
                for (k = 0; k < pBulkStream.Length; ++k)
                {
                    asyncTag[k].shutdown = 1;
                }

                // Wait for pending transactions to complete
                qusb.BulkWait(null, false);

                /*while (issuedTrans > 0)
                 * {
                 *  if (!qusb.BulkWait(pBulkStream[nextToComplete], false))
                 *  {
                 *  }
                 *  else
                 *  {
                 *      transOk = true;
                 *      --issuedTrans;
                 *      if (++nextToComplete == numBuffers)
                 *      {
                 *          nextToComplete = 0;
                 *      }
                 *  }
                 * }*/

                // Free memory
                for (k = 0; k < pBulkStream.Length; ++k)
                {
                    hAsyncTag[k].Free();
                }
            }

            if (rbAsyncLegacy.Checked)
            {
                // Wait for all issued transactions to complete

                /*while (issuedTrans > 0)
                 * {
                 *  qusb.AsyncWait(out size, transId[nextToComplete], false);
                 *
                 *  --issuedTrans;
                 *  if (++nextToComplete == numBuffers)
                 *  {
                 *      nextToComplete = 0;
                 *  }
                 * }*/
            }

            if (rbStreaming.Checked)
            {
                // Stop the stream if one is running
                if (streaming)
                {
                    if (!qusb.StopStream(streamID, false))
                    {
                        qusbError = qusb.LastError();
                        // Error
                        MessageBox.Show("Error", "QuickUSB Throughput Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }

            qusb.Close();

            if (rbAsyncLegacy.Checked)
            {
                // Free memory
                for (k = 0; k < bufferArray.Length; ++k)
                {
                    Marshal.FreeHGlobal(bufferArray[k]);
                }
            }
        }
Example #7
0
        private void bStart_Click(object sender, EventArgs e)
        {
            string[] modules = QuickUsb.FindModules();
            if (modules.Length == 0)
            {
                return;
            }
            bStart.Enabled = false;
            bStop.Enabled  = true;

            // Open the module
            QuickUsb qusb = new QuickUsb(modules[0]);

            // Perform throughput test
            int transBytes;

            double[] samples = new double[20];
            int      sampleIndex = 0;
            long     startTime, stopTime;
            double   duration, throughput;

            int dataSize = 0;

            byte[] data = null;
            uint   size;

            // Start timing
            transBytes = 0;
            QueryPerformanceCounter(out startTime);
            progressBar.Value = 0;

            // Perform the test
            do
            {
                // Check for modification to configuration parameters
                if (dataSize != (int)packetSize.Value * (int)Math.Pow((double)1024, (double)packetSizeUnit.SelectedIndex))
                {
                    dataSize = (int)packetSize.Value * (int)Math.Pow((double)1024, (double)packetSizeUnit.SelectedIndex);
                    data     = new byte[dataSize];
                }

                size = (uint)dataSize;
                if (!qusb.ReadData(data, ref size))
                {
                    // Error
                }
                if ((int)size != dataSize)
                {
                    // Error
                }
                transBytes += (int)size;

                // Calculate the throughput
                QueryPerformanceCounter(out stopTime);
                duration = (double)(stopTime - startTime) / (double)freq;
                samples[sampleIndex++] = transBytes / (1024 * 1024 * duration);
                if (sampleIndex >= samples.Length)
                {
                    sampleIndex = 0;
                }
                throughput = 0;
                for (int k = 0; k < samples.Length; ++k)
                {
                    throughput += samples[k];
                }
                throughput       /= samples.Length;
                lthroughput.Text  = String.Format("Throughput: {0:0.0} MB/s", throughput);
                progressBar.Value = Math.Min(30, (int)throughput);

                // Restart timer
                transBytes = 0;
                QueryPerformanceCounter(out startTime);

                // Perform GUI operations
                Application.DoEvents();
            } while (!quit);

            qusb.Close();
        }
Example #8
0
        /// <summary>
        /// Force a scan for QuickUsb modules.  This is automatically called by the timer.
        /// </summary>
        public void RescanForModules()
        {
            QuickUsb      qusb;
            qusbListInfo  listInfo;
            List <string> leaveList = new List <string>();
            List <string> enterList = new List <string>();

            string[] arr;

            // Pause the timer while we process
            scanTimer.Stop();

            // Check the ScanOnLoad and ScanEnabled properties and listen to them
            if (loading)
            {
                if (!ScanOnLoad)
                {
                    return;
                }
            }
            else
            {
                if (!ScanEnabled)
                {
                    return;
                }
            }

            // Find all attached modules
            string[] attachedModules;
            if (!performFlush)
            {
                if (showUnprogrammedDevices)
                {
                    byte[] buffer = new byte[4096];
                    buffer[0]       = (byte)'*';
                    buffer[1]       = (byte)'.';
                    buffer[2]       = (byte)'*';
                    attachedModules = QuickUsb.FindModules(ref buffer);
                }
                else
                {
                    attachedModules = QuickUsb.FindModules();
                }
            }
            else
            {
                attachedModules = new string[0];
                performFlush    = false;
            }

            // Check for lost modules
            arr = new string[QuickUsbDict.Count];
            QuickUsbDict.Keys.CopyTo(arr, 0);
            for (int k = 0; k < arr.Length; ++k)
            {
                string devName = arr[k];

                if (QuickUsbDict[devName].attached && !ArrayContains(attachedModules, devName))
                {
                    // Hold a reference to the QuickUsb
                    qusb = QuickUsbDict[devName].qusb;

                    // Remove the module from the listview
                    deviceListView.Items.Remove(QuickUsbDict[devName].lvi);

                    // Remove the module from our list
                    QuickUsbDict.Remove(devName);
                    AutoResizeByContentAndHeader();

                    // Send the ModuleDisconnected event
                    if (ModuleDisconnected != null)
                    {
                        ModuleDisconnected(this, new ModuleEventArgs(qusb));
                    }
                }
            }

            // Check for new modules
            arr = new string[QuickUsbDict.Count];
            QuickUsbDict.Keys.CopyTo(arr, 0);
            bool alreadyAdded;

            foreach (string devName in attachedModules)
            {
                if (!ArrayContains <string>(arr, devName))
                {
                    // Create a new qusbListInfo item
                    listInfo                = CreateQLVI(new QuickUsb(devName), null, out alreadyAdded);
                    listInfo.attached       = true;
                    listInfo.lvi.ImageIndex = 0;

                    // Add the new QuickUsb to the list and listview
                    if (!alreadyAdded)
                    {
                        if (listInfo.visible)
                        {
                            deviceListView.Items.Add(listInfo.lvi);
                        }
                        QuickUsbDict.Add(devName, listInfo);
                        AutoResizeByContentAndHeader();
                    }

                    // Send the ModuleConnected event
                    if (ModuleConnected != null)
                    {
                        ModuleConnected(this, new ModuleEventArgs(listInfo.qusb));
                    }

                    // If this is the first module connected, select it
                    if (autoSelect && deviceListView.Items.Count == 1)
                    {
                        deviceListView.Items[0].Selected = true;
                    }
                }
            }

            // Restart the timer
            scanTimer.Start();
        }
Example #9
0
        /////////////////////////////////////
        // QuickUSB Bulk Streaming Example //
        /////////////////////////////////////
        static void Main(string[] args)
        {
            // The number of data buffers to use.  An asynchronous data request is issued
            // for each data buffer, then the main thread waits for each request to complete
            // then issues a new asynchrnonous request using the same data buffer as the
            // completed request.  To maximize throughout, the number of buffers should be
            // at least equal to the number of threads (see the SETTING_THREADS setting).
            uint NumBuffers = 4;

            // The byte size of the buffers.  To maximize performance the buffer size should
            // be as large as possible and a power of 2.
            uint BufferByteSize = 512 * 1024; // 512 KB

            // The number of threads to process the data stream.  If NumThreads > 0, then
            // you are multithreading and must make sure to process access to shared data
            // from within completion routines.  Note that all threads may not be used.  The
            // more processing a completion routine does the more likely another thread will
            // be used.
            ushort NumThreads = 4;

            // The number of processing threads allowed to execute completion routines
            // concurrenty.  If NumThreads > 0, you are multithreading and
            // ThreadConcurrency must be at least 1.
            ushort ThreadConcurrency = 2;

            // The Streaming API (for data reads) can use either data buffers allocated
            // internally by the QuickUSB API or data buffers allocate by the user.  This
            // example demonstrates how to do either.
            bool UserAllocatedBuffers = true;

            // Variables
            QuickUsb qusb;
            int      k;

            string[] nameList;
            bool     qResult;

            QuickUsb.Error qusbError;
            byte           streamID;

            // The data buffers, BulkStream objects, and tag objects.  Because these objects
            // are passed to and used by unmanaged code in QuickUSB land, they must be handled
            // with care.  They cannot be relocated by the garbage collector and must either
            // be pinned or allocated in unmanaged memory.  Refer to the QuickUsbBulkAsyncCs
            // sample on how to properly use user 'tag' data.
            ushort[][] BufferArray = new ushort[NumBuffers][];

            // We must keep an active reference to the delegate so it is not garbage collected.
            // This reference must minimally stay alive until all pending asynchronous requests
            // have completed.
            QuickUsb.BulkStreamCompletionRoutine cbDelegate = new QuickUsb.BulkStreamCompletionRoutine(CompletionRoutine);

            // Query connected modules
            nameList = QuickUsb.FindModules();
            if (nameList.Length == 0)
            {
                Console.WriteLine("No modules found.");
                return;
            }

            // Open the first module
            string name = nameList[0];

            Console.WriteLine("Using Device: " + name);
            qusb    = new QuickUsb(name);
            qResult = qusb.Open(name);
            if (!qResult)
            {
                qusb.Close();
                return;
            }

            // Display the ID of the currently executing thread (the main thread)
            Console.WriteLine("Number of processors: " + Environment.ProcessorCount.ToString());
            Console.WriteLine("Main thread id: " + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.WriteLine();

            // Allocate buffers
            if (UserAllocatedBuffers)
            {
                for (k = 0; k < NumBuffers; ++k)
                {
                    // Allocate the data buffers in unmanaged memory
                    BufferArray[k] = new ushort[BufferByteSize / 2];
                }
            }

            // Start throughput timer
            QueryPerformanceFrequency(out freq);
            QueryPerformanceCounter(out tStart);

            // Start the data stream
            Console.WriteLine("Acquiring data.  Press any key to stop...");
            if (UserAllocatedBuffers)
            {
                // Start streaming data to our user allocated data buffers
                qResult = qusb.ReadBulkDataStartStream(BufferArray, NumBuffers, BufferByteSize, cbDelegate, IntPtr.Zero, out streamID, NumThreads, ThreadConcurrency);
            }
            else
            {
                // Start streaming data to data buffers that will be allocated interally by the Streaming API
                qResult = qusb.ReadBulkDataStartStream(IntPtr.Zero, NumBuffers, BufferByteSize, cbDelegate, IntPtr.Zero, out streamID, NumThreads, ThreadConcurrency);
            }
            if (!qResult)
            {
                qusbError = qusb.LastError();
                Console.WriteLine("ReadBulkDataStartStream failed with error {0}", qusbError);
            }
            else
            {
                // Wait will data gets acquired and processed in the background
                while (!Console.KeyAvailable)
                {
                    //---------------------------------------------------------
                    // Performing some background tasks
                    //---------------------------------------------------------

                    // If we are not multithreading the stream in this example, we must
                    // allow time for processing requests.  Processing requests simply
                    // means checking if a request has completed, execute its completion
                    // routine, and re-issue the requests.  QuickUsb.ProcessStream will
                    // return when either any request has completed or the specified time
                    // has elapsed.
                    if (NumThreads == 0)
                    {
                        qResult = qusb.ProcessStream(streamID, 50);
                        if (!qResult)
                        {
                            qusbError = qusb.LastError();
                            Console.WriteLine("ProcessStream failed with error {0}", qusbError);
                            break;
                        }
                    }
                    else
                    {
                        // Our background threads are processing the stream so we will
                        // just not hog the processor
                        Thread.Sleep(50);
                    }
                }

                // Stop the data stream
                Console.WriteLine("Stopping data aquisition");
                qResult = qusb.StopStream(streamID, false);
                if (!qResult)
                {
                    qusbError = qusb.LastError();
                    Console.WriteLine("BulkDataStopStream failed with error {0}", qusbError);
                }
            }

            // Stop the throughput timer
            QueryPerformanceCounter(out tEnd);
            tElapsed = (double)(tEnd - tStart) / (double)(freq);
            Console.WriteLine();

            Console.WriteLine("Time elapsed: {0:0.000} s", tElapsed);
            Console.WriteLine("Total bytes transferred: {0:0.000} MB", ((float)TotalBytes / (1024.0 * 1024.0)));
            Console.WriteLine("Data rate: {0:0.000} MS/s", ((TotalBytes / (1024.0 * 1024.0)) / tElapsed));
            Console.WriteLine();

            // Report any leaks or errors
            Console.WriteLine("{0} transaction(s) failed", ErrorCount);
            Console.WriteLine();
            foreach (KeyValuePair <int, int> kv in ThreadIds)
            {
                Console.WriteLine("Thread #{0} used for {1} completion routine callbacks", kv.Key, kv.Value);
            }

            // Close the module
            qResult = qusb.Close();
            if (!qResult)
            {
                Console.WriteLine("QuickUSB Error: {0}", qusb.LastError());
                return;
            }

            return;
        }
Example #10
0
        ///////////////////////////////////
        // QuickUSB Asynchronous Example //
        ///////////////////////////////////
        static void Main(string[] args)
        {
            // The number of data buffers to use.  An asynchronous data request is issued
            // for each data buffer, then the main thread waits for each request to complete
            // then issues a new asynchrnonous request using the same data buffer as the
            // completed request.  To maximize throughout, the number of buffers should be
            // at least equal to the number of threads (see the SETTING_THREADS setting).
            const int NumBuffers = 8;

            // The byte size of the buffers.  To maximize performance the buffer size should
            // be as large as possible and a power of 2.
            const int BufferByteSize = 512 * 1024; // 512 KB

            // The number of times to issue a request for each buffer.
            const int LOOPS = 50;

            // Variables
            int k, j, Id = 0;

            string[] nameList;
            bool     qResult;

            QuickUsb.Error qusbError;

            // Variables to track time and performace
            long   tStart, tEnd, freq;
            double tElapsed;

            // The data buffers, BulkStream objects, and tag objects.  Because these objects
            // are passed to and used by unmanaged code in QuickUSB land, they must be handled
            // with care.  They cannot be relocated by the garbage collector and must either
            // be pinned or allocated in unmanaged memory.
            ushort[][]            BufferArray = new ushort[NumBuffers][];
            QuickUsb.BulkStream[] BulkStream  = new QuickUsb.BulkStream[NumBuffers];
            BulkStreamTag[]       tag         = new BulkStreamTag[NumBuffers];

            // We must keep an active reference to the delegate so it is not garbage collected.
            // This reference must minimally stay alive until all pending asynchronous requests
            // have completed.
            QuickUsb.BulkStreamCompletionRoutine cbDelegate = new QuickUsb.BulkStreamCompletionRoutine(CompletionRoutine);

            // Query connected modules
            nameList = QuickUsb.FindModules();
            if (nameList.Length == 0)
            {
                Console.WriteLine("No modules found.");
                return;
            }

            // Open the first module
            qusb = new QuickUsb(nameList[0]);
            qusb.Open(nameList[0]);

            // Allocate buffers
            for (k = 0; k < NumBuffers; ++k)
            {
                // Allocate the data buffers in unmanaged memory
                BufferArray[k] = new ushort[BufferByteSize / 2];

                // Allocate the BulkStream objects
                BulkStream[k] = new QuickUsb.BulkStream();

                // Create the tag object as normal.  We will later get a pinned reference to this
                // object to use in issuing the request, that we will later be able to use to
                // reconstruct a reference to the managed tag object in the completion routine.
                // We can do this because the tag data is never accessed or modified in unmanaged
                // land and only ever used in managed land.
                tag[k] = new BulkStreamTag();
            }

            // Start throughput timer
            QueryPerformanceFrequency(out freq);
            QueryPerformanceCounter(out tStart);

            Console.WriteLine("Acquiring data...please wait");

            // Aquire
            for (j = 0; j < (LOOPS + 1); ++j)
            {
                for (k = 0; k < NumBuffers; ++k)
                {
                    // If this is not the first loop, wait for the last transaction to complete
                    if (j != 0)
                    {
                        // Wait for the transaction to complete.  Once this function returns successfully
                        // the completion routine has already been executed and the transaction is
                        // entirely complete.
                        qResult = qusb.BulkWait(BulkStream[k], false);
                        if (!qResult)
                        {
                            qusbError = qusb.LastError();
                            Console.WriteLine("Request failed (QuickUSB Error: {0})", qusb.LastError());
                        }
                        else
                        {
                            // Now that this request has completed we may process the data here or in the
                            // completion routine, though it is better to perform all processing in the
                            // completion routine as they can be multi-threaded, allowing the main thread
                            // to simply issue and re-issue data requests.
                        }
                    }

                    // If this is not the last loop, issue a new transaction
                    if (j != LOOPS)
                    {
                        //Console.WriteLine("Issuing Request #{0}", (Id + 1));

                        // Issue a new transaction
                        tag[k].Id = ++Id;
                        qResult   = qusb.ReadBulkDataAsync(
                            BufferArray[k],
                            BufferByteSize,
                            BulkStream[k],
                            cbDelegate,
                            GCHandle.ToIntPtr(GCHandle.Alloc(tag[k])));

                        if (!qResult)
                        {
                            Console.WriteLine(String.Format("QuickUSB Error: {0}", qusb.LastError()));
                            qusb.Close();
                            return;
                        }
                        else
                        {
                            ++RefCount;
                            ++TransCount;
                        }
                    }
                }
            }

            // Stop the throughput timer
            QueryPerformanceCounter(out tEnd);
            tElapsed = (double)(tEnd - tStart) / (double)(freq);
            Console.WriteLine();

            Console.WriteLine("Time elapsed: {0:0.000} s", tElapsed);
            Console.WriteLine("Total bytes transferred: {0:0.000} MB", ((float)TotalBytes / (1024.0 * 1024.0)));
            Console.WriteLine("Data rate: {0:0.000} MS/s", ((TotalBytes / (1024.0 * 1024.0)) / tElapsed));
            Console.WriteLine();

            // Close the module
            qResult = qusb.Close();
            if (!qResult)
            {
                Console.WriteLine("QuickUSB Error: {0}", qusb.LastError());
                return;
            }

            // Report any leaks or errors
            Console.WriteLine("{0} transaction(s) issued in total", TransCount);
            Console.WriteLine("{0} transaction(s) failed", ErrorCount);
            Console.WriteLine("{0} transaction(s) are still outstanding", RefCount);

            return;
        }