示例#1
0
        public static float[] GetWaveFromFile(AnalogChannel channel, uint waveLength, double samplePeriod, double timeOffset)
        {
            if(readChannel == null || readTime == null)
            {
                String filename = Path.GetTempFileName();
                FileStream f = new FileStream(filename, FileMode.Create, FileAccess.Write);
                byte[] i2cSequence = Resources.Load ("i2c_sequence.mat");
                f.Write(i2cSequence, 0, i2cSequence.Length);
                f.Close();

                MatfileReader matfileReader = new MatlabFileIO.MatfileReader(filename);
                readChannel = new Dictionary<AnalogChannel, float[]>() {
                    { AnalogChannel.ChA, Utils.CastArray<double, float>(matfileReader.Variables["chA"].data as double[]) },
                    { AnalogChannel.ChB, Utils.CastArray<double, float>(matfileReader.Variables["chB"].data as double[]) },
                };
                readTime = matfileReader.Variables["time"].data as double[];
                samplePeriodOriginal = readTime[1] - readTime[0];
                sequenceLength = readChannel[AnalogChannel.ChA].Length;
                matfileReader.Close();
            }

            if (samplePeriod / samplePeriodOriginal % 1.0 != 0.0)
                throw new Exception("Data from file doesn't suit the dummy scope sampling frequency");

            uint decimation = (uint)Math.Ceiling(samplePeriod / samplePeriodOriginal);
            float[] wave = Utils.DecimateArray(readChannel[channel], decimation);

            int sampleOffset = (int)Math.Ceiling(timeOffset / samplePeriodOriginal % sequenceLength);

            int requiredRepetitions = (int)Math.Ceiling(waveLength / (double)wave.Length);
            if (requiredRepetitions > 1)
            {
                List<float> concat = new List<float>();
                for(int i = 0; i < requiredRepetitions; i++)
                    concat.AddRange(wave);
                wave = concat.Take((int)waveLength).ToArray();
            }
            return wave;
        }
		float baseVoltageRangeMax = 0.6769f; //V

        /// <summary>
        /// Sets and uploads the divider and multiplier what are optimal for the requested range
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="minimum"></param>
        /// <param name="maximum"></param>
        public void SetVerticalRange(AnalogChannel channel, float minimum, float maximum)
        {
            if (!Connected) return;
            
            //Walk through dividers/multipliers till requested range fits
            //this walk assumes it starts with the smallest range, and that range is only increasing
            int dividerIndex = 0;
            int multIndex = 0;

            verticalRanges[channel] = new Range(minimum, maximum);

            for (int i = 0; i < rom.computedDividers.Length * rom.computedMultipliers.Length; i++)
            {
                dividerIndex= i / rom.computedMultipliers.Length;
                multIndex = rom.computedMultipliers.Length - (i % rom.computedMultipliers.Length) - 1;
                if (
                    (ProbeScaleHostToScope(channel, maximum) < baseVoltageRangeMax * rom.computedDividers[dividerIndex] / rom.computedMultipliers[multIndex])
                    &&
                    (ProbeScaleHostToScope(channel, minimum) > baseVoltageRangeMin * rom.computedDividers[dividerIndex] / rom.computedMultipliers[multIndex])
                    )
                    break;
            }
            SetDivider(channel, validDividers[dividerIndex]);
            SetMultiplier(channel, validMultipliers[multIndex]);
            channelSettings[channel] = rom.getCalibration(channel, validDividers[dividerIndex], validMultipliers[multIndex]);
            SetYOffset(channel, yOffset[channel]);
            yOffset[channel] = GetYOffset(channel);
            if (channel == triggerAnalog.channel)
            {
                TriggerAnalog = this.triggerAnalog;
                //SetTriggerThreshold(this.triggerThreshold);
            }
        }
		public float GetYOffset(AnalogChannel channel)
		{
            REG r = (channel == AnalogChannel.ChA) ? REG.CHA_YOFFSET_VOLTAGE : REG.CHB_YOFFSET_VOLTAGE;
            byte offsetByte = FpgaSettingsMemory[r].GetByte();
            return ConvertYOffsetByteToVoltage(channel, offsetByte);
        }
        /// <summary>
        /// Sets vertical offset of a channel
        /// </summary>
        /// <param name="channel">0 or 1 (channel A or B)</param>
        /// <param name="offset">Vertical offset in Volt</param>
        public void SetYOffset(AnalogChannel channel, float offset)
        {
            yOffset[channel] = offset;
            if (!Connected) return;
            //FIXME: convert offset to byte value
            REG r = (channel == AnalogChannel.ChA) ? REG.CHA_YOFFSET_VOLTAGE : REG.CHB_YOFFSET_VOLTAGE;
            //Logger.Debug("Set Y-offset for channel " + channel + " to " + offset + "V");
            //Offset: 0V --> 150 - swing +-0.9V
            
            //Let ADC output of 127 be the zero point of the Yoffset
            double[] c = channelSettings[channel].coefficients;
            int offsetInt = (int)(-(ProbeScaleHostToScope(channel, offset) + c[2] + c[0] * 127) / c[1]);

            FpgaSettingsMemory[r].Set((byte)Math.Max(yOffsetMin, Math.Min(yOffsetMax, -(ProbeScaleHostToScope(channel, offset) + c[2] + c[0] * 127) / c[1])));
            //Logger.Debug(String.Format("Yoffset Ch {0} set to {1} V = byteval {2}", channel, GetYOffset(channel), FpgaSettingsMemory[r].GetByte()));
        }
