Exemple #1
0
        public static void SnRxGainSweep([Values(Mykonos.OBSRXCHANNEL.OBS_SNIFFER_A, Mykonos.OBSRXCHANNEL.OBS_SNIFFER_B, Mykonos.OBSRXCHANNEL.OBS_SNIFFER_C)] Mykonos.SNIFFER_CHANNEL channel)
        {
            //Initialize param structure with Hardcoded Values
            //Check why Sniffer test checks OrxProfile
            double[] profileInfo      = Helper.SetOrxProfileInfo(Mykonos.OBSRXCHANNEL.OBS_SNIFFER_A);
            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;


            int numIndices = 58;

            double[,] amplitudeData     = new double[numIndices, 3]; //58
            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);

            testFreq      = freqLo_MHz + 5;
            amplitude_dBm = -35;

            ///ESG Setup
            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 Execution ----- //
            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(0x516, 0x84);
                    gainIndex = (byte)(255 - i);


                    //Console.WriteLine("Register 0x512: " + Link.spiRead(0x512));
                    //Console.WriteLine("Register 0x513: " + Link.spiRead(0x513));


                    //Console.WriteLine("Initial gain index = " + Link.Mykonos.getObsRxGain());
                    Link.Mykonos.setObsRxManualGain(Mykonos.OBSRXCHANNEL.OBS_SNIFFER_A, gainIndex);
                    //if (gainIndex <= 237)
                    //{
                    //    Link.spiWrite(0x516, 0xC0);
                    //    Link.spiWrite(0x508, 0x10);
                    //}
                    Console.WriteLine("Set gain index = " + gainIndex);
                    Console.WriteLine("Register 0x508: " + Link.spiRead(0x508).ToString("X"));
                    Console.WriteLine("Register 0x514: " + Link.spiRead(0x514).ToString("X"));
                    Console.WriteLine("Register 0x516: " + Link.spiRead(0x516).ToString("X"));
                    System.Threading.Thread.Sleep(100);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    break;
                }
                finally
                {
                    Link.Disconnect();
                }


                rxDataArray = Helper.MykonosOrxCapture(Mykonos.OBSRXCHANNEL.OBS_SNIFFER_A, 8192);
                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;
                Console.WriteLine("Fundamental Amplitude: " + analysisData.FundamentalPower_dBFS.ToString());
                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];
                }
            }
#if false //Graphing Error - To be fixed
            string path = SnRxRfTest.ResPath + "SnRxGainSweep";
            if (channel == Mykonos.SNIFFER_CHANNEL.SNIFFER_A)
            {
                path = path + "SnA";
            }
            else if (channel == Mykonos.SNIFFER_CHANNEL.SNIFFER_B)
            {
                path = path + "SnB";
            }
            else
            {
                path = path + "SnC";
            }
            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" };
            string[] pcbInfo = Helper.PcbInfo();

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

            Helper.AddAllChartsToPdf(container, path + ".pdf", pcbInfo);
            //Console.WriteLine(pcbInfo);
            //Open Result PDF
            System.Diagnostics.Process.Start(path + ".pdf");
