//===================================================================================================
        /// <summary>
        /// Overriden to load data into the device's FPGA
        /// </summary>
        /// <param name="buffer">The data to load</param>
        /// <returns>The error code</returns>
        //===================================================================================================
        internal override ErrorCodes LoadFPGA(byte request, byte[] buffer)
        {
            m_controlTransferMutex.WaitOne();

            ErrorCodes errorCode;

            UsbSetupPacket packet = new UsbSetupPacket(buffer.Length);
            packet.TransferType = UsbTransferTypes.ControlOut;
            packet.Request = request;
            packet.Value = 0;
            packet.Index = 0;
            packet.Length = (ushort)buffer.Length;
            Array.Copy(buffer, packet.Buffer, buffer.Length);
            errorCode = UsbControlOutRequest(packet);

            m_controlTransferMutex.ReleaseMutex();

            return errorCode;
        }
 //==================================================================
 /// <summary>
 /// Virtual method for a USB control OUT request
 /// </summary>
 /// <returns>The result</returns>
 //==================================================================
 internal override ErrorCodes UsbControlOutRequest(UsbSetupPacket packet)
 {
     System.Diagnostics.Debug.Assert(false, "UsbControlOutRequest not implemented in SynchronousUsbInterop");
     return ErrorCodes.MethodRequiresImplementation;
 }
        //==================================================================
        /// <summary>
        /// Check's the device status for a data overrun
        /// </summary>
        /// <returns>The error code</returns>
        //==================================================================
        internal override ErrorCodes CheckUnderrun()
        {
            ErrorCodes errorCode = m_errorCode;

            ControlTransferMutex.WaitOne();

            UsbSetupPacket packet = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);
            packet.TransferType = UsbTransferTypes.ControlOut;
            packet.Request = ControlRequest.MESSAGE_REQUEST;
            packet.Index = 0;
            packet.Value = 0;
            packet.Length = (ushort)m_aoScanStatusMessage.Length;
            Array.Copy(m_aoScanStatusMessage, packet.Buffer, m_aoScanStatusMessage.Length);

            // send the status message
            UsbControlOutRequest(packet);

            // get the status response
            packet.TransferType = UsbTransferTypes.ControlIn;

            UsbControlInRequest(packet);

            ControlTransferMutex.ReleaseMutex();

            string response = m_ae.GetString(packet.Buffer, 0, packet.Buffer.Length);

            if (response.Contains(PropertyValues.UNDERRUN))
                errorCode = ErrorCodes.DataUnderrun;

            return errorCode;
        }
Example #4
0
        //==================================================================
        /// <summary>
        /// Method for a USB control Out request
        /// </summary>
        /// <returns>The result</returns>
        //==================================================================
        internal override ErrorCodes UsbControlOutRequest(UsbSetupPacket packet)
        {
            int result;

            result = LibUsbInterop.LibUsbControlTransfer(m_devHandle,
                                               ControlRequestType.VENDOR_CONTROL_OUT,
                                               packet.Request,
                                               packet.Value,
                                               packet.Index,
                                               packet.Buffer,
                                               (ushort)packet.Buffer.Length,
                                               CTRL_TIMEOUT);

            if (result >=  0)
            {
                return ErrorCodes.NoErrors;
            }
            else if (result == -4)
            {
                return ErrorCodes.DeviceNotResponding;
            }
            else if (result == -9)
            {
                return ErrorCodes.InvalidMessage;
            }

            System.Diagnostics.Debug.Assert(false, String.Format("Unknown error in UsbControlOutRequest: {0}", result));
            return ErrorCodes.UnknownError;
        }
 //=============================================================================================================
 /// <summary>
 /// Virtual method for a USB control OUT request
 /// </summary>
 /// <returns>The result</returns>
 //=============================================================================================================
 internal override ErrorCodes UsbControlOutRequest(UsbSetupPacket packet)
 {
     System.Diagnostics.Debug.Assert(false, "UsbControlOutRequest must be implemented in a derived class");
     return ErrorCodes.MethodRequiresImplementation;
 }
        //===================================================================================================
        /// <summary>
        /// Virutal method to unlock a device's memory for writing to it
        /// </summary>
        /// <param name="address">The address of the unlock code</param>
        /// <param name="unlockCode">The unlock code</param>
        /// <returns>The error code</returns>
        //===================================================================================================
        internal override ErrorCodes UnlockDeviceMemory(ushort address, ushort unlockCode)
        {
            ErrorCodes errorCode = ErrorCodes.NoErrors;

            // send memory unlock code
            UsbSetupPacket packet = new UsbSetupPacket(64);
            packet.TransferType = UsbTransferTypes.ControlOut;
            packet.Request = MEM_ADDR;
            packet.Value = 0;
            packet.Index = 0;
            packet.Length = 2;
            packet.Buffer[0] = (byte)(0x00FF & address);
            packet.Buffer[1] = (byte)((0xFF00 & address) >> 8);

            // MemAddress command
            errorCode = UsbControlOutRequest(packet);

            if (errorCode != ErrorCodes.NoErrors)
                return errorCode;

            packet.Request = MEM_WRITE;
            packet.Value = 0;
            packet.Index = 0;
            packet.Length = 2;
            packet.Buffer[0] = (byte)(0x00FF & unlockCode);
            packet.Buffer[1] = (byte)((0xFF00 & unlockCode) >> 8);

            // MemWrite command
            errorCode = UsbControlOutRequest(packet);

            return errorCode;
        }
        //==============================================================================================================================================================================
        /// <summary>
        /// Overriden to Write data to a device's memory
        /// </summary>
        /// <param name="memAddrCmd">The device's memory address command</param>
        /// <param name="memWriteCmd">The device's memory write command</param>
        /// <param name="memoryOffset">The memory offset to start writing to</param>
        /// <param name="memOffsetLength">The size of the memoryOffset value (typically 2 bytes)</param>
        /// <param name="bufferOffset">The buffer offset</param>
        /// <param name="buffer">The buffer containg the data to write to memory</param>
        /// <param name="count">The number of bytes to write</param>
        /// <returns></returns>
        //==============================================================================================================================================================================
        internal override ErrorCodes WriteDeviceMemory1(byte memAddrCmd, byte memWriteCmd, ushort memoryOffset, ushort memOffsetLength, ushort bufferOffset, byte[] buffer, byte count)
        {
            m_controlTransferMutex.WaitOne();

            ErrorCodes errorCode = ErrorCodes.NoErrors;

            UsbSetupPacket packet = new UsbSetupPacket(Constants.MAX_COMMAND_LENGTH);
            packet.TransferType = UsbTransferTypes.ControlOut;
            packet.Request = memAddrCmd;
            packet.Value = 0;
            packet.Index = 0;
            packet.Length = 2;
            packet.Buffer[0] = (byte)(0x00FF & memoryOffset);
            packet.Buffer[1] = (byte)((0xFF00 & memoryOffset) >> 8);

            if (count > Constants.MAX_COMMAND_LENGTH)
            {
                m_controlTransferMutex.ReleaseMutex();
                return ErrorCodes.CountGreaterThanMaxLength;
            }

            // MemAddress command
            errorCode = UsbControlOutRequest(packet);

            // Check current MemAddress
            packet.TransferType = UsbTransferTypes.ControlIn;
            errorCode = UsbControlInRequest(packet);

            if (errorCode == ErrorCodes.NoErrors)
            {
                packet.TransferType = UsbTransferTypes.ControlOut;
                packet.Request = memWriteCmd;
                packet.Value = 0x0;

                for (int i = 0; i < count; i++)
                    packet.Buffer[i] = buffer[i + bufferOffset];

                packet.Length = count;

                // MemWrite command
                errorCode = UsbControlOutRequest(packet);
            }

            if (errorCode != ErrorCodes.NoErrors)
                errorCode = ErrorCodes.ErrorWritingDeviceMemory;

            m_controlTransferMutex.ReleaseMutex();

            return errorCode;
        }