示例#5
0
            public static SmartScope.GainCalibration ComputeCalibration(AnalogChannel channel, double div, double mul, double[] inputVoltage, double[] adcValue, double[] yOffset)
            {
                int rows = adcValue.Length;
                int cols = 3;

                double[] matrixData = adcValue.Concat(
                                        yOffset.Concat(
                                        Enumerable.Repeat(1.0, rows)
                                        )).ToArray();

                var A = new DenseMatrix(rows, cols, matrixData);
                var B = new DenseMatrix(rows, 1, inputVoltage);
                var C = A.QR().Solve(B);
                return new SmartScope.GainCalibration()
                {
                    channel = channel,
                    divider = div,
                    multiplier = mul,
                    coefficients = C.ToColumnWiseArray()
                };
            }
示例#6
0
        public static Dictionary<AnalogChannel, AnalogWaveProperties> MeasureAutoArrangeSettings(IScope scope, AnalogChannel aciveChannel, Action<float> progressReport)
        {
            float progress = 0f;
            progressReport(progress);

            //stop scope streaming
            scope.DataSourceScope.Stop();

            //Prepare scope for test
            if (scope is SmartScope)
                (scope as SmartScope).SetDisableVoltageConversion(false);

            //set to timerange wide enough to capture 50Hz, but slightly off so smallest chance of aliasing
            const float initialTimeRange = 0.0277f;
            scope.AcquisitionMode = AcquisitionMode.AUTO;
            scope.AcquisitionLength = initialTimeRange;
            scope.SetViewPort(0, scope.AcquisitionLength);
            //s.AcquisitionDepth = 4096;
            scope.TriggerHoldOff = 0;
            scope.SendOverviewBuffer = false;

            AnalogTriggerValue atv = new AnalogTriggerValue();
            atv.channel = AnalogChannel.ChA;
            atv.direction = TriggerDirection.RISING;
            atv.level = 5000;
            scope.TriggerAnalog = atv;

            foreach (AnalogChannel ch in AnalogChannel.List)
                scope.SetCoupling(ch, Coupling.DC);

            scope.CommitSettings();
            progress += .1f;
            progressReport(progress);
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // VERTICAL == VOLTAGE

            //set to largest input range
            float maxRange = 1.2f / 1f * 36f;
            foreach (AnalogChannel ch in AnalogChannel.List)
                scope.SetVerticalRange(ch, -maxRange / 2f, maxRange / 2f);

            float[] minValues = new float[] { float.MaxValue, float.MaxValue };
            float[] maxValues = new float[] { float.MinValue, float.MinValue };
            //measure min and max voltage over 3 full ranges
            for (int i = -1; i < 2; i++)
            {
                progress += .1f;
                progressReport(progress);

                foreach (AnalogChannel ch in AnalogChannel.List)
                    scope.SetYOffset(ch, (float)i * maxRange);
                scope.CommitSettings();

                System.Threading.Thread.Sleep(100);
                scope.ForceTrigger();

                //fetch data
                DataPackageScope p = FetchLastFrame(scope);
                p = FetchLastFrame(scope); //needs this second fetch as well to get voltage conversion on ChanB right?!?

                if (p == null)
                {
                    Logger.Error("Didn't receive data from scope, aborting");
                    return null;
                }

                //check if min or max need to be updated (only in case this measurement was not saturated)
                float[] dataA = (float[])p.GetData(DataSourceType.Viewport, AnalogChannel.ChA).array;
                float[] dataB = (float[])p.GetData(DataSourceType.Viewport, AnalogChannel.ChB).array;
                float minA = dataA.Min();
                float maxA = dataA.Max();
                float minB = dataB.Min();
                float maxB = dataB.Max();

                if (minA != p.SaturationLowValue[AnalogChannel.ChA] && minA != p.SaturationHighValue[AnalogChannel.ChA] && minValues[0] > minA) minValues[0] = minA;
                if (minB != p.SaturationLowValue[AnalogChannel.ChB] && minB != p.SaturationHighValue[AnalogChannel.ChB] && minValues[1] > minB) minValues[1] = minB;
                if (maxA != p.SaturationLowValue[AnalogChannel.ChA] && maxA != p.SaturationHighValue[AnalogChannel.ChA] && maxValues[0] < maxA) maxValues[0] = maxA;
                if (maxB != p.SaturationLowValue[AnalogChannel.ChB] && maxB != p.SaturationHighValue[AnalogChannel.ChB] && maxValues[1] < maxB) maxValues[1] = maxB;
            }

            //calc ideal voltage range and offset
            float sizer = 3; //meaning 3 waves would fill entire view
            float[] coarseAmplitudes = new float[2];
            coarseAmplitudes[0] = maxValues[0] - minValues[0];
            coarseAmplitudes[1] = maxValues[1] - minValues[1];
            float[] desiredOffsets = new float[2];
            desiredOffsets[0] = (maxValues[0] + minValues[0]) / 2f;
            desiredOffsets[1] = (maxValues[1] + minValues[1]) / 2f;
            float[] desiredRanges = new float[2];
            desiredRanges[0] = coarseAmplitudes[0] * sizer;
            desiredRanges[1] = coarseAmplitudes[1] * sizer;

            //intervene in case the offset is out of range for this range
            if (desiredRanges[0] < Math.Abs(desiredOffsets[0]))
                desiredRanges[0] = Math.Abs(desiredOffsets[0]);
            if (desiredRanges[1] < Math.Abs(desiredOffsets[1]))
                desiredRanges[1] = Math.Abs(desiredOffsets[1]);

            //set fine voltage range and offset
            scope.SetVerticalRange(AnalogChannel.ChA, -desiredRanges[0] / 2f, desiredRanges[0] / 2f);
            scope.SetYOffset(AnalogChannel.ChA, -desiredOffsets[0]);
            scope.SetVerticalRange(AnalogChannel.ChB, -desiredRanges[1] / 2f, desiredRanges[1] / 2f);
            scope.SetYOffset(AnalogChannel.ChB, -desiredOffsets[1]);
            scope.CommitSettings();

            //now get data in order to find accurate lowHigh levels (as in coarse mode this was not accurate)
            DataPackageScope pFine = FetchLastFrame(scope);
            pFine = FetchLastFrame(scope); //needs this second fetch as well to get voltage conversion on ChanB right?!?

            Dictionary<AnalogChannel, float[]> dataFine = new Dictionary<AnalogChannel, float[]>();
            dataFine.Add(AnalogChannel.ChA, (float[])pFine.GetData(DataSourceType.Viewport, AnalogChannel.ChA).array);
            dataFine.Add(AnalogChannel.ChB, (float[])pFine.GetData(DataSourceType.Viewport, AnalogChannel.ChB).array);

            Dictionary<AnalogChannel, float> minimumValues = new Dictionary<AnalogChannel, float>();
            Dictionary<AnalogChannel, float> maximumValues = new Dictionary<AnalogChannel, float>();
            Dictionary<AnalogChannel, float> amplitudes = new Dictionary<AnalogChannel, float>();
            Dictionary<AnalogChannel, float> offsets = new Dictionary<AnalogChannel, float>();
            Dictionary<AnalogChannel, bool> isFlatline = new Dictionary<AnalogChannel, bool>();
            foreach (var kvp in dataFine)
            {
                minimumValues.Add(kvp.Key, kvp.Value.Min());
                maximumValues.Add(kvp.Key, kvp.Value.Max());
                amplitudes.Add(kvp.Key, kvp.Value.Max() - kvp.Value.Min());
                offsets.Add(kvp.Key, (kvp.Value.Max() + kvp.Value.Min())/2f);
                isFlatline.Add(kvp.Key, amplitudes[kvp.Key] < 0.01f);
            }

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // HORIZONTAL == FREQUENCY

            const float minTimeRange = 500f * 0.00000001f;//500 samples over full hor span
            const float maxTimeRange = 1f;

            double frequency, frequencyError, dutyCycle, dutyCycleError;
            Dictionary<AnalogChannel, double> finalFrequencies = new Dictionary<AnalogChannel, double>();
            finalFrequencies.Add(AnalogChannel.ChA, double.MaxValue);
            finalFrequencies.Add(AnalogChannel.ChB, double.MaxValue);
            int iterationCounter = 0;   //only for performance testing
            float currTimeRange = minTimeRange;
            bool continueLooping = true;
            if (isFlatline.Where(x => x.Value).ToList().Count == isFlatline.Count) //no need to find frequency in case of 2 DC signals
                continueLooping = false;
            while (continueLooping)
            {
                progress += .04f;
                progressReport(progress);

                iterationCounter++;     //only for performance testing

                scope.AcquisitionLength = currTimeRange;
                scope.SetViewPort(0, scope.AcquisitionLength);
                scope.CommitSettings();

                DataPackageScope pHor = FetchLastFrame(scope);
                pHor = FetchLastFrame(scope);
                Dictionary<AnalogChannel, float[]> timeData = new Dictionary<AnalogChannel, float[]>();
                timeData.Add(AnalogChannel.ChA, (float[])pHor.GetData(DataSourceType.Viewport, AnalogChannel.ChA).array);
                timeData.Add(AnalogChannel.ChB, (float[])pHor.GetData(DataSourceType.Viewport, AnalogChannel.ChB).array);

                foreach (var kvp in timeData)
                {
                    //make sure entire amplitude is in view
                    float currMinVal = kvp.Value.Min();
                    float currMaxVal = kvp.Value.Max();
                    float lowMarginValue = minimumValues[kvp.Key] + amplitudes[kvp.Key] * 0.1f;
                    float highMarginValue = maximumValues[kvp.Key] - amplitudes[kvp.Key] * 0.1f;
                    if (currMinVal > lowMarginValue) break;
                    if (currMaxVal < highMarginValue) break;

                    ComputeFrequencyDutyCycle(pHor.GetData(DataSourceType.Viewport, kvp.Key), out frequency, out frequencyError, out dutyCycle, out dutyCycleError);
                    if (!double.IsNaN(frequency) && (finalFrequencies[kvp.Key] == double.MaxValue))
                        finalFrequencies[kvp.Key] = frequency;
                }

                //update and check whether we've found what we were looking for
                currTimeRange *= 100f;
                bool freqFoundForAllActiveWaves = true;
                foreach (var kvp in timeData)
                    if (!isFlatline[kvp.Key] && finalFrequencies[kvp.Key] == double.MaxValue)
                        freqFoundForAllActiveWaves = false;
                continueLooping = !freqFoundForAllActiveWaves;
                if (currTimeRange > maxTimeRange)
                    continueLooping = false;
            }

            //in case of flatline or very low freq, initial value will not have changed
            foreach (AnalogChannel ch in finalFrequencies.Keys.ToList())
                if (finalFrequencies[ch] == double.MaxValue)
                    finalFrequencies[ch] = 0;

            Dictionary<AnalogChannel, AnalogWaveProperties> waveProperties = new Dictionary<AnalogChannel, AnalogWaveProperties>();
            foreach (var kvp in isFlatline)
                waveProperties.Add(kvp.Key, new AnalogWaveProperties(minimumValues[kvp.Key], maximumValues[kvp.Key], amplitudes[kvp.Key], offsets[kvp.Key], isFlatline[kvp.Key], finalFrequencies[kvp.Key]));

            return waveProperties;
        }
 private float ProbeScaleHostToScope(AnalogChannel ch, float volt)
 {
     return volt / probeSettings[ch];
 }
 public void SetYOffsetByte(AnalogChannel channel, byte offset)
 {
     REG r = channel == AnalogChannel.ChA ? REG.CHA_YOFFSET_VOLTAGE : REG.CHB_YOFFSET_VOLTAGE;
     Logger.Debug("Set Y offset for channel " + channel + " to " + offset + " (int value)");
     FpgaSettingsMemory[r].Set(offset);
 }
        public Coupling GetCoupling(AnalogChannel channel)
        {
            STR dc = channel == AnalogChannel.ChA ? STR.CHA_DCCOUPLING : STR.CHB_DCCOUPLING;

            return(StrobeMemory[dc].GetBool() ? Coupling.DC : Coupling.AC);
        }
 public ProbeDivision GetProbeDivision(AnalogChannel ch)
 {
     return(probeSettings[ch]);
 }
 public void SetProbeDivision(AnalogChannel ch, ProbeDivision division)
 {
     probeSettings[ch] = division;
     SetVerticalRange(ch, verticalRanges[ch].minimum, verticalRanges[ch].maximum);
 }
 public float GetYOffsetMin(AnalogChannel channel)
 {
     return(ConvertYOffsetByteToVoltage(channel, yOffsetMin));
 }
 private float ProbeScaleScopeToHost(AnalogChannel ch, float volt)
 {
     return(volt * probeSettings[ch]);
 }
 private float ProbeScaleHostToScope(AnalogChannel ch, float volt)
 {
     return(volt / probeSettings[ch]);
 }
 public void SetProbeDivision(AnalogChannel ch, ProbeDivision division)
 {
     probeSettings[ch] = division;
     SetVerticalRange(ch, verticalRanges[ch].minimum, verticalRanges[ch].maximum);
 }
		void SetDivider(AnalogChannel channel, double divider)
		{
			validateDivider(divider);
            byte div = (byte)(Array.IndexOf(validDividers, divider));
			int bitOffset = channel.Value * 4;
			byte mask = (byte)(0x3 << bitOffset);

			byte divMul = FpgaSettingsMemory[REG.DIVIDER_MULTIPLIER].GetByte();
			divMul = (byte)((divMul & ~mask) + (div << bitOffset));
			FpgaSettingsMemory[REG.DIVIDER_MULTIPLIER].Set(divMul);
		}
        /// <summary>
        /// Get a package of scope data
        /// </summary>
        /// <returns>Null in case communication failed, a data package otherwise. Might result in disconnecting the device if a sync error occurs</returns>
        public DataPackageScope GetScopeData()
        {
            if (hardwareInterface == null)
            {
                return(null);
            }

            byte[]           buffer;
            SmartScopeHeader header;

            try {
                buffer = hardwareInterface.GetData(BYTES_PER_BURST);
            } catch (ScopeIOException) {
                return(null);
            } catch (Exception e) {
                Logger.Error("Error while trying to get scope data: " + e.Message);
                return(null);
            }
            if (buffer == null)
            {
                return(null);
            }

            try {
                header = new SmartScopeHeader(buffer);
            } catch (Exception e) {
#if WINDOWS
                Logger.Warn("Error parsing header - attempting to fix that");
                header = ResyncHeader();
                if (header == null)
                {
                    Logger.Error("Resync header failed - resetting");
                    Reset();
                    return(null);
                }
#else
                Logger.Error("Failed to parse header - resetting scope: " + e.Message);
                Reset();
                return(null);
#endif
            }

            bool newAcquisition = currentDataPackage == null || currentDataPackage.Identifier != header.AcquisitionId;
            AcquisitionDepthLastPackage = header.AcquisitionDepth;
            SamplePeriodLastPackage     = header.SamplePeriod;
            acquiring       = header.Acquiring;
            stopPending     = header.LastAcquisition;
            awaitingTrigger = header.AwaitingTrigger;
            armed           = header.Armed;
            List <AnalogChannel> analogChannels = new List <AnalogChannel>()
            {
                AnalogChannel.ChA, AnalogChannel.ChB
            };
            Dictionary <AnalogChannel, GainCalibration> channelConfig = header.ChannelSettings(this.rom);
            Dictionary <Channel, Array> receivedData;

            //find min and max voltages for each channel, to allow saturation detection
            byte[] minMaxBytes = new byte[] { 0, 255 };
            Dictionary <Channel, float[]> minMaxVoltages = new Dictionary <Channel, float[]>();
            foreach (AnalogChannel ch in analogChannels)
            {
                minMaxVoltages.Add(ch, minMaxBytes.ConvertByteToVoltage(header.ChannelSettings(this.rom)[ch], header.GetRegister(ch.YOffsetRegister()), probeSettings[ch]));
            }

            if (header.OverviewBuffer)
            {
                buffer = hardwareInterface.GetData(OVERVIEW_BUFFER_SIZE * BYTES_PER_SAMPLE);

                if (newAcquisition)
                {
                    //This should not be possible since the overview is always sent *AFTER* the viewport data,
                    //so the last received package's identifier should match with this one
                    Logger.Warn("Got an overview buffer but no data came in for it before. This is wrong");
                    return(null);
                }
                if (buffer == null)
                {
                    //This is also pretty bad
                    Logger.Warn("Failed to get overview buffer payload. This is bad");
                    return(null);
                }

                receivedData = SplitAndConvert(buffer, analogChannels, header);
                foreach (Channel ch in receivedData.Keys)
                {
                    currentDataPackage.SetData(ChannelDataSourceScope.Overview, ch, receivedData[ch]);
                    if (ch is AnalogChannel)
                    {
                        currentDataPackage.SaturationLowValue[ch]  = minMaxVoltages[ch][0];
                        currentDataPackage.SaturationHighValue[ch] = minMaxVoltages[ch][1];
                    }
                }

                return(currentDataPackage);
            }

            if (header.FullAcquisitionDump)
            {
                buffer = hardwareInterface.GetData(header.Samples * BYTES_PER_SAMPLE);
                if (newAcquisition || buffer == null)
                {
                    Logger.Warn("Got an acquisition buffer but no data came in for it before. This is wrong");
                    return(null);
                }

                receivedData = SplitAndConvert(buffer, analogChannels, header);

                foreach (Channel ch in receivedData.Keys)
                {
                    //Here we don't use AddData since we want to assign the whole acqbuf in memory
                    // at once instead of growing it as it comes in.
                    // Need to update datapackage timestamp though!
                    ChannelData target = currentDataPackage.GetData(ChannelDataSourceScope.Acquisition, ch);
                    Array       targetArray;
                    if (target == null)
                    {
                        targetArray = Array.CreateInstance(receivedData[ch].GetType().GetElementType(), header.AcquisitionDepth);
                        currentDataPackage.SetData(ChannelDataSourceScope.Acquisition, ch, targetArray);
                        if (ch is AnalogChannel)
                        {
                            currentDataPackage.SaturationLowValue[ch]  = minMaxVoltages[ch][0];
                            currentDataPackage.SaturationHighValue[ch] = minMaxVoltages[ch][1];
                        }
                    }
                    else
                    {
                        targetArray = target.array;
                    }
                    Array.ConstrainedCopy(receivedData[ch], 0, targetArray, header.PackageOffset * header.Samples, receivedData[ch].Length);
                }

                float fullAcquisitionDumpProgress = (header.PackageOffset + 1) * (float)header.Samples / header.AcquisitionDepth;

                //update FullAcquisitionFetchProgress and fire event when finished
                float previousAcqTransferProgress = currentDataPackage.FullAcquisitionFetchProgress;
                currentDataPackage.FullAcquisitionFetchProgress = fullAcquisitionDumpProgress;
                if (currentDataPackage.FullAcquisitionFetchProgress == 1 && previousAcqTransferProgress < 1)
                {
                    currentDataPackage.UpdateTimestamp();
                    if (OnAcquisitionTransferFinished != null)
                    {
                        OnAcquisitionTransferFinished(this, new EventArgs());
                    }
                }

                return(currentDataPackage);
            }

            if (header.ImpossibleDump)
            {
                return(null);
            }

            if (header.NumberOfPayloadBursts == 0 || header.TimedOut)
            {
                return(null);
            }

            try {
                buffer = hardwareInterface.GetData(BYTES_PER_BURST * header.NumberOfPayloadBursts);
            } catch (Exception e) {
                Logger.Error("Failed to fetch payload - resetting scope: " + e.Message);
                Reset();
                return(null);
            }

            if (buffer == null)
            {
                Logger.Error("Failed to get payload - resetting");
                Reset();
                return(null);
            }

            receivedData = SplitAndConvert(buffer, analogChannels, header);

            if (newAcquisition)
            {
                if (header.PackageOffset != 0)
                {
                    Logger.Warn("Got an off-set package but didn't get any date before");
                    return(null);
                }
                /* FIXME: integrate into header*/
                AnalogChannel triggerChannel    = header.TriggerValue.channel;
                byte[]        triggerLevel      = new byte[] { header.GetRegister(REG.TRIGGER_LEVEL) };
                float[]       triggerLevelFloat = triggerLevel.ConvertByteToVoltage(header.ChannelSettings(this.rom)[triggerChannel], header.GetRegister(triggerChannel.YOffsetRegister()), probeSettings[triggerChannel]);
                header.TriggerValue.level = triggerLevelFloat[0];
                currentDataPackage        = new DataPackageScope(this.GetType(),
                                                                 header.AcquisitionDepth, header.SamplePeriod,
                                                                 header.ViewportLength, header.ViewportOffsetSamples,
                                                                 header.TriggerHoldoff, header.TriggerHoldoffSamples, header.Rolling,
                                                                 header.AcquisitionId, header.TriggerValue, header.ViewportExcess);
            }

#if DEBUG
            currentDataPackage.header = header;
            currentDataPackage.Settings["AcquisitionId"] = header.AcquisitionId;
#endif
            currentDataPackage.Settings["InputDecimation"] = header.GetRegister(REG.INPUT_DECIMATION);

            currentDataPackage.offset[ChannelDataSourceScope.Viewport]       = header.ViewportOffset;
            currentDataPackage.samplePeriod[ChannelDataSourceScope.Viewport] = header.ViewportSamplePeriod;
            foreach (Channel ch in receivedData.Keys)
            {
                currentDataPackage.AddData(ChannelDataSourceScope.Viewport, ch, receivedData[ch]);
                if (ch is AnalogChannel)
                {
                    currentDataPackage.SaturationLowValue[ch]  = minMaxVoltages[ch][0];
                    currentDataPackage.SaturationHighValue[ch] = minMaxVoltages[ch][1];
                }
            }

            foreach (AnalogChannel ch in AnalogChannel.List)
            {
                currentDataPackage.Resolution[ch] = ProbeScaleScopeToHost(ch, (float)channelConfig[ch].coefficients[0]);
                currentDataPackage.Settings["Multiplier" + ch.Name] = channelConfig[ch].multiplier;
#if DEBUG
                currentDataPackage.Settings["Divider" + ch.Name] = channelConfig[ch].divider;
                currentDataPackage.Settings["Offset" + ch.Name]  = ConvertYOffsetByteToVoltage(ch, header.GetRegister(ch.YOffsetRegister()));
#endif
            }
            return(currentDataPackage);
        }
 public Coupling GetCoupling(AnalogChannel channel)
 {
     STR dc = channel == AnalogChannel.ChA ? STR.CHA_DCCOUPLING : STR.CHB_DCCOUPLING;
     return StrobeMemory[dc].GetBool() ? Coupling.DC : Coupling.AC;
 }
 public static REG YOffsetRegister(this AnalogChannel ch)
 {
     return((ch == AnalogChannel.ChA) ? REG.CHA_YOFFSET_VOLTAGE :
            /*(ch == AnalogChannel.ChB) ?*/ REG.CHB_YOFFSET_VOLTAGE);
 }
