public static void DownloadWaveform(NIRfsg rfsgHandle, Waveform waveform) { IntPtr rfsgPtr = rfsgHandle.GetInstrumentHandle().DangerousGetHandle(); rfsgHandle.Abort(); rfsgHandle.RF.PowerLevelType = RfsgRFPowerLevelType.PeakPower; try { rfsgHandle.Arb.ClearWaveform(waveform.WaveformName); //Clear existing waveform to avoid erros } catch (Ivi.Driver.OutOfRangeException) { //Intentionally ignore this exception; clearing the waveform failed because it doesn't exist } rfsgHandle.Arb.WriteWaveform(waveform.WaveformName, waveform.WaveformData); //Store loaded parameters NIRfsgPlayback.StoreWaveformSignalBandwidth(rfsgPtr, waveform.WaveformName, waveform.SignalBandwidth_Hz); NIRfsgPlayback.StoreWaveformPapr(rfsgPtr, waveform.WaveformName, waveform.PAPR_dB); NIRfsgPlayback.StoreWaveformBurstStartLocations(rfsgPtr, waveform.WaveformName, waveform.BurstStartLocations); NIRfsgPlayback.StoreWaveformBurstStopLocations(rfsgPtr, waveform.WaveformName, waveform.BurstStopLocations); NIRfsgPlayback.StoreWaveformSampleRate(rfsgPtr, waveform.WaveformName, waveform.SampleRate); //Manually configure additional settings NIRfsgPlayback.StoreWaveformLOOffsetMode(rfsgPtr, waveform.WaveformName, NIRfsgPlaybackLOOffsetMode.Disabled); NIRfsgPlayback.StoreWaveformRuntimeScaling(rfsgPtr, waveform.WaveformName, -1.5); NIRfsgPlayback.StoreWaveformRFBlankingEnabled(rfsgPtr, waveform.WaveformName, false); }
/// <summary>Configures common instrument settings for generation.</summary> /// <param name="rfsgHandle">The open RFSG session to configure.</param> /// <param name="instrConfig">The common instrument settings to configure.</param> public static void ConfigureInstrument(NIRfsg rfsgHandle, InstrumentConfiguration instrConfig) { rfsgHandle.SignalPath.SelectedPorts = instrConfig.SelectedPorts; rfsgHandle.RF.ExternalGain = -instrConfig.ExternalAttenuation_dB; rfsgHandle.RF.Configure(instrConfig.CarrierFrequency_Hz, instrConfig.DutAverageInputPower_dBm); rfsgHandle.FrequencyReference.Source = RfsgFrequencyReferenceSource.FromString(instrConfig.ReferenceClockSource); // Only configure LO settings on supported VSTs if (Regex.IsMatch(rfsgHandle.Identity.InstrumentModel, "NI PXIe-58[34].")) // Matches 583x and 584x VST families { IntPtr rfsgPtr = rfsgHandle.GetInstrumentHandle().DangerousGetHandle(); NIRfsgPlayback.RetrieveAutomaticSGSASharedLO(rfsgPtr, "", out RfsgPlaybackAutomaticSGSASharedLO currentMode); if (instrConfig.LOSharingMode == LocalOscillatorSharingMode.None && currentMode != RfsgPlaybackAutomaticSGSASharedLO.Disabled) { //Setting this property resets other settings, which can create issues. Hence, it is only set if the value //is different than the current mode. NIRfsgPlayback.StoreAutomaticSGSASharedLO(rfsgPtr, "", RfsgPlaybackAutomaticSGSASharedLO.Disabled); } else if (instrConfig.LOSharingMode == LocalOscillatorSharingMode.Automatic && currentMode != RfsgPlaybackAutomaticSGSASharedLO.Enabled) { //Setting this property resets other settings, which can create issues. Hence, it is only set if the value //is different than the current mode. NIRfsgPlayback.StoreAutomaticSGSASharedLO(rfsgPtr, "", RfsgPlaybackAutomaticSGSASharedLO.Enabled); } } //Do nothing; any configuration for LOs with standalone VSGs should be configured manually. //Baseband instruments don't have LOs. Unsupported VSTs must be configured manually. }
void StartGeneration() { string rfsgName = resourceNameComboBox.Text; double freq = (double)frequencyNumeric.Value; double power = (double)powerLevelNumeric.Value; try { rfsgSession = new NIRfsg(rfsgName, true, false); rfsgHandle = rfsgSession.GetInstrumentHandle().DangerousGetHandle(); int i = 0; foreach (string tdmsPath in tdmsFilePaths) { NIRfsgPlayback.ReadAndDownloadWaveformFromFile(rfsgHandle, tdmsPath, tdmsWaveformNames[i]); i++; } //Q: Is it acceptable to utilize mostly private class data and keep prototype empty? I suppose if I don't aniticpate any reuse I can leave it empty... string autoScript = ScriptGen(); NIRfsgPlayback.SetScriptToGenerateSingleRfsg(rfsgHandle, autoScript); rfsgSession.RF.Configure(freq, power); rfsgSession.Initiate(); } catch (Exception uhOh) { ShowError("Start Generation", uhOh); } }
public override Task <RfsgServiceSession> Initialize(RfsgServiceResource request, ServerCallContext context) { var rfsg = new NIRfsg(request.Name, request.IdQuery, request.Reset, request.OptionString); var handle = rfsg.GetInstrumentHandle().DangerousGetHandle(); sessionMap.Add(handle, rfsg); return(Task.FromResult(new RfsgServiceSession() { Handle = (long)handle })); }
public WlanSweep(string resourceName) { rfsgSession = new NIRfsg(resourceName, false, false, "DriverSetup=Bitfile:NI-RFIC.lvbitx"); rfsgHandle = rfsgSession.GetInstrumentHandle().DangerousGetHandle(); instr = new RFmxInstrMX(resourceName, "RFmxSetup=Bitfile:NI-RFIC.lvbitx"); wlan = instr.GetWlanSignalConfiguration(); instr.DangerousGetNIRfsaHandle(out IntPtr rfsaHandle); powerServo = new niPowerServo(rfsaHandle, false); }
/// <summary>Calls <see cref="NIRfsgPlayback.SetScriptToGenerateSingleRfsg(IntPtr, string)"/>, which will download the script contained in <paramref name="waveform"/> and apply /// all associated parameters.</summary> /// <param name="rfsgHandle">The open RFSG session to configure.</param> /// <param name="waveform">Specifies the waveform and its associated script that is to be used for generation.</param> public static void ApplyWaveformAttributes(NIRfsg rfsgHandle, Waveform waveform) { if (string.IsNullOrEmpty(waveform.Script)) // default to continuous if no script in waveform { ConfigureContinuousGeneration(rfsgHandle, waveform); } else { IntPtr rfsgPtr = rfsgHandle.GetInstrumentHandle().DangerousGetHandle(); NIRfsgPlayback.SetScriptToGenerateSingleRfsg(rfsgPtr, waveform.Script); } }
public void PaprCalcAgreesWithCalculated() { LoopFiles((fileName, waveform, filePath, fileConfig) => { System.IntPtr rfsgHandle = sim.GetInstrumentHandle().DangerousGetHandle(); NIRfsgPlayback.DownloadUserWaveform(rfsgHandle, waveform.Name, waveform.Data, true); NIRfsgPlayback.RetrieveWaveformPapr(rfsgHandle, waveform.Name, out double calcPapr); waveform.PAPR_dB.Should().BeApproximately(calcPapr, 0.1, $"of loading file \"{fileName}\""); }); }
public static Waveform GetWaveformParametersByName(NIRfsg rfsgHandle, string waveformName) { IntPtr rfsgPtr = rfsgHandle.GetInstrumentHandle().DangerousGetHandle(); Waveform waveform = new Waveform { WaveformName = waveformName }; NIRfsgPlayback.RetrieveWaveformSignalBandwidth(rfsgPtr, waveformName, out waveform.SignalBandwidth_Hz); NIRfsgPlayback.RetrieveWaveformPapr(rfsgPtr, waveformName, out waveform.PAPR_dB); NIRfsgPlayback.RetrieveWaveformSampleRate(rfsgPtr, waveformName, out waveform.SampleRate); NIRfsgPlayback.RetrieveWaveformBurstStartLocations(rfsgPtr, waveformName, ref waveform.BurstStartLocations); NIRfsgPlayback.RetrieveWaveformBurstStopLocations(rfsgPtr, waveformName, ref waveform.BurstStopLocations); waveform.BurstLength_s = CalculateWaveformDuration(waveform.BurstStartLocations, waveform.BurstStopLocations, waveform.SampleRate); return(waveform); }
public static void ConfigureContinuousGeneration(NIRfsg rfsgHandle, Waveform waveform, string waveformStartTriggerExport = "PXI_Trig0") { //Configure the trigger to be generated on the first sample of each waveform generation, //denoted in the script below as "marker0" rfsgHandle.DeviceEvents.MarkerEvents[0].ExportedOutputTerminal = RfsgMarkerEventExportedOutputTerminal.FromString(waveformStartTriggerExport); //A software trigger is configured that is used in the script below to control generation of //the script. This ensures that a complete packet is always generated before aborting, and //allows all generation functions to share a single abort function. rfsgHandle.Triggers.ScriptTriggers[0].ConfigureSoftwareTrigger(); string script = $@"script REPEAT{waveform.WaveformName} repeat until ScriptTrigger0 generate {waveform.WaveformName} marker0(0) end repeat end script"; //Get the instrument handle to utilize with the RFSGPlayback library IntPtr rfsgPtr = rfsgHandle.GetInstrumentHandle().DangerousGetHandle(); //Download the newly created script for generation when "Initiate" is called NIRfsgPlayback.SetScriptToGenerateSingleRfsg(rfsgPtr, script); }
/// <summary>Downloads a previously loaded waveform to the instrument and sets associated properties.</summary> /// <param name="rfsgHandle">The open RFSG session to configure.</param> /// <param name="waveform">The waveform data and associated properties to download to the instrument. Use <see cref="LoadWaveformFromTDMS(string, string)"/> to load a waveform from a TDMS file.</param> public static void DownloadWaveform(NIRfsg rfsgHandle, Waveform waveform) { IntPtr rfsgPtr = rfsgHandle.GetInstrumentHandle().DangerousGetHandle(); rfsgHandle.Abort(); try { rfsgHandle.Arb.ClearWaveform(waveform.Name); //Clear existing waveform to avoid erros } catch (Exception ex) { if (ex is Ivi.Driver.OutOfRangeException || ex is Ivi.Driver.IviCDriverException) { } //Intentionally ignore this exception; clearing the waveform failed because it doesn't exist else { throw; } } rfsgHandle.RF.PowerLevelType = RfsgRFPowerLevelType.PeakPower; // set power level to peak before writing so RFSG doesn't scale waveform rfsgHandle.Arb.WriteWaveform(waveform.Name, waveform.Data); //Store loaded parameters NIRfsgPlayback.StoreWaveformSignalBandwidth(rfsgPtr, waveform.Name, waveform.SignalBandwidth_Hz); NIRfsgPlayback.StoreWaveformPapr(rfsgPtr, waveform.Name, waveform.PAPR_dB); NIRfsgPlayback.StoreWaveformBurstStartLocations(rfsgPtr, waveform.Name, waveform.BurstStartLocations); NIRfsgPlayback.StoreWaveformBurstStopLocations(rfsgPtr, waveform.Name, waveform.BurstStopLocations); NIRfsgPlayback.StoreWaveformSampleRate(rfsgPtr, waveform.Name, waveform.SampleRate); NIRfsgPlayback.StoreWaveformRuntimeScaling(rfsgPtr, waveform.Name, waveform.RuntimeScaling); NIRfsgPlayback.StoreWaveformSize(rfsgPtr, waveform.Name, waveform.Data.SampleCount); //Manually configure additional settings NIRfsgPlayback.StoreWaveformLOOffsetMode(rfsgPtr, waveform.Name, NIRfsgPlaybackLOOffsetMode.Auto); NIRfsgPlayback.StoreWaveformRFBlankingEnabled(rfsgPtr, waveform.Name, false); }
public static void ConfigureBurstedGeneration(NIRfsg rfsgHandle, Waveform waveform, WaveformTimingConfiguration waveTiming, PAENConfiguration paenConfig, out double period, out double idleTime) { IntPtr rfsgPtr = rfsgHandle.GetInstrumentHandle().DangerousGetHandle(); rfsgHandle.Arb.GenerationMode = RfsgWaveformGenerationMode.Script; string scriptName = String.Format("{0}{1}", waveform.WaveformName, waveTiming.DutyCycle_Percent); if (waveTiming.DutyCycle_Percent <= 0) { throw new System.ArgumentOutOfRangeException("DutyCycle_Percent", waveTiming.DutyCycle_Percent, "Duty cycle must be greater than 0 %"); } //Calculate various timining information double dutyCycle = waveTiming.DutyCycle_Percent / 100; double totalBurstTime = waveTiming.PreBurstTime_s + waveform.BurstLength_s + waveTiming.PostBurstTime_s; idleTime = (totalBurstTime / dutyCycle) - totalBurstTime; period = totalBurstTime + idleTime; //Convert all time based values to sample based values long preBurstSamp, postBurstSamp, idleSamp, enableSamples, disableSamples; preBurstSamp = TimeToSamples(waveTiming.PreBurstTime_s, waveform.SampleRate); postBurstSamp = TimeToSamples(waveTiming.PostBurstTime_s, waveform.SampleRate); idleSamp = TimeToSamples(idleTime, waveform.SampleRate); enableSamples = TimeToSamples(paenConfig.CommandEnableTime_s, waveform.SampleRate); disableSamples = TimeToSamples(paenConfig.CommandDisableTime_s, waveform.SampleRate); //RFSG enforces a minimum wait time of 8 samples, so ensure that the minimum pre/post burst time // and idle time are at least 8 samples long if (preBurstSamp < 8) { preBurstSamp = 8; } if (postBurstSamp < 8) { postBurstSamp = 8; } if (idleSamp < 8) { idleSamp = 8; } //Initialize the script StringBuilder with the first line of the script (name) StringBuilder sb = new StringBuilder($"script {scriptName}"); sb.AppendLine(); #region Script Building //If we have a static PA Enable mode, ensure that we trigger at the beginning of the script prior to looping. if (paenConfig.PAEnableMode == PAENMode.Static) { sb.AppendLine("wait 8 marker1(7)"); } //Configure for endless repeating sb.AppendLine("Repeat until scriptTrigger0"); //Configure the idle time prior to each packet generation sb.Append($"wait {idleSamp}"); //If PAEN Mode is dynamic we need to trigger the PA to enable if (paenConfig.PAEnableMode == PAENMode.Dynamic) { //PA Enable is triggered at or before the last sample of the wait period long PAEnableTriggerLoc = idleSamp - enableSamples - 1; sb.Append($" marker1({PAEnableTriggerLoc})"); } sb.AppendLine(); //Configure waiting for the pre-burst time sb.AppendLine($"wait {preBurstSamp}"); //Configure generation of the selected waveform but only for the burst length; send a trigger at the beginning of each burst sb.Append($"generate {waveform.WaveformName} subset({waveform.BurstStartLocations[0]},{waveform.BurstStopLocations[0]}) marker0(0)"); //Check to see if the command time is longer than the post-burst time, which determines when the PA disable command needs sent bool LongCommand = waveTiming.PostBurstTime_s <= paenConfig.CommandDisableTime_s; if (paenConfig.PAEnableMode == PAENMode.Dynamic && LongCommand) { //Trigger is placed a number of samples from the end of the burst corresponding with //how much longer than the post burst time it is long PADisableTriggerLoc = waveform.BurstStopLocations[0] - (disableSamples - postBurstSamp) - 1; sb.Append($" marker1({PADisableTriggerLoc})"); } sb.AppendLine(); //Configure waiting for the post-burst time sb.Append($"wait {postBurstSamp}"); //If the ommand time is shorter than the post-burst time, the disable trigger must be sent //during the post-burst time if (paenConfig.PAEnableMode == PAENMode.Dynamic && !LongCommand) { long PADisableTriggerLoc = postBurstSamp - disableSamples - 1; sb.Append($" marker1({PADisableTriggerLoc})"); } sb.AppendLine(); //Close out the script sb.AppendLine("end repeat"); //If we have a static PA Enable mode, ensure that we trigger at the end of the script prior to concluding. if (paenConfig.PAEnableMode == PAENMode.Static) { sb.AppendLine("wait 10 marker1(0)"); } sb.AppendLine("end script"); #endregion //Download the generation script to the generator for later initiation NIRfsgPlayback.SetScriptToGenerateSingleRfsg(rfsgPtr, sb.ToString()); //Configure the triggering for PA enable if selected if (paenConfig.PAEnableMode != PAENMode.Disabled) { rfsgHandle.DeviceEvents.MarkerEvents[1].ExportedOutputTerminal = RfsgMarkerEventExportedOutputTerminal.FromString( paenConfig.PAEnableTriggerExportTerminal); rfsgHandle.DeviceEvents.MarkerEvents[1].OutputBehaviour = paenConfig.PAEnableTriggerMode; //Configure scriptTrigger0 for software triggering. This way, when it is time to abort we can stop //the loop and trigger the appropriate off command if PAEN mode is Static rfsgHandle.Triggers.ScriptTriggers[0].ConfigureSoftwareTrigger(); } //Configure the trigger to be generated on the first sample of each waveform generation, //denoted in the script below as "marker0" rfsgHandle.DeviceEvents.MarkerEvents[0].ExportedOutputTerminal = RfsgMarkerEventExportedOutputTerminal.FromString(waveTiming.BurstStartTriggerExport); }