public void CheckGeneration() { if (!Environs.Debug) { _generating = _rfsgSession.CheckGenerationStatus(); } }
/// <summary>Acquires the incoming signal, trains the DPD model, applies the memory polynomial to the reference waveform, and downloads the predistorted waveform to the generator. /// If generation is in progress when this function is called, generation will resume with the predistorted waveform.</summary> /// <param name="specAn">Specifies the SpecAn signal to configure.</param> /// <param name="rfsgSession">Specifies the open RFSG session to configure.</param> /// <param name="referenceWaveform">Specifies the <see cref="Waveform"/> whose data defines the complex baseband equivalent of the RF signal applied at the input /// port of the device under test when performing the measurement. See the RFmx help for more documention of this parameter.</param> /// <param name="selectorString">Pass an empty string. The signal name that is passed when creating the signal configuration is used. /// See the RFmx help for more documention of this parameter.</param> /// <returns>Common results after the application of memory polynomial based DPD.</returns> public static MemoryPolynomialResults PerformMemoryPolynomial(RFmxSpecAnMX specAn, NIRfsg rfsgSession, MemoryPolynomialConfiguration mpConfig, Waveform referenceWaveform, string selectorString = "") { //Instantiate new waveform with reference waveform properties MemoryPolynomialResults mpResults = new MemoryPolynomialResults() { PredistortedWaveform = referenceWaveform }; mpResults.PredistortedWaveform.Data = referenceWaveform.Data.Clone(); // clone waveform so RFmx can't act on reference waveform mpResults.PredistortedWaveform.UpdateNameAndScript(referenceWaveform.Name + "postMpDpd"); RFmxSpecAnMXDpdApplyDpdIdleDurationPresent idlePresent = referenceWaveform.IdleDurationPresent ? RFmxSpecAnMXDpdApplyDpdIdleDurationPresent.True : RFmxSpecAnMXDpdApplyDpdIdleDurationPresent.False; RfsgGenerationStatus preDpdGenerationStatus = rfsgSession.CheckGenerationStatus(); rfsgSession.Abort(); // abort so we don't mess with the loop logic for (int i = 0; i < mpConfig.NumberOfIterations; i++) { specAn.Dpd.Configuration.ConfigurePreviousDpdPolynomial(selectorString, mpResults.Polynomial); rfsgSession.Initiate(); specAn.Initiate(selectorString, ""); specAn.WaitForMeasurementComplete(selectorString, 10.0); // wait for polynomial coefficients to be calculated //waveform data and PAPR are overwritten in post DPD waveform specAn.Dpd.ApplyDpd.ApplyDigitalPredistortion(selectorString, referenceWaveform.Data, idlePresent, 10.0, ref mpResults.PredistortedWaveform.Data, out mpResults.PowerResults.WaveformTruePapr_dB, out mpResults.PowerResults.WaveformPowerOffset_dB); //Waveform's PAPR is modified to adjust the output power of the waveform on a per waveform basis rather than changing the //user's configured output power on the instrument mpResults.PredistortedWaveform.PAPR_dB = mpResults.PowerResults.WaveformPowerOffset_dB + mpResults.PowerResults.WaveformTruePapr_dB; DownloadWaveform(rfsgSession, mpResults.PredistortedWaveform); // implicit abort ApplyWaveformAttributes(rfsgSession, mpResults.PredistortedWaveform); specAn.Dpd.Results.FetchDpdPolynomial(selectorString, 10.0, ref mpResults.Polynomial); } mpResults.PowerResults.TrainingPower_dBm = rfsgSession.RF.PowerLevel; if (preDpdGenerationStatus == RfsgGenerationStatus.InProgress) { rfsgSession.Initiate(); // restart generation if it was running on function call } return(mpResults); }
/// <summary>Acquires the incoming signal, trains the DPD model, applies the lookup table to the reference waveform, and downloads the predistorted waveform to the generator. /// If generation is in progress when this function is called, generation will resume with the predistorted waveform.</summary> /// <param name="specAn">Specifies the SpecAn signal to configure.</param> /// <param name="rfsgSession">Specifies the open RFSG session to configure.</param> /// <param name="referenceWaveform">Specifies the <see cref="Waveform"/> whose data defines the complex baseband equivalent of the RF signal applied at the input /// port of the device under test when performing the measurement. See the RFmx help for more documention of this parameter.</param> /// <param name="selectorString">Pass an empty string. The signal name that is passed when creating the signal configuration is used. /// See the RFmx help for more documention of this parameter.</param> /// <returns>Common results after the application of lookup table based DPD.</returns> public static LookupTableResults PerformLookupTable(RFmxSpecAnMX specAn, NIRfsg rfsgSession, Waveform referenceWaveform, string selectorString = "") { //Instantiate new waveform with reference waveform properties LookupTableResults lutResults = new LookupTableResults() { PredistortedWaveform = referenceWaveform, }; lutResults.PredistortedWaveform.Data = referenceWaveform.Data.Clone(); // clone waveform so RFmx can't act on reference waveform lutResults.PredistortedWaveform.UpdateNameAndScript(referenceWaveform.Name + "postLutDpd"); RfsgGenerationStatus preDpdGenerationStatus = rfsgSession.CheckGenerationStatus(); if (preDpdGenerationStatus == RfsgGenerationStatus.Complete) { rfsgSession.Initiate(); // initiate if not already generating } specAn.Initiate(selectorString, ""); RFmxSpecAnMXDpdApplyDpdIdleDurationPresent idlePresent = referenceWaveform.IdleDurationPresent ? RFmxSpecAnMXDpdApplyDpdIdleDurationPresent.True : RFmxSpecAnMXDpdApplyDpdIdleDurationPresent.False; specAn.WaitForMeasurementComplete(selectorString, 10.0); // wait for LUT creation to finish //waveform data and PAPR are overwritten in post DPD waveform specAn.Dpd.ApplyDpd.ApplyDigitalPredistortion(selectorString, referenceWaveform.Data, idlePresent, 10.0, ref lutResults.PredistortedWaveform.Data, out lutResults.PowerResults.WaveformTruePapr_dB, out lutResults.PowerResults.WaveformPowerOffset_dB); //Waveform's PAPR is modified to adjust the output power of the waveform on a per waveform basis rather than changing the //user's configured output power on the instrument lutResults.PredistortedWaveform.PAPR_dB = lutResults.PowerResults.WaveformPowerOffset_dB + lutResults.PowerResults.WaveformTruePapr_dB; DownloadWaveform(rfsgSession, lutResults.PredistortedWaveform); // implicit call to rfsg abort ApplyWaveformAttributes(rfsgSession, lutResults.PredistortedWaveform); lutResults.PowerResults.TrainingPower_dBm = rfsgSession.RF.PowerLevel; specAn.Dpd.Results.FetchLookupTable(selectorString, 10.0, ref lutResults.InputPowers_dBm, ref lutResults.ComplexGains_dB); if (preDpdGenerationStatus == RfsgGenerationStatus.InProgress) { rfsgSession.Initiate(); // restart generation if it was running on function call } return(lutResults); }
/// <summary>Notifies running scripts configured with <see cref="ConfigureContinuousGeneration(NIRfsg, Waveform, string)"/> or /// <see cref="ConfigureBurstedGeneration(NIRfsg, Waveform, WaveformTimingConfiguration, PAENConfiguration, out double, out double)"/> /// to enter the cleanup state, and then aborts generation. This function ensures that these scripts always reach a finished state before /// aborting, so as to ensure the DUT is in the desired state at the end of generation.</summary> /// <param name="rfsgHandle">The open RFSG session to configure.</param> /// <param name="timeOut_ms">(Optional) The timeout to wait for generation to complete before manually aborting.</param> public static void AbortGeneration(NIRfsg rfsgHandle, int timeOut_ms = 1000) { //This should trigger the generator to stop infinite generation and trigger any post //generation commands. For the static PA enable case, this should trigger the requisite //off command to disable the PA. rfsgHandle.Triggers.ScriptTriggers[0].SendSoftwareEdgeTrigger(); int sleepTime_ms = 20; int maxIterations = (int)Math.Ceiling((double)timeOut_ms / sleepTime_ms); RfsgGenerationStatus genStatus = rfsgHandle.CheckGenerationStatus(); //Poll the generation status until it is complete or the timeout period is reached if (genStatus == RfsgGenerationStatus.InProgress) { for (int i = 0; i < maxIterations; i++) { genStatus = rfsgHandle.CheckGenerationStatus(); if (genStatus == RfsgGenerationStatus.Complete) { break; } else { Thread.Sleep(sleepTime_ms); } } //This will only be true if we time out if (genStatus == RfsgGenerationStatus.InProgress) { //If we timeed out then we need to call an explicit abort rfsgHandle.Abort(); throw new System.ComponentModel.WarningException("Generation did not complete in the specified timeout period, so post-script actions did not complete." + " If using bursted generation, you may need to manually disable the PA control line." + " Increase the timeout period or ensure that scripTrigger0 is properly configured to stop generation"); } } }