#endif
        }
        public static void ObsRxDecPwrTest([Values(Mykonos.OBSRXCHANNEL.OBS_RX1_TXLO, Mykonos.OBSRXCHANNEL.OBS_RX2_TXLO)] Mykonos.OBSRXCHANNEL channel,
                                           [Values(-20)] int amp_dbm)
        {
            AdiCommandServerClient Link = AdiCommandServerClient.Instance;

            Link.hw.Connect(TestSetupConfig.ipAddr, TestSetupConfig.port);
            Link.Mykonos.radioOn();
            Link.Mykonos.setObsRxPathSource(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_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 byte NUM_SAMPLES         = 255;
            ushort     obsRxDecPower_mdBFS = 10;
            byte       spiData             = 0x0;


            //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.SetRfOutput(true);
            esg.SetAmplitude(amplitude_dBm);
            System.Threading.Thread.Sleep(1000);


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


            for (int amp = -20; amp > -40; amp--)
            {
                System.Threading.Thread.Sleep(100);
                esg.SetAmplitude(amp);
                System.Threading.Thread.Sleep(100);
                short[] rxDataArray = Helper.MykonosOrxCapture(channel, 16384);

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

                Link.Mykonos.getObsRxDecPower(ref obsRxDecPower_mdBFS);
                spiData = Link.spiRead(0x4E6);


                Console.WriteLine("Received power: " + obsRxDecPower_mdBFS + " calculated power: " + analysisData.FundamentalPower_dBFS + " at " + amp + " dbfs");
                NUnit.Framework.Assert.Less(System.Math.Abs((double)obsRxDecPower_mdBFS / 1000 + analysisData.FundamentalPower_dBFS), 0.50);
                NUnit.Framework.Assert.AreEqual(spiData * 250, obsRxDecPower_mdBFS);
            }


            Link.Disconnect();
        }
        public static void ObsRxAGCTest([Values(Mykonos.OBSRXCHANNEL.OBS_SNIFFER_A)] Mykonos.OBSRXCHANNEL channel)
        {
            AdiCommandServerClient Link = AdiCommandServerClient.Instance;

            Link.hw.Connect(TestSetupConfig.ipAddr, TestSetupConfig.port);
            byte   spiData1                         = 0;
            ushort power                            = 0;
            byte   agcRx1MaxGainIndex               = 255;
            byte   agcRx1MinGainIndex               = 195;
            byte   agcRx2MaxGainIndex               = 255;
            byte   agcRx2MinGainIndex               = 195;
            byte   agcObsRxMaxGainIndex             = 255;
            byte   agcObsRxMinGainIndex             = 203;
            byte   agcObsRxSelect                   = 1;
            byte   agcPeakThresholdMode             = 1; // Change for power only mode
            byte   agcLowThsPreventGainIncrease     = 1; // Change for power only mode
            UInt32 agcGainUpdateCounter             = 30720;
            byte   agcSlowLoopSettlingDelay         = 3;
            byte   agcPeakWaitTime                  = 2;
            byte   pmdMeasDuration                  = 0x08;
            byte   pmdMeasConfig                    = 0x2;
            byte   agcResetOnRxEnable               = 1;
            byte   agcEnableSyncPulseForGainCounter = 0;

            // mykonosPowerMeasAgcCfg_t
            byte pmdUpperHighThresh           = 0x01; // Triggered at approx -2dBFS
            byte pmdUpperLowThresh            = 0x03;
            byte pmdLowerHighThresh           = 0x0C;
            byte pmdLowerLowThresh            = 0x04;
            byte pmdUpperHighGainStepAttack   = 0x04;
            byte pmdUpperLowGainStepAttack    = 0x02;
            byte pmdLowerHighGainStepRecovery = 0x02;
            byte pmdLowerLowGainStepRecovery  = 0x04;

            // mykonosPeakDetAgcCfg_t
            byte apdHighThresh               = 0x1F; //Triggered at approx -3dBFS
            byte apdLowThresh                = 0x16; //Triggered at approx -5.5dBFS
            byte hb2HighThresh               = 0xB5; // Triggered at approx -2.18dBFS
            byte hb2LowThresh                = 0x80; // Triggered at approx -5.5dBFS
            byte hb2VeryLowThresh            = 0x40; // Triggered at approx -9dBFS
            byte apdHighThreshExceededCnt    = 0x06;
            byte apdLowThreshExceededCnt     = 0x04;
            byte hb2HighThreshExceededCnt    = 0x06;
            byte hb2LowThreshExceededCnt     = 0x04;
            byte hb2VeryLowThreshExceededCnt = 0x04;
            byte apdHighGainStepAttack       = 0x04;
            byte apdLowGainStepRecovery      = 0x02;
            byte hb2HighGainStepAttack       = 0x04;
            byte hb2LowGainStepRecovery      = 0x02;
            byte hb2VeryLowGainStepRecovery  = 0x04;
            byte apdFastAttack               = 1;
            byte hb2FastAttack               = 1;
            byte hb2OverloadDetectEnable     = 1;
            byte hb2OverloadDurationCnt      = 1;
            byte hb2OverloadThreshCnt        = 0x1;

            // Write some values into the structure
            Link.Mykonos.init_obsRxAgcStructure(1, ref agcRx1MaxGainIndex,
                                                ref agcRx1MinGainIndex,
                                                ref agcRx2MaxGainIndex,
                                                ref agcRx2MinGainIndex,
                                                ref agcObsRxMaxGainIndex,
                                                ref agcObsRxMinGainIndex,
                                                ref agcObsRxSelect,
                                                ref agcPeakThresholdMode,
                                                ref agcLowThsPreventGainIncrease,
                                                ref agcGainUpdateCounter,
                                                ref agcSlowLoopSettlingDelay,
                                                ref agcPeakWaitTime,
                                                ref agcResetOnRxEnable,
                                                ref agcEnableSyncPulseForGainCounter);

            Link.Mykonos.init_obsRxPwrAgcStructure(1, ref pmdUpperHighThresh,
                                                   ref pmdUpperLowThresh,
                                                   ref pmdLowerHighThresh,
                                                   ref pmdLowerLowThresh,
                                                   ref pmdUpperHighGainStepAttack,
                                                   ref pmdUpperLowGainStepAttack,
                                                   ref pmdLowerHighGainStepRecovery,
                                                   ref pmdLowerLowGainStepRecovery, ref pmdMeasDuration,
                                                   ref pmdMeasConfig);

            Link.Mykonos.init_obsRxPeakAgcStructure(1, ref apdHighThresh,
                                                    ref apdLowThresh,
                                                    ref hb2HighThresh,
                                                    ref hb2LowThresh,
                                                    ref hb2VeryLowThresh,
                                                    ref apdHighThreshExceededCnt,
                                                    ref apdLowThreshExceededCnt,
                                                    ref hb2HighThreshExceededCnt,
                                                    ref hb2LowThreshExceededCnt,
                                                    ref hb2VeryLowThreshExceededCnt,
                                                    ref apdHighGainStepAttack,
                                                    ref apdLowGainStepRecovery,
                                                    ref hb2HighGainStepAttack,
                                                    ref hb2LowGainStepRecovery,
                                                    ref hb2VeryLowGainStepRecovery,
                                                    ref apdFastAttack,
                                                    ref hb2FastAttack,
                                                    ref hb2OverloadDetectEnable,
                                                    ref hb2OverloadDurationCnt,
                                                    ref hb2OverloadThreshCnt);


            Link.Mykonos.setupObsRxAgc();

            Link.Mykonos.radioOn();
            Link.Mykonos.setObsRxPathSource(channel);
            Console.WriteLine("gain before: " + Link.Mykonos.getObsRxGain());
            Console.WriteLine(Link.spiRead(0x448));
            //Link.spiWrite(0x448, 0x2);
            Link.Mykonos.setObsRxGainControlMode(Mykonos.GAINMODE.AGC);

            Console.WriteLine("gain after: " + Link.Mykonos.getObsRxGain());
            //Assert.Pass();


            SG_AgilentESG esg = new SG_AgilentESG(measEquipment.ESGAddress);

            //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 + 15);

            Console.WriteLine("Rx Test Signal Freq (MHz): " + testSigFreq_MHz);
            //Generate Test Signal for Rx Capture with ESG
            Console.WriteLine("ESG Info:" + esg.Identify());
            Console.WriteLine("ESG Address :" + measEquipment.ESGAddress);
            Console.WriteLine("ESG Generating Tone Freq:" + testSigFreq_MHz);
            esg.SetFrequency(testSigFreq_MHz);
            esg.SetRfOutput(true);

            AdiMath.FftAnalysis analysisData = new AdiMath.FftAnalysis();
            double samplingFreq_MHz          = samplingFreq_Hz / 1000000;
            byte   sampleBitWidth            = 16;
            string response  = "";
            string initgain  = "";
            string finalgain = "";

            //Sweep from -20 to 10db
            for (int amplitude_dBm = -20; amplitude_dBm < 10; amplitude_dBm++)
            {
                esg.SetAmplitude(amplitude_dBm);
                System.Threading.Thread.Sleep(100);
                Link.Mykonos.getObsRxDecPower(ref power);

                short[]  rxDataArray = Helper.MykonosOrxCapture(channel, 16384);
                double[] data        = AdiMath.complexfftAndScale(rxDataArray, samplingFreq_MHz, sampleBitWidth, true, out analysisData);

                response = Link.Mykonos.getObsRxGain();
                spiData1 = Link.spiRead(0x4B6);
                Assert.AreEqual(spiData1 + 128, Int32.Parse(response), "Register Readback for Sniffer Gain not as expected");


                if (amplitude_dBm == -20)
                {
                    initgain = response;
                }
                Console.WriteLine("Gain: " + response + "DecPower: " + power + " FFT Power " + analysisData.FundamentalPower_dBFS + " at " + amplitude_dBm + "\n");
            }

            //Sweep from 10 to -20db

            for (int amplitude_dBm = 10; amplitude_dBm >= -20; amplitude_dBm--)
            {
                esg.SetAmplitude(amplitude_dBm);
                System.Threading.Thread.Sleep(100);
                Link.Mykonos.getObsRxDecPower(ref power);

                short[]  rxDataArray = Helper.MykonosOrxCapture(channel, 16384);
                double[] data        = AdiMath.complexfftAndScale(rxDataArray, samplingFreq_MHz, sampleBitWidth, true, out analysisData);

                response = Link.Mykonos.getObsRxGain();
                spiData1 = Link.spiRead(0x4B6);
                Assert.AreEqual(spiData1 + 128, Int32.Parse(response), "Register Readback for Sniffer Gain not as expected");


                if (amplitude_dBm == -20)
                {
                    finalgain = response;
                }
                Console.WriteLine("Gain: " + response + "DecPower: " + power + " FFT Power " + analysisData.FundamentalPower_dBFS + " at " + amplitude_dBm + "\n");
            }
            Assert.AreEqual(initgain, finalgain, "Initial gain is not equal to the final gain");
            Link.Disconnect();
        }
        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
        }
        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);
        }
        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);
        }
        public static void TxLoopbackRx1Rx2Capture(int amp_dbm1,
                                                   int OffSet1,
                                                   int IQExptVal1,
                                                   int amp_dbm2,
                                                   int OffSet2,
                                                   int IQExptVal2)
        {
            //Retrieve Profile Information, samplingFreq_Hz,  ProfileBW, LO Frequency Information
            double[] rxprofileInfo = new double[3];
            rxprofileInfo[0] = settings.rxProfileData.IqRate_kHz;
            rxprofileInfo[1] = settings.rxPllLoFreq_Hz;
            rxprofileInfo[2] = settings.rxProfileData.PrimarySigBw_Hz;

            double[] txprofileInfo = new double[3];
            txprofileInfo[0] = settings.txProfileData.IqRate_kHz;
            txprofileInfo[1] = settings.txPllLoFreq_Hz;
            txprofileInfo[2] = settings.txProfileData.PrimarySigBw_Hz;


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

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

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



            //Define DataCapture Parameters
            const int NUM_SAMPLES = 8192;

            short[] rx1DataArray = new short[NUM_SAMPLES * 2];
            double[,] rx1timeDomainData = new double[NUM_SAMPLES / 2, 3];

            short[] rx2DataArray = new short[NUM_SAMPLES * 2];
            double[,] rx2timeDomainData = new double[NUM_SAMPLES / 2, 3];



            //Enable Mykonos Rx and Tx Datapaths
            AdiCommandServerClient Link = AdiCommandServerClient.Instance;

            Link.hw.Connect(TestSetupConfig.ipAddr, TestSetupConfig.port);
#if false    //Debug To check Test works- messup ADC Sampler Crossbar
            byte dataRb;
            dataRb = Link.spiRead(0x082);
            Console.Write(dataRb.ToString("X"));
            Link.spiWrite(0x082, 0xF0);
            dataRb = Link.spiRead(0x082);
            Console.Write(dataRb.ToString("X"));
#endif
#if false    //Debug To check Test works- messup Lane Crossbar
            byte dataRb;
            dataRb = Link.spiRead(0x083);
            Console.Write(dataRb.ToString("X"));
            Link.spiWrite(0x083, 0xE0);
            dataRb = Link.spiRead(0x083);
            Console.Write(dataRb.ToString("X"));
#endif
            Link.Mykonos.radioOn();
            Link.Disconnect();

            //Generate Loopback Tone
            Helper.GenerateTxTone(Mykonos.TXCHANNEL.TX1, txprofileInfo, OffSet1 * 100000, amp_dbm1);
            Helper.GenerateTxTone(Mykonos.TXCHANNEL.TX2, txprofileInfo, OffSet2 * 100000, amp_dbm2);


            //Capture Rx Data Tone
            System.Threading.Thread.Sleep(500);
            rx1DataArray = Helper.MykonosRxCapture(Mykonos.RXCHANNEL.RX1, NUM_SAMPLES);
            rx2DataArray = Helper.MykonosRxCapture(Mykonos.RXCHANNEL.RX2, NUM_SAMPLES);

            //Frequency Domain Data Processing for Rx1
            AdiMath.FftAnalysis analysisData = new AdiMath.FftAnalysis();
            double   samplingFreq_MHz        = samplingFreq_Hz / 1000000;
            byte     sampleBitWidth          = 16;
            double[] data = AdiMath.complexfftAndScale(rx1DataArray, 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++)
            {
                rx1timeDomainData[i, 0] = i;
                rx1timeDomainData[i, 1] = rx1DataArray[2 * i];
                rx1timeDomainData[i, 2] = rx1DataArray[2 * i + 1];
            }

            //Frequency Domain Data Processing for Rx2
            data = AdiMath.complexfftAndScale(rx2DataArray, samplingFreq_MHz, sampleBitWidth, true, out analysisData);

            //Define the 2D array to store frequency bins corresponding to fft data
            fftFreqAmp = new double[data.Length, 2];
            binSize    = (samplingFreq_MHz / NUM_SAMPLES);
            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
            numSamplesDiv2 = (int)NUM_SAMPLES / 2;
            for (int i = 0; i < numSamplesDiv2; i++)
            {
                rx2timeDomainData[i, 0] = i;
                rx2timeDomainData[i, 1] = rx2DataArray[2 * i];
                rx2timeDomainData[i, 2] = rx2DataArray[2 * i + 1];
            }

            //Check IQ Data For Rx1
            var IMin = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => rx1timeDomainData[i, 1]).Min();
            var IMax = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => rx1timeDomainData[i, 1]).Max();
            var QMin = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => rx1timeDomainData[i, 2]).Min();
            var QMax = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => rx1timeDomainData[i, 2]).Max();
            Console.WriteLine("I Max, Min:" + IMax.ToString() + "," + IMin.ToString());
            Console.WriteLine("Q Max, Min:" + QMax.ToString() + "," + QMin.ToString());
            NUnit.Framework.Assert.Greater(IMin, ((-1) * (IQExptVal1 + ((IQExptVal1 * 10) / 100))));
            NUnit.Framework.Assert.Less(IMin, (IQExptVal1 * (-1)));
            NUnit.Framework.Assert.Less(IMax, ((IQExptVal1 + ((IQExptVal1 * 10) / 100))));
            NUnit.Framework.Assert.Greater(IMax, IQExptVal1);

            NUnit.Framework.Assert.Greater(QMin, ((-1) * (IQExptVal1 + ((IQExptVal1 * 10) / 100))));
            NUnit.Framework.Assert.Less(QMin, (IQExptVal1 * (-1)));
            NUnit.Framework.Assert.Less(QMax, ((IQExptVal1 + ((IQExptVal1 * 10) / 100))));
            NUnit.Framework.Assert.Greater(QMax, IQExptVal1);

            //Check IQ Data For Rx2
            IMin = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => rx2timeDomainData[i, 1]).Min();
            IMax = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => rx2timeDomainData[i, 1]).Max();
            QMin = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => rx2timeDomainData[i, 2]).Min();
            QMax = System.Linq.Enumerable.Range(0, numSamplesDiv2).Select(i => rx2timeDomainData[i, 2]).Max();
            Console.WriteLine("I Max, Min:" + IMax.ToString() + "," + IMin.ToString());
            Console.WriteLine("Q Max, Min:" + QMax.ToString() + "," + QMin.ToString());
            NUnit.Framework.Assert.Greater(IMin, ((-1) * (IQExptVal2 + ((IQExptVal2 * 10) / 100))));
            NUnit.Framework.Assert.Less(IMin, (IQExptVal2 * (-1)));
            NUnit.Framework.Assert.Less(IMax, ((IQExptVal2 + ((IQExptVal2 * 10) / 100))));
            NUnit.Framework.Assert.Greater(IMax, IQExptVal2);

            NUnit.Framework.Assert.Greater(QMin, ((-1) * (IQExptVal2 + ((IQExptVal2 * 10) / 100))));
            NUnit.Framework.Assert.Less(QMin, (IQExptVal2 * (-1)));
            NUnit.Framework.Assert.Less(QMax, ((IQExptVal2 + ((IQExptVal2 * 10) / 100))));
            NUnit.Framework.Assert.Greater(QMax, IQExptVal2);


