Пример #1
0
        public static void OrxCaptureTest([Values(Mykonos.OBSRXCHANNEL.OBS_RX1_TXLO, Mykonos.OBSRXCHANNEL.OBS_RX2_TXLO)] Mykonos.OBSRXCHANNEL channel, [Values(-20)] int amp_dbm,
                                          [Values(10000)] int IQExptVal)
        {
            //Retrieve Profile Information, samplingFreq_Hz,  ProfileBW, LO Frequency Information
            double[] profileInfo = new double[3];
            profileInfo[0] = settings.rxProfileData.IqRate_kHz;
            profileInfo[1] = settings.rxPllLoFreq_Hz;
            profileInfo[2] = settings.rxProfileData.PrimarySigBw_Hz;

            double samplingFreq_Hz = profileInfo[0] * 1000;
            double profileBW_MHz   = profileInfo[2] / 1000000;

            Console.WriteLine("Rx Sampling Freq (Hz): " + samplingFreq_Hz);
            Console.WriteLine("Rx Profile Bandwdith (MHz): " + profileBW_MHz);
            double freqLo_kHz = profileInfo[1] / 1000;

            Console.WriteLine("Rx LO Frequency (kHz): " + freqLo_kHz);

            //Define Receiver Test Signal to be 10MHz Offset from LO frequency
            double testSigFreq_MHz = (freqLo_kHz / 1000 + 10);
            int    amplitude_dBm   = amp_dbm;

            Console.WriteLine("Rx Test Signal Freq (MHz): " + testSigFreq_MHz);

            //Define DataCapture Parameters
            const int NUM_SAMPLES = 8192;

            short[] rxDataArray = new short[NUM_SAMPLES * 2];
            double[,] timeDomainData = new double[NUM_SAMPLES / 2, 3];


            //Generate Test Signal for Rx Capture with ESG
            SG_AgilentESG esg = new SG_AgilentESG(measEquipment.ESGAddress);

            Console.WriteLine("ESG Info:" + esg.Identify());
            Console.WriteLine("ESG Address :" + measEquipment.ESGAddress);
            Console.WriteLine("ESG Generating Tone Freq:" + testSigFreq_MHz);
            Console.WriteLine("ESG Generating Tone Amp:" + amplitude_dBm);
            esg.SetFrequency(testSigFreq_MHz);
            esg.SetAmplitude(amp_dbm);
            esg.SetRfOutput(true);

            //Enable Mykonos Rx Datapath
            AdiCommandServerClient Link = AdiCommandServerClient.Instance;

            Link.hw.Connect(TestSetupConfig.ipAddr, TestSetupConfig.port);
            //Link.Mykonos.setEnsmState(Mykonos.ENSM_STATE.TX_RX);
            //Link.Mykonos.powerUpRxPath(channel);
            Link.Mykonos.radioOn();
            Link.Mykonos.setObsRxPathSource(channel);

            Link.Disconnect();
            System.Threading.Thread.Sleep(1000);

            //Retrieve Rx Data from FPGA
            rxDataArray = Helper.MykonosOrxCapture(channel, NUM_SAMPLES);

            //Frequency Domain Data Processing
            AdiMath.FftAnalysis analysisData = new AdiMath.FftAnalysis();
            double samplingFreq_MHz          = samplingFreq_Hz / 1000000;
            byte   sampleBitWidth            = 16;

            double[] data = AdiMath.complexfftAndScale(rxDataArray, samplingFreq_MHz, sampleBitWidth, true, out analysisData);

            //Define the 2D array to store frequency bins corresponding to fft data
            double[,] fftFreqAmp = new double[data.Length, 2];
            double binSize = (samplingFreq_MHz / NUM_SAMPLES);
            double minFreq = samplingFreq_MHz / 2 * (-1);

            for (int i = 0; i < data.Length; i++)
            {
                fftFreqAmp[i, 0] = minFreq + (binSize * 2 * i);
                fftFreqAmp[i, 1] = data[i];
            }

            //Time Domain Data Processing
            int numSamplesDiv2 = (int)NUM_SAMPLES / 2;

            for (int i = 0; i < numSamplesDiv2; i++)
            {
                timeDomainData[i, 0] = i;
                timeDomainData[i, 1] = rxDataArray[2 * i];
                timeDomainData[i, 2] = rxDataArray[2 * i + 1];
            }

            var IMin = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => timeDomainData[i, 1]).Min();
            var IMax = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => timeDomainData[i, 1]).Max();
            var QMin = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => timeDomainData[i, 2]).Min();
            var QMax = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => timeDomainData[i, 2]).Max();

            Console.WriteLine("I Max, Min:" + IMax.ToString() + "," + IMin.ToString());
            Console.WriteLine("Q Max, Min:" + QMax.ToString() + "," + QMin.ToString());