Example #8
0
        protected void CheckTriggerRearm()
        {
            string triggerSupport = m_daqDevice.GetDevCapsString("AISCAN:TRIG", false);

            if (triggerSupport.Contains(DevCapImplementations.PROG))
            {
                string response;

                m_daqDevice.SendMessageDirect(Messages.AISCAN_TRIG_QUERY);
                response = ReadStringDirect();

                UsbSetupPacket packet = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);

                // if the trigger is enabled, check the AISCAN:REARM setting
                if (response.Contains(PropertyValues.ENABLE))
                {
                    string rearmSupport = m_daqDevice.GetDevCapsString("AITRIG:REARM", false);

                    if (rearmSupport.Contains(DevCapImplementations.PROG))
                    {
                        // check if rearm is enabled
                        m_daqDevice.SendMessageDirect(Messages.AITRIG_REARM_QUERY);
                        response = ReadStringDirect();

                        if (response.Contains(PropertyValues.ENABLE))
                        {
                            // transfer size must be integer multiple of the packet size because
                            // we're going to switch to continuous mode
                            while (m_criticalParams.BulkInXferSize % m_criticalParams.AiChannelCount != 0)
                                m_criticalParams.BulkInXferSize += m_deviceInfo.MaxPacketSize;

                            // switch to continuous mode so the device can continually re-trigger
                            m_criticalParams.InputSampleMode = SampleMode.Continuous;

                            // get the current sample count
                            m_daqDevice.SendMessageDirect(Messages.AISCAN_SAMPLES_QUERY);
                            response = ReadStringDirect();
                            response = response.Trim(new char[] { Constants.NULL_TERMINATOR });

                            int samples = MessageTranslator.GetSamples(response);
                            m_criticalParams.AdjustedRearmSamplesPerTrigger = samples;

                            // calculate the number of bytes in each transfer
                            int inputBytes = m_criticalParams.AiChannelCount * m_criticalParams.DataInXferSize * samples;

                            int rearmBytes = 0;
                            int rearmSamples = 0;

                            if (inputBytes % m_criticalParams.BulkInXferSize != 0)
                            {
                                // when xfer mode is not SINGLEIO, the rearm bytes need to be an integer multiple of the xfer size
                                // because we're using continuous mode
                                if (m_criticalParams.InputTransferMode != TransferMode.SingleIO)
                                    rearmBytes = (int)Math.Floor((double)inputBytes / (double)m_criticalParams.BulkInXferSize) * m_criticalParams.BulkInXferSize;
                                else
                                    rearmBytes = inputBytes;

                                // adjust the number of samples
                                rearmSamples = rearmBytes / (m_criticalParams.AiChannelCount * m_criticalParams.DataInXferSize);

                                // now update the device's SAMPLE property
                                string msg = Messages.AISCAN_SAMPLES;
                                msg = Messages.InsertValue(msg, rearmSamples);

                                m_criticalParams.AdjustedRearmSamplesPerTrigger = rearmSamples;
                            }

                            // Delta rearm samples will non-zero when xfer mode is not SINGLEIO
                            if (m_criticalParams.InputTransferMode != TransferMode.SingleIO)
                                m_criticalParams.DeltaRearmInputSamples = rearmSamples - samples;
                            else
                                m_criticalParams.DeltaRearmInputSamples = 0;

                            m_totalSamplesToReadPerChannel = INTERNAL_READ_BUFFER_SIZE / 2;

                            m_totalSamplesToReadPerChannel = (int)Math.Ceiling((double)m_totalSamplesToReadPerChannel / (double)m_criticalParams.AiChannelCount) * m_criticalParams.AiChannelCount;
                            m_criticalParams.InputScanSamples = m_totalSamplesToReadPerChannel;

                            if (m_onDataAvailableCallbackControl != null && m_onDataAvailableCallbackControl.NumberOfSamples > m_criticalParams.AdjustedRearmSamplesPerTrigger)
                                m_onDataAvailableCallbackControl.NumberOfSamples = m_criticalParams.AdjustedRearmSamplesPerTrigger;
                        }
                        else
                        {
                            m_criticalParams.DeltaRearmInputSamples = 0;
                        }
                    }
                }
            }
        }
