public RfsgTask(SequenceData sequence, SettingsData settings, int channelID, string rfsgDeviceName, DeviceSettings deviceSettings) { if (!settings.logicalChannelManager.GPIBs.ContainsKey(channelID)) { throw new InvalidDataException("Attempted to create an rfsg task with channel id " + channelID + ", which does not exist in the settings as a gpib channel."); } this.channelID = channelID; int currentStepIndex = -1; //measured in ticks. 1 tick = 100 ns. long currentTime = 0; commandBuffer = new List<RFSGCommand>(); if (deviceSettings.AutoInitate) { RFSGCommand com = new RFSGCommand(); com.commandTime = 0; com.commandType = RFSGCommand.CommandType.Initiate; commandBuffer.Add(com); } if (deviceSettings.AutoEnable) { RFSGCommand com = new RFSGCommand(); com.commandTime = 0; com.commandType = RFSGCommand.CommandType.EnableOutput; commandBuffer.Add(com); } long postRetriggerTime = 100; // corresponds to 10us. // A workaround to issue when using software timed groups in // fpga-retriggered words // the workaround: delay the software timed group by an immesurable amount // if it is started in a retriggered word // This functionality is sort of somewhat duplicated in sequencedata.generatebuffers. It would be good // to come up with a more coherent framework to do these sorts of operations. while (true) { currentStepIndex++; if (currentStepIndex >= sequence.TimeSteps.Count) break; TimeStep currentStep = sequence.TimeSteps[currentStepIndex]; if (!currentStep.StepEnabled) continue; if (currentStep.GpibGroup == null || !currentStep.GpibGroup.channelEnabled(channelID)) { currentTime += seconds_to_ticks(currentStep.StepDuration.getBaseValue()); continue; } long postTime = 0; if (currentStep.RetriggerOptions.WaitForRetrigger) postTime = postRetriggerTime; // determine the index of the next step in which this channel has an action int nextEnabledStepIndex = sequence.findNextGpibChannelEnabledTimestep(currentStepIndex, channelID); long groupDuration = seconds_to_ticks(sequence.timeBetweenSteps(currentStepIndex, nextEnabledStepIndex)); // now take action: GPIBGroupChannelData channelData = currentStep.GpibGroup.getChannelData(channelID); if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.raw_string) { throw new Exception("Not yet implemented."); /* // Raw string commands just get added string stringWithCorrectNewlines = AddNewlineCharacters(channelData.RawString); commandBuffer.Add(new GpibCommand(stringWithCorrectNewlines, currentTime));*/ } else if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.voltage_frequency_waveform) { double[] amplitudeArray; double[] frequencyArray; // get amplitude and frequency value arrays int nSamples = (int)(ticks_to_seconds(groupDuration) * (double)deviceSettings.SampleClockRate); double secondsPerSample = ticks_to_seconds(groupDuration) / (double)nSamples; amplitudeArray = channelData.volts.getInterpolation(nSamples, 0, ticks_to_seconds(groupDuration), sequence.Variables, sequence.CommonWaveforms); frequencyArray = channelData.frequency.getInterpolation(nSamples, 0, ticks_to_seconds(groupDuration), sequence.Variables, sequence.CommonWaveforms); double lastFreq = Double.MinValue; double lastAmp = Double.MinValue; for (int i = 0; i < nSamples; i++) { double currentFreq = frequencyArray[i]; double currentAmp = amplitudeArray[i]; if (currentFreq != lastFreq || currentAmp != lastAmp) { RFSGCommand command = new RFSGCommand(); command.commandType = RFSGCommand.CommandType.AmplitudeFrequency; command.frequency = currentFreq; command.amplitude = Vpp_to_dBm(currentAmp); command.commandTime = (long)(currentTime + i * secondsPerSample * 10000000) + postTime; commandBuffer.Add(command); } lastAmp = currentAmp; lastFreq = currentFreq; } } else if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.string_param_string) { foreach (StringParameterString sps in channelData.StringParameterStrings) { string clean = sps.Prefix.Trim().ToUpper(); if (clean == "ENABLE") { RFSGCommand com = new RFSGCommand(); com.commandType = RFSGCommand.CommandType.EnableOutput; com.commandTime = currentTime + postTime; commandBuffer.Add(com); } if (clean == "DISABLE") { RFSGCommand com = new RFSGCommand(); com.commandType = RFSGCommand.CommandType.DisableOutput; com.commandTime = currentTime + postTime; commandBuffer.Add(com); } if (clean == "ABORT") { RFSGCommand com = new RFSGCommand(); com.commandType = RFSGCommand.CommandType.Abort; com.commandTime = currentTime + postTime; commandBuffer.Add(com); } if (clean == "INITIATE") { RFSGCommand com = new RFSGCommand(); com.commandType = RFSGCommand.CommandType.Initiate; com.commandTime = currentTime + postTime; commandBuffer.Add(com); } } } currentTime += seconds_to_ticks(currentStep.StepDuration.getBaseValue()); } if (rfsgDevices == null) { rfsgDevices = new Dictionary<string, niRFSG>(); rfsgDeviceInitiated = new Dictionary<niRFSG, bool>(); } if (rfsgDevices.ContainsKey(rfsgDeviceName)) { rfsgDevice = rfsgDevices[rfsgDeviceName]; } else { try { rfsgDevice = new niRFSG(rfsgDeviceName, true, false); } catch (Exception e) { throw new InvalidDataException("Caught exception when attempting to instantiate an rfsg device named " + rfsgDeviceName + ". Maybe a device by this name does not exist? Exception message: " + e.Message); } rfsgDevices.Add(rfsgDeviceName, rfsgDevice); rfsgDeviceInitiated.Add(rfsgDevice, false); } if (deviceSettings.MasterTimebaseSource != null && deviceSettings.MasterTimebaseSource != "") { rfsgDevice.ConfigureRefClock(deviceSettings.MasterTimebaseSource, 10000000); } }
public bool generateBuffer(SequenceData sequence, DeviceSettings deviceSettings, HardwareChannel hc, int logicalChannelID) { this.logicalChannelID = logicalChannelID; commandBuffer = new List<RS232Command>(); if (deviceSettings.StartTriggerType != DeviceSettings.TriggerType.SoftwareTrigger) { throw new Exception("RS232 devices must have a software start trigger."); } // List<TimeStep> enabledSteps = sequence.enabledTimeSteps(); int currentStepIndex = -1; //measured in ticks. 1 tick = 100 ns. long currentTime = 0; // This functionality is sort of somewhat duplicated in sequencedata.generatebuffers. It would be good // to come up with a more coherent framework to do these sorts of operations. while (true) { currentStepIndex++; if (currentStepIndex >= sequence.TimeSteps.Count) break; TimeStep currentStep = sequence.TimeSteps[currentStepIndex]; if (!currentStep.StepEnabled) continue; if (currentStep.rs232Group == null || !currentStep.rs232Group.channelEnabled(logicalChannelID)) { currentTime += seconds_to_ticks(currentStep.StepDuration.getBaseValue()); continue; } // determine the index of the next step in which this channel has an action int nextEnabledStepIndex = sequence.findNextRS232ChannelEnabledTimestep(currentStepIndex, logicalChannelID); long groupDuration = seconds_to_ticks(sequence.timeBetweenSteps(currentStepIndex, nextEnabledStepIndex)); // now take action: RS232GroupChannelData channelData = currentStep.rs232Group.getChannelData(logicalChannelID); if (channelData.DataType == RS232GroupChannelData.RS232DataType.Raw) { // Raw string commands just get added string stringWithCorrectNewlines = AddNewlineCharacters(channelData.RawString); commandBuffer.Add(new RS232Command( stringWithCorrectNewlines, currentTime)); } else if (channelData.DataType == RS232GroupChannelData.RS232DataType.Parameter) { if (channelData.StringParameterStrings != null) { foreach (StringParameterString srs in channelData.StringParameterStrings) { commandBuffer.Add(new RS232Command( AddNewlineCharacters(srs.ToString()), currentTime)); } } } currentTime += seconds_to_ticks(currentStep.StepDuration.getBaseValue()); } return true; }
public bool generateBuffer(SequenceData sequence, DeviceSettings deviceSettings, HardwareChannel hc, int logicalChannelID, List<GpibRampCommandConverter> commandConverters) { this.logicalChannelID = logicalChannelID; this.deviceType = hc.GpibDeviceType; commandBuffer = new List<GpibCommand>(); if (deviceSettings.StartTriggerType != DeviceSettings.TriggerType.SoftwareTrigger) { throw new Exception("GPIB devices must have a software start trigger."); } // start by adding the initialization string to the command buffer // this does nothing for unknown device types // Modified by REO 11/25/08: Null strings produce errors if written to device, so check if(HardwareChannel.HardwareConstants.gpibInitializationCommands[(int)deviceType]!= null) commandBuffer.Add(new GpibCommand(HardwareChannel.HardwareConstants.gpibInitializationCommands[(int)deviceType], 0)); if (deviceType == HardwareChannel.HardwareConstants.GPIBDeviceType.Unknown) { foreach (GpibRampCommandConverter conv in commandConverters) { //Modified by REO 11/25/08: Null strings produce errors if written to device, so check if (deviceSettings.DeviceDescription.Contains(conv.DeviceIdentifierSubstring) && conv.InitializationCommand != null) commandBuffer.Add(new GpibCommand(AddNewlineCharacters(conv.InitializationCommand), 0)); } } int currentStepIndex = - 1; //measured in ticks. 1 tick = 100 ns. long currentTime = 0; // This functionality is sort of somewhat duplicated in sequencedata.generatebuffers. It would be good // to come up with a more coherent framework to do these sorts of operations. while (true) { currentStepIndex++; if (currentStepIndex >= sequence.TimeSteps.Count) break; TimeStep currentStep = sequence.TimeSteps[currentStepIndex]; if (!currentStep.StepEnabled) continue; if (currentStep.GpibGroup == null || !currentStep.GpibGroup.channelEnabled(logicalChannelID)) { currentTime += seconds_to_ticks(currentStep.StepDuration.getBaseValue()); continue; } // determine the index of the next step in which this channel has an action int nextEnabledStepIndex = sequence.findNextGpibChannelEnabledTimestep(currentStepIndex, logicalChannelID); long groupDuration = seconds_to_ticks(sequence.timeBetweenSteps(currentStepIndex, nextEnabledStepIndex)); // now take action: GPIBGroupChannelData channelData = currentStep.GpibGroup.getChannelData(logicalChannelID); if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.raw_string) { // Raw string commands just get added string stringWithCorrectNewlines = AddNewlineCharacters(channelData.RawString); commandBuffer.Add(new GpibCommand( stringWithCorrectNewlines, currentTime)); } else if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.voltage_frequency_waveform) { GpibRampCommandConverter rampConverter = null; switch (hc.GpibDeviceType) { case HardwareChannel.HardwareConstants.GPIBDeviceType.Unknown: { foreach (GpibRampCommandConverter conv in commandConverters) { if (deviceSettings.DeviceDescription.Contains(conv.DeviceIdentifierSubstring)) rampConverter = conv; } if (rampConverter == null) { throw new Exception("Voltage/frequency ramp not supported for unknown gpib device " + hc.ToString() + "."); } } break; case HardwareChannel.HardwareConstants.GPIBDeviceType.Agilent_ESG_SIG_Generator: { rampConverter = ESG_SeriesRampConverter; } break; } double[] amplitudeArray; double[] frequencyArray; // get amplitude and frequency value arrays int nSamples = (int)(ticks_to_seconds(groupDuration) * (double)deviceSettings.SampleClockRate); double secondsPerSample = ticks_to_seconds(groupDuration) / (double) nSamples; amplitudeArray = channelData.volts.getInterpolation(nSamples, 0, ticks_to_seconds(groupDuration), sequence.Variables, sequence.CommonWaveforms); frequencyArray = channelData.frequency.getInterpolation(nSamples, 0, ticks_to_seconds(groupDuration), sequence.Variables, sequence.CommonWaveforms); List<DoubleIntPair> amplitudeIndexPairs = ConvertArrayToIndexValuePairs(amplitudeArray); List<DoubleIntPair> frequencyIndexPairs = ConvertArrayToIndexValuePairs(frequencyArray); int amplitudeIndex = 0; int frequencyIndex = 0; for (int i = 0; i < nSamples; i++) { bool amplitudeMatch = false; bool frequencyMatch = false; // determine if there is either a amplitude or frequency data point for this sample number if (amplitudeIndex < amplitudeIndexPairs.Count) amplitudeMatch = amplitudeIndexPairs[amplitudeIndex].myInt == i; if (frequencyIndex < frequencyIndexPairs.Count) frequencyMatch = frequencyIndexPairs[frequencyIndex].myInt == i; if (amplitudeIndex >= amplitudeIndexPairs.Count && frequencyIndex >= frequencyIndexPairs.Count) break; if (amplitudeMatch || frequencyMatch) { string command = ""; if (amplitudeMatch) { command += rampConverter.amplitudeCommand(amplitudeIndexPairs[amplitudeIndex].myDouble); amplitudeIndex++; } if (frequencyMatch) { command += rampConverter.frequencyCommand(frequencyIndexPairs[frequencyIndex].myDouble); frequencyIndex++; } long commandTime = currentTime + seconds_to_ticks((double)i * secondsPerSample); commandBuffer.Add(new GpibCommand(command, commandTime)); } } } else if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.string_param_string) { if (channelData.StringParameterStrings != null) { foreach (StringParameterString sps in channelData.StringParameterStrings) { string commandWithCorrectNewlines = AddNewlineCharacters(sps.ToString()); commandBuffer.Add(new GpibCommand(commandWithCorrectNewlines, currentTime)); } } } currentTime += seconds_to_ticks(currentStep.StepDuration.getBaseValue()); } return true; }