#if WR_RES_TO_PDF
            string path = RxRfTests.ResPath + "Rx_FFT_TimeDomain_Plots";
            if (channel == Mykonos.OBSRXCHANNEL.OBS_RX1_TXLO)
            {
                path = path + "ORX1";
            }
            else
            {
                path = path + "ORX2";
            }

            string[] timeLabels = new string[] { "Time Domain Response of " + channel.ToString(), "Sample Number", "ADC Codes", "I data", "Q data" };
            string[] fftLabels  = new string[] { "Frequency Domain Response of " + channel.ToString(), "Frequency (MHz)", "Amplitude (dBFS)", "FFT DATA" };                                                                                       // Should be >=4 long.

            var doc1 = new Document();
            iTextSharp.text.Image[] container = new iTextSharp.text.Image[2];
            container[0] = Helper.MakeChartObject(timeDomainData, timeLabels, path);
            container[1] = Helper.MakeChartObject(fftFreqAmp, fftLabels, path);
            string[] pcbInfo;
            pcbInfo = Helper.PcbInfo((settings.txPllLoFreq_Hz / 1000000.0).ToString(), (settings.rxPllLoFreq_Hz / 1000000.0).ToString(), settings.mykSettings.txProfileName, settings.mykSettings.rxProfileName, "N/A", "N/A");

            Helper.AddAllChartsToPdf(container, path + ".pdf", pcbInfo);

            // open result pdf
            System.Diagnostics.Process.Start(path + ".pdf");
#endif


            // open result pdf
            System.Diagnostics.Process.Start(path + ".pdf");

            /*
             * NUnit.Framework.Assert.Greater(IMin, ((-1) * (IQExptVal + ((IQExptVal * 10) / 100))));
             * NUnit.Framework.Assert.Less(IMin, (IQExptVal * (-1)));
             * NUnit.Framework.Assert.Less(IMax, ((IQExptVal + ((IQExptVal * 10) / 100))));
             * NUnit.Framework.Assert.Greater(IMax, IQExptVal);
             *
             * NUnit.Framework.Assert.Greater(QMin, ((-1) * (IQExptVal + ((IQExptVal * 10) / 100))));
             * NUnit.Framework.Assert.Less(QMin, (IQExptVal * (-1)));
             * NUnit.Framework.Assert.Less(QMax, ((IQExptVal + ((IQExptVal * 10) / 100))));
             * NUnit.Framework.Assert.Greater(QMax, IQExptVal);
             */
            NUnit.Framework.Assert.Greater(IMax, 5000);
            NUnit.Framework.Assert.Greater(QMax, 5000);
        }