Example #9
0
        //=================================================================
        /// <summary>
        /// Gets the state of an Output scan operation
        /// </summary>
        /// <returns>The scan state</returns>
        //=================================================================
        protected ScanState GetOutputScanState()
        {
            m_platformInterop.ControlTransferMutex.WaitOne();

            UsbSetupPacket packet = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);
            packet.TransferType = UsbTransferTypes.ControlOut;
            packet.Request = ControlRequest.MESSAGE_REQUEST;
            packet.Index = 0;
            packet.Value = 0;
            packet.Length = (ushort)m_aoStatusMessage.Length;
            Array.Copy(m_aoStatusMessage, packet.Buffer, m_aoStatusMessage.Length);

            // send the status message
            m_platformInterop.UsbControlOutRequest(packet);

            // get the status response
            packet.TransferType = UsbTransferTypes.ControlIn;

            m_platformInterop.UsbControlInRequest(packet);

            string response = m_ae.GetString(packet.Buffer, 0, packet.Buffer.Length);

            m_platformInterop.ControlTransferMutex.ReleaseMutex();

            if (response.Contains("RUNNING"))
            {
                m_outputScanState = ScanState.Running;
            }
            else if (response.Contains("UNDERRUN"))
            {
                if (!m_stopOutputScan)
                {
                    m_errorCode = ErrorCodes.DataUnderrun;
                    m_outputScanState = ScanState.Underrun;
                }
                else
                {
                    // Let ProcessOutputScanThread clear the data underrun when it exits.
                    //m_platformInterop.ClearDataUnderrun();
                    m_outputScanState = ScanState.Idle;
                }
            }
            else
            {
                m_outputScanState = ScanState.Idle;
            }

            return m_outputScanState;
        }
Example #10
0
        internal DriverInterface(DaqDevice daqDevice, DeviceInfo deviceInfo, Object deviceLock)
        {
            m_deviceInfo = deviceInfo;
            m_daqDevice = daqDevice;
            m_deviceLock = deviceLock;

            m_platformInterop = PlatformInterop.GetUsbPlatformInterop(deviceInfo, m_criticalParams);

            // the error code may be set if the device did not initialzie
            m_errorCode = m_platformInterop.ErrorCode;

            m_usbPackets = new List<UsbSetupPacket>();
            m_usbPacketsDirect = new List<UsbSetupPacket>();
            m_ae = new ASCIIEncoding();

            string message;

            // convert following messages to an array of bytes for direct use by this driver interface

            message = "?AISCAN:STATUS";
            Array.Clear(m_aiStatusMessage, 0, m_aiStatusMessage.Length);
            m_ae.GetBytes(message.ToCharArray(), 0, message.Length, m_aiStatusMessage, 0);

            message = "?AISCAN:TRIG";
            Array.Clear(m_aiTrigStatus, 0, m_aiTrigStatus.Length);
            m_ae.GetBytes(message.ToCharArray(), 0, message.Length, m_aiTrigStatus, 0);

            message = "?AITRIG:REARM";
            Array.Clear(m_aiRearmStatus, 0, m_aiRearmStatus.Length);
            m_ae.GetBytes(message.ToCharArray(), 0, message.Length, m_aiRearmStatus, 0);

            message = "?AISCAN:SAMPLES";
            Array.Clear(m_aiQuerySamples, 0, m_aiQuerySamples.Length);
            m_ae.GetBytes(message.ToCharArray(), 0, message.Length, m_aiQuerySamples, 0);

            message = "AISCAN:SAMPLES=";
            Array.Clear(m_aiScanSamples, 0, m_aiScanSamples.Length);
            m_ae.GetBytes(message.ToCharArray(), 0, message.Length, m_aiScanSamples, 0);

            message = "?AOSCAN:STATUS";
            Array.Clear(m_aoStatusMessage, 0, m_aoStatusMessage.Length);
            m_ae.GetBytes(message.ToCharArray(), 0, message.Length, m_aoStatusMessage, 0);

            message = "AISCAN:STOP";
            Array.Clear(m_aiScanStopMessage, 0, m_aiScanStopMessage.Length);
            m_ae.GetBytes(message.ToCharArray(), 0, message.Length, m_aiScanStopMessage, 0);

            message = "AOSCAN:STOP";
            Array.Clear(m_aoScanStopMessage, 0, m_aoScanStopMessage.Length);
            m_ae.GetBytes(message.ToCharArray(), 0, message.Length, m_aoScanStopMessage, 0);

            m_deferredResponsePacket = new UsbSetupPacket(Constants.MAX_COMMAND_LENGTH);
            m_deferredResponsePacket.TransferType = UsbTransferTypes.ControlIn;
            m_deferredResponsePacket.Request = ControlRequest.MESSAGE_REQUEST;
            m_deferredResponsePacket.DeferTransfer = false;
            m_deferredResponsePacket.Index = 0;
            m_deferredResponsePacket.Value = 0;
            m_deferredResponsePacket.Length = Constants.MAX_COMMAND_LENGTH;
            m_inputBufferSizeOverride = false;

            m_controlInPacket = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);
            m_controlInPacket.TransferType = UsbTransferTypes.ControlIn;
            m_controlInPacket.Request = ControlRequest.MESSAGE_REQUEST;

            m_controlOutPacket = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);
            m_controlOutPacket.TransferType = UsbTransferTypes.ControlOut;
            m_controlOutPacket.Request = ControlRequest.MESSAGE_REQUEST;

            m_controlInPacketDirect = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);
            m_controlInPacketDirect.TransferType = UsbTransferTypes.ControlIn;
            m_controlInPacketDirect.Request = ControlRequest.MESSAGE_REQUEST;

            m_controlOutPacketDirect = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);
            m_controlOutPacketDirect.TransferType = UsbTransferTypes.ControlOut;
            m_controlOutPacketDirect.Request = ControlRequest.MESSAGE_REQUEST;

            m_criticalParams.ScanType = ScanType.AnalogInput;

            m_currentOutputScanWriteIndex = 0;
            m_outputTransferStartIndex = 0;

            unsafe
            {
                m_externalReadBuffer = null;
            }

            m_inputBlockSize = PropertyValues.DEFAULT;

            // by default, don't let old data that hasn't been read yet get overwritten
            m_criticalParams.InputScanOverwrite = false;

            m_internalReadBuffer = new byte[INTERNAL_READ_BUFFER_SIZE];
            m_internalWriteBuffer = new byte[INTERNAL_WRITE_BUFFER_SIZE];

            m_stopOutputScanDelegate = new StopOutputScanDelegate(StopOutputScan);
            m_stopOutputScanCallback = new AsyncCallback(StopOutputScanCallback);
        }
