示例#1
0
        /*Summary
         * This is a recursive routine for pinning all the buffers used in the transfer in memory.
         * It will get recursively called QueueSz times.  On the QueueSz_th call, it will call
         * XferData, which will loop, transferring data, until the stop button is clicked.
         * Then, the recursion will unwind.
         */
        public unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo)
        {
            // Allocate one set of buffers for the queue. Buffered IO method require user to allocate a buffer as a part of command buffer,
            // the BeginDataXfer does not allocated it. BeginDataXfer will copy the data from the main buffer to the allocated while initializing the commands.
            cBufs[j]    = new byte[CyConst.SINGLE_XFER_LEN + IsoPktBlockSize + ((EndPoint.XferMode == XMODE.BUFFERED) ? BufSz : 0)];
            xBufs[j]    = new byte[BufSz];
            oLaps[j]    = new byte[20];
            pktsInfo[j] = new ISO_PKT_INFO[PPX];

            fixed(byte *tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j])   // Pin the buffers in memory
            {
                OVERLAPPED *ovLapStatus = (OVERLAPPED *)tL0;

                ovLapStatus->hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0);

                // Pre-load the queue with a request
                int len = BufSz;

                EndPoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]);

                j++;

                if (j < QueueSz)
                {
                    LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo);  // Recursive call to pin next buffers in memory
                }
                else
                {
                    XferData(cBufs, xBufs, oLaps, pktsInfo);          // All loaded. Let's go!
                }
            }
        }
示例#2
0
        /// <summary>
        /// Equivalent to the CyUSBEndPoint.XferData(...) but with pointer pinning to ensure that the garbage collector does not move buffers
        /// </summary>
        /// <param name="buf">The buffer to transfer data into or out</param>
        /// <param name="len">Length of data to transfer. Can be overwritten with actual transfer length</param>
        /// <param name="endpoint">Endpoint to perform the transfer operation on</param>
        /// <returns>Bool indicating success of the transfer operation</returns>
        static public unsafe bool XferData(ref byte[] buf, ref int len, ref CyUSBEndPoint endpoint)
        {
            byte[] ov = new byte[endpoint.OverlapSignalAllocSize];
            fixed(byte *numPtr = ov)
            {
                ((OVERLAPPED *)numPtr)->hEvent = PInvoke.CreateEvent(0U, 0U, 0U, 0U);
                byte[] singleXfer = new byte[38 + (endpoint.XferMode == XMODE.DIRECT ? 0 : len)];
                // These pinned pointers ensure that the buffers don't move in memory
                var cmd_buff_handle = GCHandle.Alloc(singleXfer, GCHandleType.Pinned);
                var data_handle     = GCHandle.Alloc(buf, GCHandleType.Pinned);

                //Perform async transfer
                endpoint.BeginDataXfer(ref singleXfer, ref buf, ref len, ref ov);
                bool flag1 = WaitForIO(((OVERLAPPED *)numPtr)->hEvent, ref endpoint);
                bool flag2 = endpoint.FinishDataXfer(ref singleXfer, ref buf, ref len, ref ov);

                PInvoke.CloseHandle(((OVERLAPPED *)numPtr)->hEvent);

                //release memory
                cmd_buff_handle.Free();
                data_handle.Free();

                //return operation flags
                return(flag1 && flag2);
            }
        }
示例#3
0
        /*Summary
         * This is a recursive routine for pinning all the buffers used in the transfer in memory.
         * It will get recursively called QueueSz times.  On the QueueSz_th call, it will call
         * XferData, which will loop, transferring data, until the stop button is clicked.
         * Then, the recursion will unwind.
         */
        public unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo)
        {
            // Allocate one set of buffers for the queue, Buffered IO method require user to allocate a buffer as a part of command buffer,
            // the BeginDataXfer does not allocated it. BeginDataXfer will copy the data from the main buffer to the allocated while initializing the commands.
            cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN + IsoPktBlockSize + ((EndPoint.XferMode == XMODE.BUFFERED) ? BufSz : 0)];

            xBufs[j] = new byte[BufSz];

            //initialize the buffer with initial value 0xA5
            for (int iIndex = 0; iIndex < BufSz; iIndex++)
            {
                xBufs[j][iIndex] = DefaultBufInitValue;
            }

            oLaps[j]    = new byte[20];
            pktsInfo[j] = new ISO_PKT_INFO[PPX];

            fixed(byte *tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j])   // Pin the buffers in memory
            {
                OVERLAPPED *ovLapStatus = (OVERLAPPED *)tL0;

                ovLapStatus->hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0);

                // Pre-load the queue with a request
                int len = BufSz;

                EndPoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]);

                //if (Save == true)  //mady
                //{
                //    Buffer.BlockCopy(xBufs[j], 0, temp, j * PPX * EndPoint.MaxPktSize, PPX * EndPoint.MaxPktSize); //mady: Take Backup of received data to Temp Buffer
                //}


                j++;

                if (j < QueueSz)
                {
                    LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo);  // Recursive call to pin next buffers in memory
                }
                else
                {
                    XferData(cBufs, xBufs, oLaps, pktsInfo);
                }
            }
        }