#if false
            string path = JesdRfTests.ResPath + "Rx_JESD_FFT_TimeDomain_Plots";
            path = path + "RX2";

            string[] timeLabels = new string[] { "Time Domain Response of " + "RX2", "Sample Number", "ADC Codes", "I data", "Q data" };
            string[] fftLabels  = new string[] { "Frequency Domain Response of " + "RX2", "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(rx2timeDomainData, timeLabels, path);
            container[1] = Helper.MakeChartObject(fftFreqAmp, fftLabels, path);
            string[] pcbInfo;
            pcbInfo = Helper.PcbInfo();

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

            // open result pdf
            System.Diagnostics.Process.Start(path + ".pdf");
#endif
        }
        public static void TxLoopbackRxCapture([Values(Mykonos.RXCHANNEL.RX1, Mykonos.RXCHANNEL.RX2)] Mykonos.RXCHANNEL channel,
                                               [Values(-20)] int amp_dbm,
                                               [Values(10)] int OffSet,
                                               [Values(20000)] int IQExptVal)
        {
            //Retrieve Profile Information, samplingFreq_Hz,  ProfileBW, LO Frequency Information
            double[] rxprofileInfo = new double[3];
            rxprofileInfo[0] = settings.rxProfileData.IqRate_kHz;
            rxprofileInfo[1] = settings.rxPllLoFreq_Hz;
            rxprofileInfo[2] = settings.rxProfileData.PrimarySigBw_Hz;

            double[] txprofileInfo = new double[3];
            txprofileInfo[0] = settings.txProfileData.IqRate_kHz;
            txprofileInfo[1] = settings.txPllLoFreq_Hz;
            txprofileInfo[2] = settings.txProfileData.PrimarySigBw_Hz;


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

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

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



            //Define DataCapture Parameters
            const int NUM_SAMPLES = 8192;

            short[] rxDataArray = new short[NUM_SAMPLES * 2];
            double[,] timeDomainData = new double[NUM_SAMPLES / 2, 3];
            double[,] DomainData     = new double[(2 * OffSet), 2];


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

            Link.hw.Connect(TestSetupConfig.ipAddr, TestSetupConfig.port);
            Link.Mykonos.radioOn();
            Link.Disconnect();

            Helper.GenerateTxTone(Mykonos.TXCHANNEL.TX1_TX2, txprofileInfo, OffSet * 100000, amp_dbm);

            System.Threading.Thread.Sleep(500);
            rxDataArray = Helper.MykonosRxCapture(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());
            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);


#if WR_RES_TO_PDF
            string path = JesdRfTests.ResPath + "Rx_JESD_FFT_TimeDomain_Plots";
            if (channel == Mykonos.RXCHANNEL.RX1)
            {
                path = path + "RX1";
            }
            else
            {
                path = path + "RX2";
            }

            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();

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

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