Example #11
0
        //=====================================================================
        /// <summary>
        /// Checks to see if the trigger level needs to be resent 
        /// in case other messages sent after the AITRIG:LEVEL message
        /// effects its scaling
        /// </summary>
        //=====================================================================
        protected void CheckForTriggerLevelResend()
        {
            if (m_daqDevice.CriticalParams.InputTriggerEnabled &&
                    m_daqDevice.CriticalParams.ResendInputTriggerLevelMessage &&
                        m_daqDevice.CriticalParams.InputTriggerSource.Contains("SWSTART"))
            {
                // release the control transfer mutex so the trigger message can be sent
                m_platformInterop.ControlTransferMutex.WaitOne();

                UsbSetupPacket packet = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);
                packet.Request = ControlRequest.MESSAGE_REQUEST;
                packet.TransferType = UsbTransferTypes.ControlOut;
                packet.Index = 0;
                packet.Length = (ushort)packet.Buffer.Length;
                packet.Value = 0;

                string msg = Messages.AITRIG_LEVEL;
                msg = Messages.InsertValue(msg, m_criticalParams.InputTriggerLevel);

                for (int i = 0; i < msg.Length; i++)
                    packet.Buffer[i] = (byte)msg[i];

                m_errorCode = m_platformInterop.UsbControlOutRequest(packet);

                // reaquire the control transfer mutex
                m_platformInterop.ControlTransferMutex.ReleaseMutex();
            }
        }