示例#20
0
 private AnalogChannelRaw(AnalogChannel ch) : base(ch.Name + "Raw", ch.Value, typeof(byte))
 {
 }
示例#21
0
 public static AnalogChannelRaw Raw(this AnalogChannel ch)
 {
     return((AnalogChannelRaw)ch);
 }
示例#22
0
 public GainCalibration getCalibration(AnalogChannel ch, double divider, double multiplier)
 {
     return gainCalibration.Where(x => x.channel == ch && x.divider == divider && x.multiplier == multiplier).First();
 }
示例#23
0
 public void SetDummyWaveAmplitude(AnalogChannel channel, double amplitude)
 {
     ChannelConfig[channel].amplitude = amplitude;
 }
示例#24
0
 private AnalogChannelRaw(AnalogChannel ch)
     : base(ch.Name, ch.Value)
 {
 }
示例#25
0
 public void SetDummyWaveFrequency(AnalogChannel channel, double frequency)
 {
     ChannelConfig[channel].frequency = frequency;
 }
 private float ConvertYOffsetByteToVoltage(AnalogChannel channel, byte value)
 {
     double[] c = channelSettings[channel].coefficients;
     float voltageSet = (float)(-value * c[1] - c[2] - c[0] * 127.0);
     return ProbeScaleScopeToHost(channel, voltageSet);
 }