Пример #2
0
        public static void ORxGainSweep([Values(Mykonos.OBSRXCHANNEL.OBS_RX1_TXLO, Mykonos.OBSRXCHANNEL.OBS_RX2_TXLO)] Mykonos.OBSRXCHANNEL channel)
        {
            //Initialize param structure with Hardcoded Values
            double[] profileInfo      = Helper.SetOrxProfileInfo(channel);
            double   samplingFreq_MHz = profileInfo[0] / 1000;
            double   freqLo_MHz       = profileInfo[1] / 1000000;
            double   profileBW_MHz    = profileInfo[2] / 1000000;
            double   testFreq         = 2510;
            double   amplitude_dBm    = -20;

            string[] pcbInfo;

            //TODO: Hard coded, may want to read the gain tables instead if custom ones are loaded
            //Number of known indicies in the gain index table.
            //Should a customer provide a custom gain table, we should determine the number of valid gain indicies
            // and this array size should correspond to that number.
            int numIndices = 19;

            double[,] amplitudeData     = new double[numIndices, 3];
            double[,] amplitudeDiffData = new double[numIndices - 1, 2];
            short[] rxDataArray = new short[16384];
            Console.WriteLine("Detected LO Frequency: " + freqLo_MHz);
            Console.WriteLine("Profile BW: " + profileBW_MHz);

            switch (channel)
            {
            case Mykonos.OBSRXCHANNEL.OBS_RX1_TXLO:
            case Mykonos.OBSRXCHANNEL.OBS_RX2_TXLO:
                testFreq = freqLo_MHz + 10;
                break;

            case Mykonos.OBSRXCHANNEL.OBS_SNIFFER_A:
            case Mykonos.OBSRXCHANNEL.OBS_SNIFFER_B:
            case Mykonos.OBSRXCHANNEL.OBS_SNIFFER_C:
                testFreq      = freqLo_MHz + 5;
                amplitude_dBm = -30;
                break;
            }

            //ESG Configuration
            SG_AgilentESG esg = new SG_AgilentESG(measEquipment.ESGAddress);

            Console.WriteLine(measEquipment.ESGAddress);
            Console.WriteLine(esg.Identify());
            esg.SetFrequency(testFreq);
            esg.SetAmplitude(amplitude_dBm);
            esg.SetRfOutput(true);

            //Test Sequence
            byte gainIndex = 255;
            AdiCommandServerClient Link = AdiCommandServerClient.Instance;

            AdiMath.FftAnalysis analysisData = new AdiMath.FftAnalysis();

            for (int i = 0; i < (numIndices + 1); i++)
            {
                try
                {
                    Link.hw.Connect(TestSetupConfig.ipAddr, TestSetupConfig.port);
                    Link.spiWrite(0x4F1, 0x80);
                    gainIndex = (byte)(255 - i);
                    Console.WriteLine("Initial gain index = " + Link.Mykonos.getObsRxGain());
                    Link.Mykonos.setObsRxManualGain(channel, gainIndex);    //There is currently an error in the API.
                    Console.WriteLine("Set gain index = " + gainIndex);
                    System.Threading.Thread.Sleep(100);
                }
                catch (Exception e)
                {
                    //Console.WriteLine("Invalid Gain index reached" + i);    //Need to figure out a better way to exit the loop when invalid gain reached
                    Console.WriteLine(e);
                    break;
                }
                finally
                {
                    Link.Disconnect();
                }


                rxDataArray = Helper.MykonosOrxCapture(channel, 8192); //Grab data from the FPGA
                byte     sampleBitWidth = 16;
                double[] data           = AdiMath.complexfftAndScale(rxDataArray, samplingFreq_MHz, sampleBitWidth, true, out analysisData);

                amplitudeData[i, 0] = (double)gainIndex;
                amplitudeData[i, 1] = analysisData.FundamentalPower_dBFS;
                if (i == 0)
                {
                    amplitudeData[i, 2] = analysisData.FundamentalPower_dBFS;
                }
                else
                {
                    amplitudeData[i, 2]         = amplitudeData[i - 1, 2] - 1;
                    amplitudeDiffData[i - 1, 0] = (double)gainIndex;
                    amplitudeDiffData[i - 1, 1] = amplitudeData[i - 1, 1] - amplitudeData[i, 1];
                    Console.WriteLine(" Gain index :" + amplitudeDiffData[i - 1, 0]);
                    Console.WriteLine(" Differential Amplitude" + amplitudeDiffData[i - 1, 1]);
                }
            }


#if WR_RES_TO_PDF
            string path = ObsRxRfTests.ResPath + "ORxGainSweep";
            if (channel == Mykonos.OBSRXCHANNEL.OBS_RX1_TXLO)
            {
                path = path + "OBS_RX1_TXLO";
            }
            else
            {
                path = path + "OBS_RX2_TXLO";
            }
            var doc1 = new Document();
            iTextSharp.text.Image[] container = new iTextSharp.text.Image[2];
            string[] timeLabels = new string[] { "Rx Gain Sweep versus Amplitude for " + channel.ToString(),
                                                 "Gain Index (byte)",
                                                 "Amplitude (dBFS)",
                                                 "Amplitude: " + amplitude_dBm + "dBm",
                                                 "Perfect 1dB Gain Index Steps" };
            string[] timeLabels2 = new string[] { "Difference between consecutive gain entries " + channel.ToString(),
                                                  "Gain Index",
                                                  "Amplitude delta (dB, comparing A(n + 1) - A(n))",
                                                  "Amplitude: " + amplitude_dBm + "dBm" };
            pcbInfo = Helper.PcbInfo();

            container[0] = Helper.MakeChartObject(amplitudeData, timeLabels, path);
            container[1] = Helper.MakeChartObject(amplitudeDiffData, timeLabels2, path + "2");

            Helper.AddAllChartsToPdf(container, path + ".pdf", pcbInfo);
            //Open Result PDF
            System.Diagnostics.Process.Start(path + ".pdf");
            for (int i = 1; i < (numIndices); i++)
            {
                NUnit.Framework.Assert.IsTrue(((amplitudeDiffData[i - 1, 1] < 1) &&
                                               (amplitudeDiffData[i - 1, 1] > 0)));
            }
#endif
        }