Example #12
0
        //======================================================================================
        /// <summary>
        /// Transfers the incoming message to the device using one of the platform interop objects
        /// Each message results in a Send/Receive transfer. The Send is to send the message to
        /// the device through a Control Out transfer and the Receive is to receive a response
        /// through a Control In transfer
        /// </summary>
        /// <param name="incomingMessage">The incoming message string</param>
        /// <returns>The error code</returns>
        //======================================================================================
        internal ErrorCodes TransferMessage(byte[] incomingMessage)
        {
            if (m_deviceLost)
                m_deviceLost = !m_platformInterop.AcquireDevice();

            ErrorCodes errorCode = ErrorCodes.NoErrors;

            UsbSetupPacket packet;

            if (!m_platformInterop.DeviceInitialized)
            {
                errorCode = ErrorCodes.DeviceNotInitialized;
            }
            else
            {
                // Acquire the  mutex so that a Control Out
                m_platformInterop.ControlTransferMutex.WaitOne();

                // create packets for the incoming message
                // each message will get a packet for a Control Out transfer and a Control In transfer
                CreateUsbPackets(incomingMessage);

                if (errorCode == ErrorCodes.NoErrors)
                {
                    ////////////////////////////////////////////
                    // Control Out request
                    ////////////////////////////////////////////
                    packet = m_usbPackets[0];

                    if (m_usbPackets.Count == 1 && packet.TransferType == UsbTransferTypes.ControlOut)
                    {
                        m_internalReadString = String.Empty;
                        m_internalReadValue = double.NaN;
                    }

                    // Convert any decimal separators back to en-US
                    for (int i = 0; i < packet.Buffer.Length; i++)
                    {
                        if (packet.Buffer[i] == (byte)PlatformInterop.LocalNumberDecimalSeparator)
                            packet.Buffer[i] = (byte)Constants.DECIMAL.ToCharArray()[0];
                    }

                    // define a packet for deferred messages
                    UsbSetupPacket deferredPacket = null;

                    // send the Control Out request to the device
                    if (!packet.DeferTransfer)
                    {
                        errorCode = m_platformInterop.UsbControlOutRequest(packet);
                    }
                    else
                    {
                        // queue the message packet. It will be sent at the beginning of a scan thread

                        // first make a copy so it doesn't get overwritten since its an instance member of this class
                        deferredPacket = new UsbSetupPacket(packet.Buffer.Length);

                        deferredPacket.DeferTransfer = packet.DeferTransfer;
                        deferredPacket.TransferType = packet.TransferType;
                        deferredPacket.Request = packet.Request;
                        deferredPacket.Value = packet.Value;
                        deferredPacket.Index = packet.Index;
                        deferredPacket.Length = packet.Length;
                        Array.Copy(packet.Buffer, deferredPacket.Buffer, packet.Buffer.Length);
                    }

                    ////////////////////////////////////////////
                    // Control In request
                    ////////////////////////////////////////////
                    if (m_usbPackets.Count > 1)
                    {
                        packet = m_usbPackets[1];

                        errorCode = m_platformInterop.UsbControlInRequest(packet);

                        if (packet.Request == ControlRequest.MESSAGE_REQUEST)
                        {
                            if (errorCode == ErrorCodes.NoErrors)
                            {
                                m_internalReadString = m_ae.GetString(packet.Buffer, 0, packet.Buffer.Length);

                                if (m_internalReadString.IndexOf(Constants.NULL_TERMINATOR) >= 0)
                                {
                                    int indexOfNt = m_internalReadString.IndexOf(Constants.NULL_TERMINATOR);
                                    m_internalReadString = m_internalReadString.Remove(indexOfNt, m_internalReadString.Length - indexOfNt);
                                }

                                if (m_internalReadString == PropertyValues.INVALID)
                                {
                                    errorCode = ErrorCodes.InvalidMessage;
                                }
                                else
                                {
                                    m_internalReadValue = TryConvertData(ref m_internalReadString);
                                }
                            }
                            else
                            {
                                m_internalReadString = String.Empty;
                                m_internalReadValue = double.NaN;
                            }
                        }
                    }

                    if (m_startInputScan)
                    {
                        if (errorCode == ErrorCodes.NoErrors)
                        {
                            if (deferredPacket != null)
                                m_deferredInputMessages.Enqueue(deferredPacket);

                            ScanState scanState = GetInputScanState();

                            if (scanState == ScanState.Running)
                            {
                                errorCode = ErrorCodes.InputScanAlreadyInProgress;
                            }
                            else if (m_deviceInfo.EndPointIn == 0)
                            {
                                errorCode = ErrorCodes.InvalidMessage;
                            }
                            else
                            {
                                // m_startInputScan is set to true in CheckForCriticalParams
                                m_deferredInputResponses.Clear();

                                CheckTriggerRearm();

                                if (m_criticalParams.InputSampleMode == SampleMode.Continuous)
                                {
                                    if (m_onDataAvailableCallbackControl != null)
                                    {
                                        if (m_criticalParams.AiChannelCount * m_criticalParams.DataInXferSize * m_onDataAvailableCallbackControl.NumberOfSamples > m_internalReadBuffer.Length / 2)
                                        {
                                            errorCode = ErrorCodes.CallbackCountTooLarge;
                                        }
                                    }
                                }

                                // release the control transfer mutex so that the deferred messages can be sent
                                m_platformInterop.ControlTransferMutex.ReleaseMutex();

                                if (errorCode == ErrorCodes.NoErrors)
                                    errorCode = StartInputScan();

                                // reaquire the control transfer mutex
                                m_platformInterop.ControlTransferMutex.WaitOne();

                                if (errorCode == ErrorCodes.NoErrors)
                                {
                                    if (m_inputScanErrorCode != ErrorCodes.NoErrors)
                                    {
                                        errorCode = m_inputScanErrorCode;
                                    }
                                    else if (packet.DeferTransfer)
                                    {
                                        m_internalReadString = m_deferredInputResponses[0].Trim(new char[] { Constants.NULL_TERMINATOR });
                                    }
                                }
                                else
                                {
                                    // if an error occurred dont't send the deferred message
                                    m_deferredInputMessages.Clear();
                                }
                            }
                        }
                    }
                    else if (m_startOutputScan)
                    {
                        if (errorCode == ErrorCodes.NoErrors)
                        {
                            if (deferredPacket != null)
                                m_deferredOutputMessages.Enqueue(deferredPacket);

                            ScanState scanState = GetOutputScanState();

                            if (scanState == ScanState.Running)
                            {
                                errorCode = ErrorCodes.OutputScanAlreadyInProgress;
                            }
                            else if (m_deviceInfo.EndPointIn == 0)
                            {
                                errorCode = ErrorCodes.InvalidMessage;
                            }
                            else
                            {
                                // m_startInputScan is set to true in CheckForCriticalParams
                                m_deferredOutputResponses.Clear();

                                // release the control transfer mutex so that the deferred messages can be sent
                                m_platformInterop.ControlTransferMutex.ReleaseMutex();

                                if (errorCode == ErrorCodes.NoErrors)
                                    errorCode = StartOutputScan();

                                // reaquire the control transfer mutex
                                m_platformInterop.ControlTransferMutex.WaitOne();

                                if (errorCode == ErrorCodes.NoErrors)
                                {
                                    if (m_outputScanErrorCode != ErrorCodes.NoErrors)
                                    {
                                        errorCode = m_outputScanErrorCode;
                                    }
                                    else if (packet.DeferTransfer)
                                    {
                                        if (m_deferredOutputResponses.Count > 0)
                                            m_internalReadString = m_deferredOutputResponses[0].Trim(new char[] { Constants.NULL_TERMINATOR });
                                        else
                                            System.Diagnostics.Debug.Assert(false, "Deferred response list is empty");
                                    }
                                }
                                else
                                {
                                    // if an error occurred don't send the deferred message
                                    m_deferredOutputMessages.Clear();
                                }
                            }
                        }
                    }
                    else if (m_initiateStopForInput && m_deviceInfo.EndPointIn != 0)
                    {
                        // release the control transfer mutex so that the Input scan thread can exit
                        m_platformInterop.ControlTransferMutex.ReleaseMutex();

                        // m_initiateStopForInput is set to true in CheckForCriticalParams

                        if (deferredPacket != null)
                        {
                            // executes on Linux - this must be called first before sending
                            // the deferred STOP command
                            StopInputScan(false);

                            errorCode = m_platformInterop.UsbControlOutRequest(deferredPacket);

                            if (m_deferredOutputResponses.Count > 0)
                                m_internalReadString = m_deferredOutputResponses[0].Trim(new char[] { Constants.NULL_TERMINATOR });
                            else
                                System.Diagnostics.Debug.Assert(false, "Deferred response list is empty");

                            m_platformInterop.FlushInputDataFromDevice();
                            m_initiateStopForInput = false;
                        }
                        else
                        {
                            // executes on Windows
                            StopInputScan(true);
                        }

                        // reaquire the control transfer mutex
                        m_platformInterop.ControlTransferMutex.WaitOne();
                    }
                    else if (m_initiateStopForOutput && m_deviceInfo.EndPointOut != 0)
                    {
                        // release the control transfer mutex so that the Input scan thread can exit
                        m_platformInterop.ControlTransferMutex.ReleaseMutex();

                        // m_initiateStopForInput is set to true in CheckForCriticalParams

                        if (deferredPacket != null)
                        {
                            // executes on Linux - this must be called first before sending
                            // the deferred STOP command
                            StopOutputScan(false);

                            errorCode = m_platformInterop.UsbControlOutRequest(deferredPacket);

                            if (m_deferredOutputResponses.Count > 0)
                                m_internalReadString = m_deferredOutputResponses[0].Trim(new char[] { Constants.NULL_TERMINATOR });
                            else
                                System.Diagnostics.Debug.Assert(false, "Deferred response list is empty");

                            m_initiateStopForOutput = false;
                        }
                        else
                        {
                            // executes on Windows
                            StopOutputScan(true);
                        }

                        // reaquire the control transfer mutex
                        m_platformInterop.ControlTransferMutex.WaitOne();
                    }
                }

                m_platformInterop.ControlTransferMutex.ReleaseMutex();
            }

            if (errorCode == ErrorCodes.DeviceNotResponding)
            {
                ReleaseDevice();
                m_deviceLost = true;
                return errorCode;
            }

            // check if the device refused the message because a scan is running...
            if (errorCode == ErrorCodes.InvalidMessage)
            {
                ErrorCodes status = m_daqDevice.CheckUsage();

                if (status != ErrorCodes.NoErrors)
                {
                    errorCode = status;
                }
            }

            return errorCode;
        }