示例#27
0
 public void SetDummyWavePhase(AnalogChannel channel, double phase)
 {
     ChannelConfig[channel].phase = phase;
 }
 public float GetYOffsetMin(AnalogChannel channel) { return ConvertYOffsetByteToVoltage(channel, yOffsetMin); }
示例#29
0
 public void SetDummyWaveDutyCycle(AnalogChannel channel, double dc)
 {
     ChannelConfig[channel].dutyCycle = dc > 1 ? 1 : dc < 0 ? 0 : dc;
 }
		public float[] GetVerticalRange(AnalogChannel channel)
		{
			int dividerIndex = Array.IndexOf (validDividers, channelSettings [channel].divider);
			int multIndex = Array.IndexOf (validMultipliers, channelSettings [channel].multiplier);
			return new float[] {
				ProbeScaleScopeToHost(channel, (float)(baseVoltageRangeMin * rom.computedDividers[dividerIndex] / rom.computedMultipliers[multIndex])),

				ProbeScaleScopeToHost(channel, (float)(baseVoltageRangeMax * rom.computedDividers[dividerIndex] / rom.computedMultipliers[multIndex]))
			};
		}
示例#31
0
 public void SetDummyWaveForm(AnalogChannel channel, AnalogWaveForm w)
 {
     ChannelConfig[channel].waveform = w;
 }
 public ProbeDivision GetProbeDivision(AnalogChannel ch)
 {
     return probeSettings[ch];
 }
