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);
        }
Beispiel #2
0
        /// <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);
            }
        }
Beispiel #4
0
        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
            }));
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
 /// <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);
        }
Beispiel #10
0
        /// <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);
        }