Example #13
0
        //=============================================================================
        /// <summary>
        /// Stops an input scan directly using a control transfer
        /// </summary>
        //=============================================================================
        internal void StopInputScanDirect()
        {
            UsbSetupPacket packet = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);
            packet.TransferType = UsbTransferTypes.ControlOut;
            packet.Request = ControlRequest.MESSAGE_REQUEST;
            packet.Index = 0;
            packet.Value = 0;
            packet.Length = (ushort)m_aiScanStopMessage.Length;
            Array.Copy(m_aiScanStopMessage, packet.Buffer, m_aiScanStopMessage.Length);

            // send the status message
            m_platformInterop.ControlTransferMutex.WaitOne();

            m_platformInterop.UsbControlOutRequest(packet);

            m_platformInterop.ControlTransferMutex.ReleaseMutex();

            m_platformInterop.StopInputTransfers();

            m_stopInputScan = true;
        }
Example #14
0
        //==================================================================
        /// <summary>
        /// Clears the pipe's stall state 
        /// </summary>
        //==================================================================
        protected void ClearStall(byte pipe, UsbSetupPacket resetPacket)
        {
            m_controlTransferMutex.WaitOne();

            UsbControlOutRequest(resetPacket);

            m_controlTransferMutex.ReleaseMutex();

            LibUsbClearHalt(m_devHandle, pipe);
        }
        //============================================================================================================================================================
        /// <summary>
        /// Reads a device's memory
        /// </summary>
        /// <param name="offset">The starting addresss</param>
        /// <param name="count">The number of bytes to read</param>
        /// <param name="buffer">The buffer containing the memory contents</param>
        /// <returns>The error code</returns>
        //============================================================================================================================================================
        internal override ErrorCodes ReadDeviceMemory1(byte memAddrCmd, byte memReadCmd, ushort memoryOffset, ushort memoryOffsetLength, byte count, out byte[] buffer)
        {
            ErrorCodes errorCode = ErrorCodes.NoErrors;

            if (count > Constants.MAX_COMMAND_LENGTH)
                errorCode = ErrorCodes.CountGreaterThanMaxLength;

            UsbSetupPacket packet;

            buffer = null;

            if (errorCode == ErrorCodes.NoErrors)
            {
                // create a packet to send the memory address command
                packet = new UsbSetupPacket(memoryOffsetLength);
                packet.TransferType = UsbTransferTypes.ControlOut;
                packet.Request = memAddrCmd;
                packet.Value = 0;
                packet.Index = 0;
                packet.Length = 2;

                // store the memory offset in the first two bytes of the buffer
                packet.Buffer[0] = (byte)(0x00FF & memoryOffset);
                packet.Buffer[1] = (byte)((0xFF00 & memoryOffset) >> 8);

                buffer = null;

                // send the mem address command
                errorCode = UsbControlOutRequest(packet);

                if (errorCode == ErrorCodes.NoErrors)
                {
                    // create a new packet for reading a block of device memory
                    packet = new UsbSetupPacket(count);
                    packet.TransferType = UsbTransferTypes.ControlIn;
                    packet.Request = memReadCmd;
                    packet.Length = count;

                    // read a block of memory (up to max packet size)
                    errorCode = UsbControlInRequest(packet);

                    buffer = packet.Buffer;
                }

                if (errorCode != ErrorCodes.NoErrors)
                    errorCode = ErrorCodes.ErrorReadingDeviceMemory;
            }

            return errorCode;
        }