示例#33
0
 public void SetDummyWaveDcOffset(AnalogChannel channel, double dcOffset)
 {
     ChannelConfig[channel].dcOffset = dcOffset;
 }
		void SetMultiplier(AnalogChannel channel, double multiplier)
		{
			validateMultiplier(multiplier);

			int bitOffset = channel.Value * 4;
			byte mul = (byte)(Array.IndexOf(validMultipliers, multiplier) << 2);
			byte mask = (byte)(0xC << bitOffset);

			byte divMul = FpgaSettingsMemory[REG.DIVIDER_MULTIPLIER].GetByte();
			divMul = (byte)((divMul & ~mask) + (mul << bitOffset));
			FpgaSettingsMemory[REG.DIVIDER_MULTIPLIER].Set(divMul);
		}
示例#35
0
 public void SetDummyWaveDcOffset(AnalogChannel channel, int bursts)
 {
     ChannelConfig[channel].bursts = bursts;
 }
 public void SetCoupling(AnalogChannel channel, Coupling coupling)
 {
     STR dc = channel == AnalogChannel.ChA ? STR.CHA_DCCOUPLING : STR.CHB_DCCOUPLING;
     bool enableDc = coupling == Coupling.DC;
     //Logger.Debug("Set DC coupling for channel " + channel + (enableDc ? " ON" : " OFF"));
     StrobeMemory[dc].Set(enableDc);
 }
