//=================================================================================== /// <summary> /// Virtual method for a USB Bulk OUT request /// </summary> /// <param name="buffer">The buffer containing the data to send</param> /// <param name="count">The number of samples to send</param> /// <returns>The result</returns> //=================================================================================== internal abstract int UsbBulkOutRequest(UsbBulkOutRequest br, ref int bytesTransferred);
//================================================================== /// <summary> /// Virtual method for a USB Bulk OUT request /// </summary> /// <param name="buffer">The buffer containing the data to send</param> /// <param name="count">The number of samples to send</param> /// <returns>The result</returns> //================================================================== internal override int UsbBulkOutRequest(UsbBulkOutRequest br, ref int bytesTransferred) { System.Diagnostics.Debug.Assert(false, "UsbBulkOutRequest not implemented in SynchronousUsbInterop"); return 0; }
//=================================================================================================== /// <summary> /// Virtual method for submitting bulk out requests /// </summary> /// <param name="request">The request object</param> /// <returns>True on success otherwise false</returns> //=================================================================================================== internal virtual bool SubmitBulkOutRequest(UsbBulkOutRequest request) { return false; }
//============================================================================================================= /// <summary> /// Overriden for bulk out request /// </summary> /// <param name="buffer">The buffer containing the data to send</param> /// <param name="count">The number of samples to send</param> /// <returns>The result</returns> //============================================================================================================= internal override int UsbBulkOutRequest(UsbBulkOutRequest br, ref int bytesTransferred) { System.Diagnostics.Debug.Assert(false, "UsbControlOutRequest must be implemented in a derived class"); return 0; }
//=================================================================================================== /// <summary> /// Overriden to submit bulk out requests /// </summary> /// <param name="request">The request object</param> /// <returns>True on success otherwise false</returns> //=================================================================================================== internal override bool SubmitBulkOutRequest(UsbBulkOutRequest request) { bool result; uint lengthTransfered = 0; if (m_deviceInfo.EndPointOut == 0) { m_errorCode = ErrorCodes.BulkOutputTransfersNotSupported; return false; } //DebugLogger.WriteLine("submitting bulk out transfer # {0} - {1} bytes", request.Index, request.BytesRequested); result = McUsb_WritePipe(m_deviceHandle, m_deviceInfo.EndPointOut, request.Buffer, (uint)request.BytesRequested, ref lengthTransfered, request.NativeOverLappedIntPtr); m_numberOfOutputRequestsSubmitted++; if (!result) { int errorCode = GetLastError(); // error 997 is Overlapped I/O operation is in progress (so this is good). if (errorCode == 997) { m_totalNumberOfOutputBytesTransferred += request.BytesRequested; result = true; } } return result; }
//=================================================================================================== /// <summary> /// Creates one or more BulkOutRequest objects that contain the overlapped struct and data buffer /// These are used by the SubmitBulkOutRequest and CompleteBulkOutRequest methods /// </summary> //=================================================================================================== protected override void CreateBulkOutputRequestObjects(int transferSize) { m_bulkOutRequests.Clear(); int byteCount = 0; int bytesRequested; int bytesToCopyOnFirstPass; int bytesToCopyOnSecondPass; int sourceBufferLength = m_driverInterfaceOutputBuffer.Length; for (int i = 0; i < m_numberOfWorkingOutputRequests; i++) { UsbBulkOutRequest request = new UsbBulkOutRequest(); request.Index = i; request.Overlapped = new Overlapped(); request.Buffer = new byte[transferSize]; if (m_criticalParams.OutputSampleMode == SampleMode.Continuous) { // for continuous mode make each request the transfer size bytesRequested = transferSize; } else { // for finite mode make each request the transfer size except maybe not the last one // the last request may be a short transfer if (m_totalNumberOfOutputBytesRequested - byteCount > transferSize) bytesRequested = transferSize; else bytesRequested = m_totalNumberOfOutputBytesRequested - byteCount; } byteCount += bytesRequested; request.BytesRequested = bytesRequested; request.NativeOverlapped = request.Overlapped.Pack(CompleteBulkOutRequest, request.Buffer); if (sizeof(IntPtr) == 8) request.NativeOverLappedIntPtr = new IntPtr((long)request.NativeOverlapped); else request.NativeOverLappedIntPtr = new IntPtr((int)request.NativeOverlapped); if (i > 0) m_bulkOutRequests[i - 1].Next = request; m_bulkOutRequests.Add(request); } UsbBulkOutRequest br; for (int i = 0; i < m_numberOfQueuedOutputRequests; i++) { br = m_bulkOutRequests[i]; if ((m_driverInterfaceOutputBufferIndex + br.BytesRequested) >= sourceBufferLength) { // two passes are required since the current input scan write index // wrapped around to the beginning of the internal read buffer bytesToCopyOnFirstPass = sourceBufferLength - m_driverInterfaceOutputBufferIndex; bytesToCopyOnSecondPass = br.BytesRequested - bytesToCopyOnFirstPass; } else { // only one pass is required since the current input scan write index // did not wrap around bytesToCopyOnFirstPass = br.BytesRequested; bytesToCopyOnSecondPass = 0; } if (bytesToCopyOnFirstPass > 0) Array.Copy(m_driverInterfaceOutputBuffer, m_driverInterfaceOutputBufferIndex, br.Buffer, 0, bytesToCopyOnFirstPass); m_driverInterfaceOutputBufferIndex += bytesToCopyOnFirstPass; // reset the index to the begining of the buffer if (m_driverInterfaceOutputBufferIndex >= m_driverInterfaceOutputBuffer.Length) m_driverInterfaceOutputBufferIndex = 0; if (bytesToCopyOnSecondPass > 0) Array.Copy(m_driverInterfaceOutputBuffer, m_driverInterfaceOutputBufferIndex, br.Buffer, bytesToCopyOnFirstPass, bytesToCopyOnSecondPass); m_driverInterfaceOutputBufferIndex += bytesToCopyOnSecondPass; if (m_driverInterfaceOutputBufferIndex >= m_driverInterfaceOutputBuffer.Length) m_driverInterfaceOutputBufferIndex = 0; } m_bulkOutRequests[m_bulkOutRequests.Count - 1].Next = m_bulkOutRequests[0]; }
//=================================================================================================== /// <summary> /// Creates one or more BulkInRequest objects that contain the overlapped struct and data buffer /// These are used by the SubmitBulkInRequest and CompleteBulkInRequest methods /// </summary> //=================================================================================================== protected override void CreateBulkOutRequestObjects() { m_bulkOutRequests.Clear(); int byteCount = 0; int bytesRequested; int bytesToCopyOnFirstPass; int bytesToCopyOnSecondPass; int sourceBufferLength = m_driverInterfaceOutputBuffer.Length; for (int i = 0; i < m_numberOfWorkingOutputRequests; i++) { // create bulk in request object UsbBulkOutRequest request = new UsbBulkOutRequest(); // assign index request.Index = i; // allocate the bulk in request buffer request.Buffer = new byte[m_bulkOutXferSize]; if (m_driverInterfaceOutputBuffer.Length - byteCount < m_bulkOutXferSize) bytesRequested = m_driverInterfaceOutputBuffer.Length - byteCount; else if (m_totalNumberOfOutputBytesRequested - byteCount > m_bulkOutXferSize) bytesRequested = request.Buffer.Length; else bytesRequested = m_totalNumberOfOutputBytesRequested - byteCount; byteCount += bytesRequested; request.BytesRequested = bytesRequested; m_bulkOutRequests.Add(request); } UsbBulkOutRequest br; for (int i = 0; i < m_numberOfWorkingOutputRequests; i++) { br = m_bulkOutRequests[i]; //m_driverInterfaceOutputBufferIndex += br.BytesRequested; if ((m_driverInterfaceOutputBufferIndex + br.BytesRequested) >= sourceBufferLength) { // two passes are required since the current input scan write index // wrapped around to the beginning of the internal read buffer bytesToCopyOnFirstPass = sourceBufferLength - m_driverInterfaceOutputBufferIndex; bytesToCopyOnSecondPass = (int)br.BytesRequested - bytesToCopyOnFirstPass; } else { // only one pass is required since the current input scan write index // did not wrap around bytesToCopyOnFirstPass = (int)br.BytesRequested; bytesToCopyOnSecondPass = 0; } // copy data from driver interface's output buffer and transfer to the device if (bytesToCopyOnFirstPass > 0) Array.Copy(m_driverInterfaceOutputBuffer, m_driverInterfaceOutputBufferIndex, br.Buffer, 0, bytesToCopyOnFirstPass); m_driverInterfaceOutputBufferIndex += bytesToCopyOnFirstPass; if (m_driverInterfaceOutputBufferIndex >= m_driverInterfaceOutputBuffer.Length) m_driverInterfaceOutputBufferIndex = 0; if (bytesToCopyOnSecondPass > 0) Array.Copy(m_driverInterfaceOutputBuffer, m_driverInterfaceOutputBufferIndex, br.Buffer, bytesToCopyOnFirstPass, bytesToCopyOnSecondPass); m_driverInterfaceOutputBufferIndex += bytesToCopyOnSecondPass; if (m_driverInterfaceOutputBufferIndex >= m_driverInterfaceOutputBuffer.Length) m_driverInterfaceOutputBufferIndex = 0; } }
//================================================================================================ /// <summary> /// Overriden to perform a bulk out transfer using libusb /// </summary> /// <param name="br">The bulk out request object</param> /// <param name="bytesTransferred">The number of bytes sent to the device</param> /// <returns>The libusb error code</returns> //================================================================================================ internal override int UsbBulkOutRequest(UsbBulkOutRequest br, ref int bytesTransferred) { int status; status = LibUsbInterop.LibUsbBulkTransfer(m_devHandle, m_deviceInfo.EndPointOut, br.Buffer, br.BytesRequested, ref bytesTransferred, 0); return status; }