Example #16
0
        //===================================================================================================
        /// <summary>
        /// Get the device ID that a user set to store in the device info object
        /// </summary>
        /// <returns>The device ID</returns>
        //===================================================================================================
        internal override string GetDeviceID(DeviceInfo deviceInfo)
        {
            m_controlTransferMutex.WaitOne();

            string deviceID = String.Empty;

            InitializeDevice(deviceInfo);

            if (m_deviceInitialized)
            {
                UsbSetupPacket packet = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);

                packet.TransferType = UsbTransferTypes.ControlOut;
                packet.Request = 0x80;
                packet.DeferTransfer = false;
                packet.BytesTransfered = 0;

                for (int i = 0; i < m_devIdMessage.Length; i++)
                    packet.Buffer[i] = m_devIdMessage[i];

                UsbControlOutRequest(packet);

                packet.TransferType = UsbTransferTypes.ControlIn;
                UsbControlInRequest(packet);

                m_deviceHandle.Close();

                string response = m_ae.GetString(packet.Buffer).Trim(new char[] { Constants.NULL_TERMINATOR });

                int index = response.IndexOf('=');

                if (index >= 0)
                    deviceID = response.Substring(index + 1);

                m_controlTransferMutex.ReleaseMutex();
            }

            ReleaseDevice();

            return deviceID;
        }
        //============================================================================================================================================================
        /// <summary>
        /// Reads a device's memory
        /// </summary>
        /// <param name="offset">The starting addresss</param>
        /// <param name="count">The number of bytes to read</param>
        /// <param name="buffer">The buffer containing the memory contents</param>
        /// <returns>The error code</returns>
        //============================================================================================================================================================
        internal override ErrorCodes ReadDeviceMemory4(byte memReadCmd, ushort memoryOffset, ushort memoryOffsetLength, byte count, out byte[] buffer)
        {
            ErrorCodes errorCode = ErrorCodes.NoErrors;

            if (count > Constants.MAX_COMMAND_LENGTH)
                errorCode = ErrorCodes.CountGreaterThanMaxLength;

            UsbSetupPacket packet;

            buffer = null;

            if (errorCode == ErrorCodes.NoErrors)
            {
                if (errorCode == ErrorCodes.NoErrors)
                {
                    // create a new packet for reading a block of device memory
                    packet = new UsbSetupPacket(count);
                    packet.TransferType = UsbTransferTypes.ControlIn;
                    packet.Request = memReadCmd;
                    packet.Value = memoryOffset;
                    packet.Index = 0;
                    packet.Length = count;

                    // read a block of memory (up to max packet size)
                    errorCode = UsbControlInRequest(packet);

                    buffer = packet.Buffer;
                }

                if (errorCode != ErrorCodes.NoErrors)
                    errorCode = ErrorCodes.ErrorReadingDeviceMemory;
            }

            return errorCode;
        }
Example #18
0
        //==================================================================
        /// <summary>
        /// Method for a USB control OUT request
        /// </summary>
        /// <returns>The result</returns>
        //==================================================================
        internal override ErrorCodes UsbControlOutRequest(UsbSetupPacket packet)
        {
            bool result;

            WindowsUsbSetupPacket winUsbPacket = new WindowsUsbSetupPacket();
            winUsbPacket.RequestType = ControlRequestType.VENDOR_CONTROL_OUT;
            winUsbPacket.Request = packet.Request;
            winUsbPacket.Value = packet.Value;
            winUsbPacket.Index = packet.Index;
            winUsbPacket.Length = packet.Length;

            uint bytesTransfered = 0;

            //System.Diagnostics.Debug.WriteLine(String.Format("Starting Control Out transfer on thread {0}", Thread.CurrentThread.ManagedThreadId));

            try
            {
                result = McUsb_ControlTransfer(m_deviceHandle,
                                               winUsbPacket,
                                               packet.Buffer,
                                               (ushort)winUsbPacket.Length,
                                               ref bytesTransfered,
                                               IntPtr.Zero);

                //System.Diagnostics.Debug.WriteLine(String.Format("Completed Control Out transfer on thread {0}", Thread.CurrentThread.ManagedThreadId));
            }
            catch (Exception)
            {
                return ErrorCodes.UsbIOError;
            }

            packet.BytesTransfered = bytesTransfered;

            if (result == true)
            {
                return ErrorCodes.NoErrors;
            }
            else
            {
                int lastError = GetLastError();

                if (lastError == 22 || lastError == 1176)
                    return ErrorCodes.DeviceNotResponding;
                else if (lastError == 2 || lastError == 31)
                    return ErrorCodes.InvalidMessage;
                else if (lastError == 6)
                    return ErrorCodes.InvalidDeviceHandle;

                System.Diagnostics.Debug.Assert(false, String.Format("Unknown Error Code: {0}", lastError));
                return ErrorCodes.UnknownError;
            }
        }
 //==================================================================
 /// <summary>
 /// Virtual method for a USB control OUT request
 /// </summary>
 /// <returns>The result</returns>
 //==================================================================
 internal abstract ErrorCodes UsbControlOutRequest(UsbSetupPacket packet);