Пример #3
0
        public static void ORxPassbandSweep([Values(Mykonos.OBSRXCHANNEL.OBS_RX1_TXLO, Mykonos.OBSRXCHANNEL.OBS_RX2_TXLO)] Mykonos.OBSRXCHANNEL channel)
        {
            //Retrieve Profile Information, samplingFreq_Hz,  ProfileBW, LO Frequency Information
            double[] profileInfo = new double[3];
            profileInfo[0] = settings.rxProfileData.IqRate_kHz;
            profileInfo[1] = settings.rxPllLoFreq_Hz;
            profileInfo[2] = settings.rxProfileData.PrimarySigBw_Hz;

            double samplingFreq_MHz = profileInfo[0] / 1000;
            double profileBW_MHz    = profileInfo[2] / 1000000;

            Console.WriteLine("Rx Sampling Freq (MHz): " + samplingFreq_MHz);
            Console.WriteLine("Rx Profile Bandwdith (MHz): " + profileBW_MHz);
            double freqLo_MHz = profileInfo[1] / 1000000;

            Console.WriteLine("Rx LO Frequency (MHz): " + freqLo_MHz);



            //Define Test Parameters Based on Profile Info & Lo Frequency
            //Allow for testing 50%  over & under PassBand
            //Hard coded values for amplitude & Frequency Setups settings
            const int      NUM_SAMPLES = 8192;
            double         SwpSigAmp   = -20;
            double         SwpMinFreq  = freqLo_MHz - (profileBW_MHz / 2) * 1.5;
            double         SwpMaxFreq  = freqLo_MHz + (profileBW_MHz / 2) * 1.5;
            int            SwpNumSteps = 150;
            SwpParamStruct param       = new SwpParamStruct(SwpMinFreq, SwpMaxFreq, SwpSigAmp, SwpNumSteps);

            Console.WriteLine("SwpMinFreq (MHz): " + SwpMinFreq);
            Console.WriteLine("SwpMaxMax (MHz): " + SwpMaxFreq);
            Console.WriteLine("SwpSigAmp (MHz): " + SwpSigAmp);


            //Define Data Array for storing Fundamental
            short[] rxDataArray = new short[16384];
            double[,] outputData = new double[param.numSteps, 4];
            string[]            pcbInfo;
            AdiMath.FftAnalysis analysisData = new AdiMath.FftAnalysis();

            //Configure Signal Generator
            SG_AgilentESG sigGen = new SG_AgilentESG(measEquipment.ESGAddress);

            Console.WriteLine(sigGen.Identify());
            sigGen.SetFrequency(param.freqMin);
            sigGen.SetAmplitude(param.amplitude);
            sigGen.SetRfOutput(true);
            //Enable Mykonos Rx Datapath
            AdiCommandServerClient Link = AdiCommandServerClient.Instance;

            Link.hw.Connect(TestSetupConfig.ipAddr, TestSetupConfig.port);
            //Link.Mykonos.setEnsmState(Mykonos.ENSM_STATE.TX_RX);
            //Link.Mykonos.powerUpRxPath(channel);
            Link.Mykonos.radioOn();
            Link.Disconnect();

            //Test Sequence
            //Sweep Thru Rx Passband & Capture Data
            //Capture Received data from FPGA
            //Process Sampled Data to Determine
            //Fundemental Frequency Detected (MHz)
            //Fundamental Power of Signal (dBFS)
            //Image Power(dBFS)
            for (int i = 0; i < param.numSteps; i++)
            {
                double test_freq = param.freqMin + i * (param.freqMax - param.freqMin) / param.numSteps;
                sigGen.SetFrequency(test_freq);
                System.Threading.Thread.Sleep(100);

                rxDataArray = Helper.MykonosOrxCapture(channel, NUM_SAMPLES);

                byte     sampleBitWidth   = 16;
                double[] fftMagnitudeData = AdiMath.complexfftAndScale(rxDataArray, samplingFreq_MHz, sampleBitWidth, true, out analysisData);

                outputData[i, 0] = test_freq;
                //outputData[i, 0] = analysisData.FundamentalFrequency_MHz;
                outputData[i, 1] = analysisData.FundamentalPower_dBFS;
                outputData[i, 2] = analysisData.ImagePower_dBFS;
                outputData[i, 3] = analysisData.DcOffset_dBFS;
            }


            string path = RxRfTests.ResPath + "RxPassbandSweep";

            if (channel == Mykonos.OBSRXCHANNEL.OBS_RX1_TXLO)
            {
                path = path + "RX1";
            }
            else
            {
                path = path + "RX2";
            }
#if  WR_RES_TO_PDF
            var doc1 = new Document();
            iTextSharp.text.Image[] container = new iTextSharp.text.Image[1];
            string[] timeLabels = new string[] { "FFT Statistics versus CW Input Frequency for " + channel.ToString(),
                                                 "CW Input Frequency (MHz)",
                                                 "Amplitude (dBFS)",
                                                 "Fundamental Tone",
                                                 "Image Amplitude",
                                                 "DC Offset Amplitude" };
            pcbInfo      = Helper.PcbInfo((settings.txPllLoFreq_Hz / 1000000.0).ToString(), (settings.rxPllLoFreq_Hz / 1000000.0).ToString(), settings.mykSettings.txProfileName, settings.mykSettings.rxProfileName, "N/A", "N/A");
            container[0] = Helper.MakeChartObject(outputData, timeLabels, path);
            Helper.AddAllChartsToPdf(container, path + ".pdf", pcbInfo);

            //Open Result PDF
            System.Diagnostics.Process.Start(path + ".pdf");
#endif
#if WR_RES_TO_TXT
            // Write data to txt file
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(path + ".txt"))
            {
                file.WriteLine("Sample,  Frequency MHz, Fundamental Power(dBFS), Image Power(dBFS), DC Offset(dBFS)");
                for (int i = 0; i < param.numSteps; i++)
                {
                    file.WriteLine(i + "," + outputData[i, 0].ToString() + "," + outputData[i, 1].ToString() + "," + outputData[i, 2].ToString() + "," + outputData[i, 3].ToString());
                }
            }
#endif
            //Check Min Max Fund Amplitudes are within 0.5db of each other.
            //var MinFundPower_dBFS = System.Linq.Enumerable.Range(50, 100).Select(i => outputData[i, 1]).Min();
            //var MaxFundPower_dBFS = System.Linq.Enumerable.Range(50, 100).Select(i => outputData[i, 1]).Max();
            double MinFundPower_dBFS = outputData[50, 1];
            double MaxFundPower_dBFS = outputData[50, 1];
            for (int i = 50; i < 100; i++)
            {
                if (outputData[i, 1] < MinFundPower_dBFS)
                {
                    MinFundPower_dBFS = outputData[i, 1];
                }
                if (outputData[i, 1] > MaxFundPower_dBFS)
                {
                    MaxFundPower_dBFS = outputData[i, 1];
                }
            }
            Console.WriteLine("MinFundAmp: " + MinFundPower_dBFS);
            Console.WriteLine("MaxFundAmp: " + MaxFundPower_dBFS);
            Console.WriteLine("MaxDiffFundAmp: " + (MaxFundPower_dBFS - MinFundPower_dBFS));
            NUnit.Framework.Assert.IsTrue((MaxFundPower_dBFS - MinFundPower_dBFS) <= 0.5);
        }