示例#4
0
        /*Summary
         * This is a recursive routine for pinning all the buffers used in the transfer in memory.
         * It will get recursively called QueueSz times.  On the QueueSz_th call, it will call
         * XferData, which will loop, transferring data, until the stop button is clicked.
         * Then, the recursion will unwind.
         */
        public unsafe void LockNLoad(byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo)
        {
            int j           = 0;
            int nLocalCount = j;

            GCHandle[] bufSingleTransfer = new GCHandle[QueueSz];
            GCHandle[] bufDataAllocation = new GCHandle[QueueSz];
            GCHandle[] bufPktsInfo       = new GCHandle[QueueSz];
            GCHandle[] handleOverlap     = new GCHandle[QueueSz];

            while (j < QueueSz)
            {
                // Allocate one set of buffers for the queue, Buffered IO method require user to allocate a buffer as a part of command buffer,
                // the BeginDataXfer does not allocated it. BeginDataXfer will copy the data from the main buffer to the allocated while initializing the commands.
                cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN + IsoPktBlockSize + ((EndPoint.XferMode == XMODE.BUFFERED) ? BufSz : 0)];

                xBufs[j] = new byte[BufSz];

                //initialize the buffer with initial value 0xA5
                for (int iIndex = 0; iIndex < BufSz; iIndex++)
                {
                    xBufs[j][iIndex] = DefaultBufInitValue;
                }

                int sz = Math.Max(CyConst.OverlapSignalAllocSize, sizeof(OVERLAPPED));
                oLaps[j]    = new byte[sz];
                pktsInfo[j] = new ISO_PKT_INFO[PPX];

                /*/////////////////////////////////////////////////////////////////////////////
                *
                * fixed keyword is getting thrown own by the compiler because the temporary variables
                * tL0, tc0 and tb0 aren't used. And for jagged C# array there is no way, we can use this
                * temporary variable.
                *
                * Solution  for Variable Pinning:
                * Its expected that application pin memory before passing the variable address to the
                * library and subsequently to the windows driver.
                *
                * Cypress Windows Driver is using this very same memory location for data reception or
                * data delivery to the device.
                * And, hence .Net Garbage collector isn't expected to move the memory location. And,
                * Pinning the memory location is essential. And, not through FIXED keyword, because of
                * non-usability of temporary variable.
                *
                *  /////////////////////////////////////////////////////////////////////////////*/
                //fixed (byte* tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j])  // Pin the buffers in memory
                //////////////////////////////////////////////////////////////////////////////////////////////
                bufSingleTransfer[j] = GCHandle.Alloc(cBufs[j], GCHandleType.Pinned);
                bufDataAllocation[j] = GCHandle.Alloc(xBufs[j], GCHandleType.Pinned);
                bufPktsInfo[j]       = GCHandle.Alloc(pktsInfo[j], GCHandleType.Pinned);
                handleOverlap[j]     = GCHandle.Alloc(oLaps[j], GCHandleType.Pinned);
                // oLaps "fixed" keyword variable is in use. So, we are good.
                /////////////////////////////////////////////////////////////////////////////////////////////

                unsafe
                {
                    //fixed (byte* tL0 = oLaps[j])
                    {
                        CyUSB.OVERLAPPED ovLapStatus = new CyUSB.OVERLAPPED();
                        ovLapStatus        = (CyUSB.OVERLAPPED)Marshal.PtrToStructure(handleOverlap[j].AddrOfPinnedObject(), typeof(CyUSB.OVERLAPPED));
                        ovLapStatus.hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0);
                        Marshal.StructureToPtr(ovLapStatus, handleOverlap[j].AddrOfPinnedObject(), true);

                        // Pre-load the queue with a request
                        int len = BufSz;
                        if (EndPoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]) == false)
                        {
                            Failures++;
                        }
                    }
                    j++;
                }
            }

            XferData(cBufs, xBufs, oLaps, pktsInfo, handleOverlap);          // All loaded. Let's go!

            unsafe
            {
                for (nLocalCount = 0; nLocalCount < QueueSz; nLocalCount++)
                {
                    CyUSB.OVERLAPPED ovLapStatus = new CyUSB.OVERLAPPED();
                    ovLapStatus = (CyUSB.OVERLAPPED)Marshal.PtrToStructure(handleOverlap[nLocalCount].AddrOfPinnedObject(), typeof(CyUSB.OVERLAPPED));
                    PInvoke.CloseHandle(ovLapStatus.hEvent);

                    /*////////////////////////////////////////////////////////////////////////////////////////////
                    *
                    * Release the pinned allocation handles.
                    *
                    *  ////////////////////////////////////////////////////////////////////////////////////////////*/
                    bufSingleTransfer[nLocalCount].Free();
                    bufDataAllocation[nLocalCount].Free();
                    bufPktsInfo[nLocalCount].Free();
                    handleOverlap[nLocalCount].Free();

                    cBufs[nLocalCount] = null;
                    xBufs[nLocalCount] = null;
                    oLaps[nLocalCount] = null;
                }
            }
            GC.Collect();
        }