Example #20
0
        //==================================================================
        /// <summary>
        /// Clears the pipe's stall state 
        /// </summary>
        //==================================================================
        protected void ClearStall(byte pipe, UsbSetupPacket resetCommandPacket)
        {
            m_controlTransferMutex.WaitOne();

            UsbControlOutRequest(resetCommandPacket);

            m_controlTransferMutex.ReleaseMutex();

            McUsb_ResetPipe(m_deviceHandle, pipe);
        }
        //==============================================================================================================================================================================
        /// <summary>
        /// Virtual method to Write data to a device's memory
        /// </summary>
        /// <param name="unlockKey">The unlock key</param>
        /// <param name="memCmd">The device's memory read/write command</param>
        /// <param name="memoryOffset">The memory offset to start writing to</param>
        /// <param name="memOffsetLength">The size of the memoryOffset value (typically 2 bytes)</param>
        /// <param name="bufferOffset">The buffer offset</param>
        /// <param name="buffer">The buffer containg the data to write to memory</param>
        /// <param name="count">The number of bytes to write</param>
        /// <returns></returns>
        //==============================================================================================================================================================================
        internal override ErrorCodes WriteDeviceMemory3(ushort unlockKey, byte memCmd, ushort memoryOffset, ushort memOffsetLength, ushort bufferOffset, byte[] buffer, byte count)
        {
            m_controlTransferMutex.WaitOne();

            ErrorCodes errorCode = ErrorCodes.NoErrors;

            if (count > Constants.MAX_COMMAND_LENGTH)
                errorCode = ErrorCodes.CountGreaterThanMaxLength;

            if (errorCode == ErrorCodes.NoErrors)
            {
                UsbSetupPacket packet = new UsbSetupPacket(Constants.MAX_COMMAND_LENGTH);
                packet.TransferType = UsbTransferTypes.ControlOut;
                packet.Request = memCmd;
                packet.Value = unlockKey;
                packet.Index = memoryOffset;
                packet.Length = count;

                for (int i = 0; i < count; i++)
                    packet.Buffer[i] = buffer[i + bufferOffset];

                // MemWrite command
                errorCode = UsbControlOutRequest(packet);
            }

            if (errorCode != ErrorCodes.NoErrors)
                errorCode = ErrorCodes.ErrorWritingDeviceMemory;

            m_controlTransferMutex.ReleaseMutex();

            return errorCode;
        }
Example #22
0
        //===================================================================================================
        /// <summary>
        /// Get the device ID that a user set to store in the device info object
        /// </summary>
        /// <returns>The device ID</returns>
        //===================================================================================================
        internal override string GetDeviceID(DeviceInfo deviceInfo)
        {
            m_controlTransferMutex.WaitOne();

            string deviceID = String.Empty;

            InitializeDevice(deviceInfo);

            // get the device ID
            UsbSetupPacket packet = new UsbSetupPacket(Constants.MAX_MESSAGE_LENGTH);

            packet.TransferType = UsbTransferTypes.ControlOut;
            packet.Request = 0x80;
            packet.DeferTransfer = false;
            packet.BytesTransfered = 0;

            for (int i = 0; i < m_devIdMessage.Length; i++)
                packet.Buffer[i] = m_devIdMessage[i];

            UsbControlOutRequest(packet);

            packet.TransferType = UsbTransferTypes.ControlIn;
            UsbControlInRequest(packet);

            string response;
            int index;

            response = m_ae.GetString(packet.Buffer, 0, packet.Buffer.Length).Trim(new char[] { Constants.NULL_TERMINATOR });

            index = response.IndexOf('=');

            if (index >= 0)
                deviceID = response.Substring(index + 1);

            // replace the serial number that came from the device descriptor with
            // the mfg serial number

            for (int i = 0; i < m_sernoMessage.Length; i++)
                packet.Buffer[i] = m_sernoMessage[i];

            UsbControlOutRequest(packet);

            packet.TransferType = UsbTransferTypes.ControlIn;
            UsbControlInRequest(packet);

            response = m_ae.GetString(packet.Buffer, 0, packet.Buffer.Length).Trim(new char[] { Constants.NULL_TERMINATOR });

            index = response.IndexOf('=');

            if (index >= 0)
                deviceInfo.SerialNumber = response.Substring(index + 1);

            LibUsbInterop.LibUsbReleaseInterface(deviceInfo.DeviceHandle, 0);
            LibUsbInterop.LibUsbClose(deviceInfo.DeviceHandle);
            deviceInfo.DeviceHandle = IntPtr.Zero;

            m_controlTransferMutex.ReleaseMutex();

            return deviceID;
        }