示例#37
0
 public void SetNoiseAmplitude(AnalogChannel channel, double noiseAmplitude)
 {
     ChannelConfig[channel].noise = noiseAmplitude;
 }
 /// <summary>
 /// Choose channel upon which to trigger
 /// </summary>
 /// <param name="channel"></param>
 public void SetTriggerChannel(AnalogChannel channel)
 {
     this.triggerAnalog.channel = channel;
     TriggerAnalog = this.triggerAnalog;
 }
示例#39
0
 public void SetVerticalRange(AnalogChannel ch, float minimum, float maximum)
 {
 }
 private float ProbeScaleScopeToHost(AnalogChannel ch, float volt)
 {
     return volt * probeSettings[ch];
 }
示例#41
0
        private Dictionary <Channel, Array> SplitAndConvert(byte[] buffer, List <AnalogChannel> channels, SmartScopeHeader header, Dictionary <AnalogChannel, SmartScope.GainCalibration> channelSettings, int offset, int length)
        {
            int n_channels = channels.Count;
            int n_samples  = length / n_channels;

            byte[][]  splitRaw  = new byte[n_channels][];
            float[][] splitVolt = new float[n_channels][];

            for (int j = 0; j < n_channels; j++)
            {
                splitRaw[j]  = new byte[n_samples];
                splitVolt[j] = new float[n_samples];
            }

            //this section converts twos complement to a physical voltage value
            Dictionary <Channel, Array> result = new Dictionary <Channel, Array>();

            for (int j = 0; j < n_channels; j++)
            {
                AnalogChannel ch    = channels[j];
                double[]      coeff = channelSettings[ch].coefficients;
                if (coeff.Length != 3)
                {
                    throw new Exception(String.Format("Calibration coefficients are not of length 3, but {0} for ch {1} (n_ch:{2}", coeff.Length, ch.Name, n_channels));
                }
                byte  yOffset     = header.GetRegister(ch.YOffsetRegister());
                float gain        = probeSettings[ch];
                float totalOffset = (float)(yOffset * coeff[1] + coeff[2]);

                int k = j;
                if (offset + n_channels * (n_samples - 1) + k >= buffer.Length)
                {
                    throw new Exception(String.Format("Buffer will be addressed out of bounds. [offset:{0}][n_chan:{1}][length:{2}][n_samp:{3}][buf_len:{4}]", offset, n_channels, length, n_samples, buffer.Length));
                }
                for (int i = 0; i < n_samples; i++)
                {
                    byte b = buffer[offset + k];
                    splitRaw[j][i]  = b;
                    splitVolt[j][i] = (float)(b * coeff[0] + totalOffset) * gain;
                    k += n_channels;
                }
            }

            for (int j = 0; j < n_channels; j++)
            {
                AnalogChannel ch = channels[j];
                if (header.GetStrobe(STR.LA_ENABLE) && header.GetStrobe(STR.LA_CHANNEL) == ch.Value > 0)
                {
                    if (j >= splitRaw.Length)
                    {
                        throw new Exception(String.Format("Assigning LA channel failing due to oob index {1} (len = {2})", j, splitRaw.Length));
                    }
                    result[LogicAnalyserChannel.LA] = splitRaw[j];
                }
                else
                {
                    if (j >= splitVolt.Length)
                    {
                        throw new Exception(String.Format("Assigning Voltage channel failing due to oob index {1} (len = {2})", j, splitVolt.Length));
                    }
                    result[ch] = splitVolt[j];
                }
                if (j >= splitRaw.Length)
                {
                    throw new Exception(String.Format("Assigning RAW failing due to oob index {1} (len = {2})", j, splitRaw.Length));
                }
                result[ch.Raw()] = splitRaw[j];
            }
            return(result);
        }