private void VerifyPA()
        {
            //float tol = 0.05f; // 5%

            if(!console.PowerOn)
            {
                MessageBox.Show("Power must be on in order to Verify PA.", "Power Is Off",
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnPAVerify.BackColor = Color.Red;
                return;
            }

            PowerMaster pm;
            try
            {
                pm = new PowerMaster(comboCOMPort.Text);
            }
            catch(Exception)
            {
                MessageBox.Show("Error opening COM Port for Power Master",
                    "COM Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnPAVerify.BackColor = Color.Red;
                return;
            }
            if(pm.Watts != 0.0f) return;

            Band[] bands = { Band.B160M, Band.B80M, Band.B60M, Band.B40M, Band.B30M, Band.B20M, Band.B17M, Band.B15M, Band.B12M, Band.B10M, Band.B6M };
            float[] band_freqs = { 1.85f, 3.75f, 5.3665f, 7.15f, 10.125f, 14.175f, 18.1f, 21.300f, 24.9f, 28.4f, 50.11f};
            int[] targets = { 10, 100 };
            float[][] bridge_power = new float[bands.Length][];
            for(int i=0; i<bands.Length; i++)
                bridge_power[i] = new float[targets.Length];
            float[][] pm_power = new float[bands.Length][];
            for(int i=0; i<bands.Length; i++)
                pm_power[i] = new float[targets.Length];

            float[] pm_trim = { 1.04f, 1.03f, 1.03f, 1.03f, 1.02f, 1.01f, 1.01f, 1.0f, 1.0f, 1.0f, 0.9f };
            try
            {
                StreamReader reader = new StreamReader("powermaster.txt");
                string temp = reader.ReadLine();

                int start = temp.IndexOf(":")+1;
                int length = temp.Length - start;
                lstDebug.Items.Insert(0, "PowerMaster S/N: "+temp.Substring(start, length).Trim());

                for(int i=0; i<11; i++)
                {
                    temp = reader.ReadLine();
                    start = temp.IndexOf(":")+1;
                    length = temp.Length - start;
                    pm_trim[i] = 1.0f+0.01f*float.Parse(temp.Substring(start, length).Trim());
                    lstDebug.Items.Insert(0, BandToString(bands[i])+": "+pm_trim[i].ToString("f2"));
                }
                reader.Close();
            }
            catch(Exception)
            {
                MessageBox.Show("Error reading Array Solutions Power Master calibration file found.  Using defaults.");
            }

            double vfoa = console.VFOAFreq;
            double vfob = console.VFOBFreq;

            int tune_power = console.TunePower;
            console.TunePower = 100;

            MeterTXMode tx_meter = console.CurrentMeterTXMode;
            console.CurrentMeterTXMode = MeterTXMode.FORWARD_POWER;

            progress.SetPercent(0.0f);
            pm.Start();

            int counter = 0;
            int num_bands = 0;
            for(int i=0; i<band_freqs.Length; i++)
            {
                bool do_band = false;
                switch(bands[i])
                {
                    case Band.B160M: do_band = ck160.Checked; break;
                    case Band.B80M: do_band = ck80.Checked; break;
                    case Band.B60M: do_band = ck60.Checked; break;
                    case Band.B40M: do_band = ck40.Checked; break;
                    case Band.B30M: do_band = ck30.Checked; break;
                    case Band.B20M: do_band = ck20.Checked; break;
                    case Band.B17M: do_band = ck17.Checked; break;
                    case Band.B15M: do_band = ck15.Checked; break;
                    case Band.B12M: do_band = ck12.Checked; break;
                    case Band.B10M:	do_band = ck10.Checked; break;
                    case Band.B6M: do_band = ck6.Checked; break;
                }
                if(do_band) num_bands++;
            }

            int total_counts = num_bands*targets.Length*40;

            for(int i=0; i<band_freqs.Length; i++)
            {
                bool do_band = false;
                switch(bands[i])
                {
                    case Band.B160M: do_band = ck160.Checked; break;
                    case Band.B80M: do_band = ck80.Checked; break;
                    case Band.B60M: do_band = ck60.Checked; break;
                    case Band.B40M: do_band = ck40.Checked; break;
                    case Band.B30M: do_band = ck30.Checked; break;
                    case Band.B20M: do_band = ck20.Checked; break;
                    case Band.B17M: do_band = ck17.Checked; break;
                    case Band.B15M: do_band = ck15.Checked; break;
                    case Band.B12M: do_band = ck12.Checked; break;
                    case Band.B10M:	do_band = ck10.Checked; break;
                    case Band.B6M: do_band = ck6.Checked; break;
                }

                if(do_band)
                {
                    console.VFOAFreq = band_freqs[i];
                    console.VFOBFreq = band_freqs[i];

                    FWC.SetTXAnt(1);
                    Thread.Sleep(50);

                    DSPMode dsp_mode = console.RX1DSPMode;
                    console.RX1DSPMode = DSPMode.USB;

                    console.VFOAFreq = band_freqs[i];
                    console.VFOBFreq = band_freqs[i];

                    for(int k=0; k<targets.Length; k++)
                    {
                        console.TunePower = targets[k];
                        console.TUN = true;
                        for(int j=0; j<20; j++)
                        {
                            progress.SetPercent(++counter/(float)total_counts);
                            if(!progress.Visible) goto end;
                            Thread.Sleep(50);
                        }

                        pm_power[i][k] = pm.Watts*pm_trim[i];
                        //bridge_power[i][k] = console.NewMeterData;
                        console.TUN = false;
                        for(int j=0; j<20; j++)
                        {
                            progress.SetPercent(++counter/(float)total_counts);
                            if(!progress.Visible) goto end;
                            Thread.Sleep(50);
                        }

                        if((pm_power[i][k] < targets[k] - 5.0f) ||
                            (pm_power[i][k] > targets[k] + 20.0f))
                        {
                            btnPAVerify.BackColor = Color.Red;
                            if(!test_pa_verify.StartsWith("PA Verify Test: Failed ("))
                                test_pa_verify = "PA Verify Test: Failed (";
                            test_pa_verify += BandToString(bands[i])+"-"+targets[k]+", ";
                            lstDebug.Items.Insert(0, "PA Verify - "+BandToString(bands[i])+": Failed ("+
                                targets[k]+", "/*+bridge_power[i][k].ToString("f1")+", "*/+pm_power[i][k].ToString("f1")+")");
                        }
                        else
                        {
                            lstDebug.Items.Insert(0, "PA Verify - "+BandToString(bands[i])+": Passed ("+
                                targets[k]+", "/*+bridge_power[i][k].ToString("f1")+", "*/+pm_power[i][k].ToString("f1")+")");
                        }
                    }
                    console.RX1DSPMode = dsp_mode;
                }
            }

            end:
            console.TUN = false;
            console.VFOAFreq = 0.590;
            console.VFOAFreq = vfoa;
            console.VFOBFreq = vfob;
            console.TunePower = tune_power;
            console.FullDuplex = false;

            console.CurrentMeterTXMode = tx_meter;

            try
            {
                pm.Stop();
                Thread.Sleep(100);
                pm.Close();
            }
            catch(Exception) { }

            if(test_pa_verify.StartsWith("PA Verify Test: Failed ("))
                test_pa_verify = test_pa_verify.Substring(0, test_pa_verify.Length-2)+")";
            toolTip1.SetToolTip(btnPAVerify, test_pa_verify);

            string path = Application.StartupPath+"\\Tests";
            if(!Directory.Exists(path))	Directory.CreateDirectory(path);
            bool file_exists = File.Exists(path+"\\pa_verify.csv");
            StreamWriter writer = new StreamWriter(path+"\\pa_verify.csv", true);
            if(!file_exists) writer.WriteLine("PA Serial Num, Date/Time, Version,"
                                 +"Bridge 160-10, PM 160-10, Bridge 160-100, PM 160-100,"
                                 +"Bridge 80-10, PM 80-10, Bridge 80-100, PM 80-100,"
                                 +"Bridge 60-10, PM 60-10, Bridge 60-100, PM 60-100,"
                                 +"Bridge 40-10, PM 40-10, Bridge 40-100, PM 40-100,"
                                 +"Bridge 30-10, PM 30-10, Bridge 30-100, PM 30-100,"
                                 +"Bridge 20-10, PM 20-10, Bridge 20-100, PM 20-100,"
                                 +"Bridge 17-10, PM 17-10, Bridge 17-100, PM 17-100,"
                                 +"Bridge 15-10, PM 15-10, Bridge 15-100, PM 15-100,"
                                 +"Bridge 12-10, PM 12-10, Bridge 12-100, PM 12-100,"
                                 +"Bridge 10-10, PM 10-10, Bridge 10-100, PM 10-100,"
                                 +"Bridge 6-10, PM 6-10, Bridge 6-100, PM 6-100,"
                                );
            writer.Write(FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+","
                +DateTime.Now.ToShortDateString()+" "+DateTime.Now.ToShortTimeString()+","
                +console.Text+",");
            for(int i=0; i<bands.Length; i++)
            {
                for(int j=0; j<targets.Length; j++)
                {
                    writer.Write(bridge_power[i][j].ToString("f1")+",");
                    writer.Write(pm_power[i][j].ToString("f1")+",");
                }
            }
            writer.WriteLine("");
            writer.Close();

            path += "\\PA Verify";
            if(!Directory.Exists(path)) Directory.CreateDirectory(path);
            writer = new StreamWriter(path+"\\pa_bridge_"+FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+".csv");
            writer.WriteLine("Band, Bridge 10w, PM 10w, Bridge 100w, PM 100w");
            for(int i=0; i<bands.Length; i++)
            {
                writer.Write(BandToString(bands[i])+",");
                for(int j=0; j<targets.Length; j++)
                {
                    writer.Write(bridge_power[i][j].ToString("f1")+",");
                    writer.Write(pm_power[i][j].ToString("f1")+",");
                }
                writer.WriteLine("");
            }
            writer.Close();

            DialogResult dr = MessageBox.Show("Would you like to save EEPROM data to a file now?",
                "Save EEPROM Data?",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question);
            if(dr == DialogResult.Yes)
            {
                if(File.Exists(Application.StartupPath+"\\FLEX-5000 EEPROM.exe"))
                    Process.Start(Application.StartupPath+"\\FLEX-5000 EEPROM.exe");
                else MessageBox.Show("Could not locate EEPROM Tool.  Please put tool in PowerSDR directory.",
                         "Error finding EEPROM Tool",
                         MessageBoxButtons.OK,
                         MessageBoxIcon.Error);
            }

            progress.Hide();
            grpPA.Enabled = true;
            grpIO.Enabled = true;
        }
        private void NullBridge()
        {
            if(!console.PowerOn)
            {
                MessageBox.Show("Power must be on in order to run Null Bridge.", "Power Is Off",
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                progress.Hide();
                grpPA.Enabled = true;
                grpIO.Enabled = true;
                return;
            }

            PowerMaster pm;
            try
            {
                pm = new PowerMaster(comboCOMPort.Text);
            }
            catch(Exception)
            {
                MessageBox.Show("Error opening COM Port for Power Master",
                    "COM Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnNullBridge.BackColor = Color.Red;
                return;
            }
            if(pm.Watts != 0.0f) return;

            Band[] bands = { Band.B160M, Band.B80M, Band.B60M, Band.B40M, Band.B30M, Band.B20M, Band.B17M, Band.B15M, Band.B12M, Band.B10M, Band.B6M };
            float[] pm_trim = { 1.04f, 1.03f, 1.03f, 1.03f, 1.02f, 1.01f, 1.01f, 1.0f, 1.0f, 1.0f, 0.9f };
            try
            {
                StreamReader reader = new StreamReader(Application.StartupPath+"\\powermaster.txt");
                string temp = reader.ReadLine();

                int start = temp.IndexOf(":")+1;
                int length = temp.Length - start;
                lstDebug.Items.Insert(0, "PowerMaster S/N: "+temp.Substring(start, length).Trim());

                for(int i=0; i<11; i++)
                {
                    temp = reader.ReadLine();
                    start = temp.IndexOf(":")+1;
                    length = temp.Length - start;
                    pm_trim[i] = 1.0f+0.01f*float.Parse(temp.Substring(start, length).Trim());
                    lstDebug.Items.Insert(0, BandToString(bands[i])+": "+pm_trim[i].ToString("f2"));
                }
                reader.Close();
            }
            catch(Exception)
            {
                MessageBox.Show("Error reading Array Solutions Power Master calibration file found.  Using defaults.");
            }

            double vfoa = console.VFOAFreq;
            console.VFOAFreq = 28.0;

            double vfob = console.VFOBFreq;
            console.VFOBFreq = 28.0;

            console.FullDuplex = true;

            FWC.SetQSD(true);
            Thread.Sleep(50);
            FWC.SetQSE(true);
            Thread.Sleep(50);
            FWC.SetTR(true);
            Thread.Sleep(50);
            FWC.SetSig(true);
            Thread.Sleep(50);
            FWC.SetGen(false);
            Thread.Sleep(50);
            FWC.SetTest(true);
            Thread.Sleep(50);
            FWC.SetTXMon(false);
            Thread.Sleep(50);

            FWC.SetTXAnt(1);
            Thread.Sleep(50);

            DSPMode dsp_mode = console.RX1DSPMode;
            console.RX1DSPMode = DSPMode.USB;

            int power = console.PWR;
            console.PWR = 100;

            FWC.SetMOX(true);
            Thread.Sleep(50);
            Audio.TXInputSignal = Audio.SignalSource.SINE;
            double scale = Audio.SourceScale;
            Audio.SourceScale = 1.0;
            Audio.RadioVolume = 0.05;

            grpBridgeNull.Visible = true;
            pm.Start();
            Thread.Sleep(1500);

            lstDebug.Items.Insert(0, "PM: "+(pm.Watts*pm_trim[10]).ToString("f1"));
            if(pm.Watts*pm_trim[10] < 20.0f)
            {
                FWC.SetMOX(false);
                Thread.Sleep(50);
                progress.Hide();
                MessageBox.Show("PA Bridge Null Error: Low Power from PowerMaster.\nCheck COM port and try again.",
                    "PA Bridge Null: Low Power",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                pm.Close();
            }
            else
            {
                pm.Close();
                while(progress.Visible)
                {
                    bridge_null_volts = bridge_null_volts*0.8f + console.ReadRefPowerVolts(1)*0.2f;
                    picNullBridge.Invalidate();
                    Thread.Sleep(100);
                }
            }

            grpBridgeNull.Visible = false;

            FWC.SetMOX(false);
            Thread.Sleep(50);
            FWC.SetQSD(true);
            Thread.Sleep(50);
            FWC.SetQSE(false);
            Thread.Sleep(50);
            FWC.SetTR(false);
            Thread.Sleep(50);
            FWC.SetSig(false);
            Thread.Sleep(50);
            FWC.SetGen(false);
            Thread.Sleep(50);
            FWC.SetTest(false);
            Thread.Sleep(50);
            FWC.SetTXMon(false);
            Thread.Sleep(50);
            Audio.TXInputSignal = Audio.SignalSource.RADIO;
            Audio.SourceScale = scale;
            console.RX1DSPMode = dsp_mode;
            console.VFOAFreq = vfoa;
            console.VFOBFreq = vfob;
            console.PWR = power;
            console.FullDuplex = false;

            grpPA.Enabled = true;
            grpIO.Enabled = true;
            btnNullBridge.BackColor = Color.Green;
        }
        private void PARunCal()
        {
            if(!console.PowerOn)
            {
                MessageBox.Show("Power must be on in order to calibrate PA.", "Power Is Off",
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnRunPACal.BackColor = Color.Red;
                return;
            }

            PowerMaster pm;
            try
            {
                pm = new PowerMaster(comboCOMPort.Text);
            }
            catch(Exception)
            {
                MessageBox.Show("Error opening COM Port for Power Master",
                    "COM Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnRunPACal.BackColor = Color.Red;
                return;
            }
            if(pm.Watts != 0.0f) return;

            Band[] bands = { Band.B160M, Band.B80M, Band.B60M, Band.B40M, Band.B30M, Band.B20M, Band.B17M, Band.B15M, Band.B12M, Band.B10M, Band.B6M };
            float[] band_freqs = { 1.85f, 3.75f, 5.3665f, 7.15f, 10.125f, 14.175f, 18.1f, 21.300f, 24.9f, 28.4f, 50.11f};
            float[] targets = { 1.0f, 2.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f };

            float[] pm_trim = { 1.04f, 1.03f, 1.03f, 1.03f, 1.02f, 1.01f, 1.01f, 1.0f, 1.0f, 1.0f, 0.9f };
            try
            {
                StreamReader reader = new StreamReader("powermaster.txt");
                string temp = reader.ReadLine();

                int start = temp.IndexOf(":")+1;
                int length = temp.Length - start;
                lstDebug.Items.Insert(0, "PowerMaster S/N: "+temp.Substring(start, length).Trim());

                for(int i=0; i<11; i++)
                {
                    temp = reader.ReadLine();
                    start = temp.IndexOf(":")+1;
                    length = temp.Length - start;
                    pm_trim[i] = 1.0f+0.01f*float.Parse(temp.Substring(start, length).Trim());
                    lstDebug.Items.Insert(0, BandToString(bands[i])+": "+pm_trim[i].ToString("f2"));
                }
                reader.Close();
            }
            catch(Exception)
            {
                MessageBox.Show("Error reading Array Solutions Power Master calibration file found.  Using defaults.");
            }

            double vfoa = console.VFOAFreq;
            double vfob = console.VFOBFreq;

            console.FullDuplex = true;

            FWC.SetQSD(true);
            Thread.Sleep(50);
            FWC.SetQSE(true);
            Thread.Sleep(50);
            FWC.SetTR(true);
            Thread.Sleep(50);
            FWC.SetSig(true);
            Thread.Sleep(50);
            FWC.SetGen(false);
            Thread.Sleep(50);
            FWC.SetTest(true);
            Thread.Sleep(50);
            FWC.SetTXMon(false);
            Thread.Sleep(50);

            progress.SetPercent(0.0f);
            pm.Start();

            int counter = 0;
            int num_bands = 0;
            for(int i=0; i<band_freqs.Length; i++)
            {
                bool do_band = false;
                switch(bands[i])
                {
                    case Band.B160M: do_band = ck160.Checked; break;
                    case Band.B80M: do_band = ck80.Checked; break;
                    case Band.B60M: do_band = ck60.Checked; break;
                    case Band.B40M: do_band = ck40.Checked; break;
                    case Band.B30M: do_band = ck30.Checked; break;
                    case Band.B20M: do_band = ck20.Checked; break;
                    case Band.B17M: do_band = ck17.Checked; break;
                    case Band.B15M: do_band = ck15.Checked; break;
                    case Band.B12M: do_band = ck12.Checked; break;
                    case Band.B10M:	do_band = ck10.Checked; break;
                    case Band.B6M: do_band = ck6.Checked; break;
                }
                if(do_band) num_bands++;
            }

            int total_counts = num_bands*28;

            for(int i=0; i<band_freqs.Length; i++) // main loop
            {
                bool do_band = false;
                switch(bands[i])
                {
                    case Band.B160M: do_band = ck160.Checked; break;
                    case Band.B80M: do_band = ck80.Checked; break;
                    case Band.B60M: do_band = ck60.Checked; break;
                    case Band.B40M: do_band = ck40.Checked; break;
                    case Band.B30M: do_band = ck30.Checked; break;
                    case Band.B20M: do_band = ck20.Checked; break;
                    case Band.B17M: do_band = ck17.Checked; break;
                    case Band.B15M: do_band = ck15.Checked; break;
                    case Band.B12M: do_band = ck12.Checked; break;
                    case Band.B10M:	do_band = ck10.Checked; break;
                    case Band.B6M: do_band = ck6.Checked; break;
                }

                if(do_band)
                {
                    for(int ii=0; ii<13; ii++)
                        console.power_table[(int)bands[i]][ii] = 0.0f;
                    for(int ii=0; ii<6; ii++)
                        console.pa_bridge_table[(int)bands[i]][ii] = 0.0f;
                    console.swr_table[(int)bands[i]] = 0.0f;

                    console.VFOAFreq = band_freqs[i];
                    console.VFOBFreq = band_freqs[i];

                    FWC.SetTXAnt(1);
                    Thread.Sleep(50);

                    DSPMode dsp_mode = console.RX1DSPMode;
                    console.RX1DSPMode = DSPMode.USB;

                    console.VFOAFreq = band_freqs[i];
                    console.VFOBFreq = band_freqs[i];

                    Audio.RadioVolume = 0.00;

                    for(int j=0; j<10; j++)
                    {
                        if(!progress.Visible) goto end;
                        Thread.Sleep(50);
                    }

                    Audio.RadioVolume = 0.04;
                    double last_watts = 0.0;
                    double last_volts = 0.0;

                    for(int k=0; k<targets.Length; k++)
                    {
                        int try_again_count = 0;
                        int zero_count = 0;
                        float tol = 1.0f;
                        if(targets[k] < 60.0f) tol = 0.5f;
                        if(targets[k] < 15.0f) tol = 0.2f;

                        FWC.SetMOX(true);
                        Thread.Sleep(50);
                        Audio.TXInputSignal = Audio.SignalSource.SINE;
                        Audio.SourceScale = 1.0;

                        float p = 0.0f;

                        while(Math.Abs(targets[k]-p) > tol)
                        {
                            for(int j=0; j<20; j++)
                            {
                                if(!progress.Visible) goto end;
                                Thread.Sleep(50);
                            }

                            p = pm.Watts*pm_trim[i];
                            Debug.WriteLine("p: "+p.ToString("f1"));

                            if(p == 0.0f)
                            {
                                zero_count++;
                                if(zero_count > 2)
                                {
                                    FWC.SetMOX(false);
                                    Thread.Sleep(50);
                                    MessageBox.Show("No power reading from PowerMaster.  Check cables and try again.");
                                    progress.Text = "";
                                    goto end;
                                }
                                p = 0.01f;
                            }

                            if(Math.Abs(targets[k]-p) > tol)
                            {
                                if(try_again_count++ == 20) // poop out
                                {
                                    FWC.SetMOX(false);
                                    Thread.Sleep(50);
                                    for(int kk = k; kk<12; kk++)
                                        lstDebug.Items.Insert(0, "Bridge/Power - "+BandToString(bands[i])+" ("+targets[kk].ToString("f0")+"w): Failed");
                                    btnRunPACal.BackColor = Color.Red;
                                    k = 12;
                                    p = targets[k];
                                    if(k>0)
                                        Audio.RadioVolume = console.power_table[(int)bands[i]][k-1];
                                }
                                else if(targets[k] <= 10)
                                {
                                    double x1 = Math.Pow(last_volts, 2.0);
                                    double x2 = Math.Pow(Audio.RadioVolume, 2.0);
                                    double y1 = last_watts;
                                    double y2 = p;
                                    double next_volts = 0.0;

                                    if(y2 == y1)
                                    {
                                        if(y1 == 0.0) next_volts = last_volts*2;
                                        else next_volts += (Audio.RadioVolume-last_volts);
                                    }
                                    else if(x2 == x1)
                                    {
                                        FWC.SetMOX(false);
                                        Thread.Sleep(50);
                                        MessageBox.Show("Error in Bridge Cal");
                                        progress.Text = "";
                                        goto end;
                                    }
                                    else
                                    {
                                        double a = (y2-y1)/(x2-x1);

                                        if(a <= 0.0)
                                        {
                                            next_volts += (Audio.RadioVolume-last_volts);
                                        }
                                        else
                                        {
                                            double b = y2-a*x2;

                                            lstDebug.Items.Insert(0, x1.ToString("f5")+" "+x2.ToString("f5")+" "+y1.ToString("f1")+" "+y2.ToString("f1"));
                                            lstDebug.Items.Insert(0, a.ToString("f5")+" "+b.ToString("f5"));

                                            next_volts = Math.Sqrt((targets[k]-b)/a);
                                            if(double.IsNaN(next_volts))
                                            {
                                                /*// error out -- two times through the cap will do this
                                                FWC.SetMOX(false);
                                                MessageBox.Show("NaN Error in Bridge Cal");
                                                progress.Text = "";
                                                goto end;*/
                                                next_volts += (Audio.RadioVolume-last_volts);
                                            }
                                        }
                                    }

                                    last_volts = Audio.RadioVolume;
                                    if(next_volts/last_volts > 2.0)
                                        next_volts = last_volts*2.0;
                                    else if(next_volts/last_volts < 0.5)
                                        next_volts = last_volts*0.5;
                                    Audio.RadioVolume = Math.Min(0.5, next_volts); // 0.5 cap where 0.83 is max before overloading QSE
                                }
                                else Audio.RadioVolume *= Math.Sqrt(targets[k]/p);

                                if(p > 50.0)
                                {
                                    FWC.SetMOX(false);
                                    Thread.Sleep(50);
                                    for(int j=0; j<20; j++)
                                    {
                                        if(!progress.Visible)
                                        {
                                            progress.Text = "";
                                            goto end;
                                        }
                                        Thread.Sleep(50);
                                    }
                                    FWC.SetMOX(true);
                                    Thread.Sleep(50);
                                }
                            }

                            last_watts = p;
                        }

                        progress.SetPercent(++counter/(float)total_counts);

                        bool fail = false;
                        if(k < 5 || k == 11)
                        {
                            int kk = k;
                            if(kk == 11) kk = 5;
                            float v1 = console.ReadFwdPowerVolts(3);
                            console.pa_bridge_table[(int)bands[i]][kk] = v1;

                            if(console.pa_bridge_table[(int)bands[i]][kk] == 0.0f ||
                                k>0 && console.pa_bridge_table[(int)bands[i]][kk] <= console.pa_bridge_table[(int)bands[i]][kk-1])
                            {
                                btnRunPACal.BackColor = Color.Red;
                                fail = true;
                            }
                        }
                        console.power_table[(int)bands[i]][k] = (float)Audio.RadioVolume;

                        if(k==0 || (console.power_table[(int)bands[i]][k] > console.power_table[(int)bands[i]][k-1] && !fail))
                        {
                            lstDebug.Items.Insert(0, "Bridge/Power - "+BandToString(bands[i])+" ("+targets[k].ToString("f0")+"w): Passed");
                        }
                        else
                        {
                            lstDebug.Items.Insert(0, "Bridge/Power - "+BandToString(bands[i])+" ("+targets[k].ToString("f0")+"w): Failed");
                            btnRunPACal.BackColor = Color.Red;
                        }
                    }

                    // do SWR cal here
                    console.MOX = false;

                    FWCAnt tx_ant = console.TXAnt;
                    console.TXAnt = FWCAnt.ANT2;
                    FWC.SetTXAnt(2);
                    Thread.Sleep(50);

                    for(int j=0; j<5; j++)
                    {
                        Thread.Sleep(50);
                        if(!progress.Visible) goto end2;
                        progress.SetPercent(counter++/(float)total_counts);
                    }

                    console.swr_table[(int)bands[i]] = 1.0f;
                    console.TUN = true;
                    int old_tun_pwr = console.PWR;
                    console.PWR = 50;
                    for(int j=0; j<10; j++)
                    {
                        Thread.Sleep(50);
                        if(!progress.Visible) goto end1;
                        progress.SetPercent(counter++/(float)total_counts);
                    }

                    double f = console.ReadFwdPower(3);
                    double r = console.ReadRefPower(3);
                    Debug.WriteLine("f: "+f.ToString("f1")+"  r: "+r.ToString("f1"));

                    float alpha = (float)(f/r/9);

                    console.swr_table[(int)bands[i]] = alpha;
                    lstDebug.Items.Insert(0, "SWR Test - "+BandToString(bands[i])+": "+alpha.ToString("f4"));

                end1:
                    console.PWR = old_tun_pwr;
                    console.TUN = false;
                end2:
                    console.TXAnt = tx_ant;
                    if(!progress.Visible) goto end;
                    console.RX1DSPMode = dsp_mode;
                }
            }
            end:
            progress.Hide();
            console.TUN = false;
            console.MOX = false;
            Audio.TXInputSignal = Audio.SignalSource.RADIO;
            console.VFOAFreq = 0.590;
            console.VFOAFreq = vfoa;
            console.VFOBFreq = vfob;
            console.FullDuplex = false;
            FWC.SetQSD(true);
            Thread.Sleep(50);
            FWC.SetQSE(false);
            Thread.Sleep(50);
            FWC.SetTR(false);
            Thread.Sleep(50);
            FWC.SetSig(false);
            Thread.Sleep(50);
            FWC.SetGen(false);
            Thread.Sleep(50);
            FWC.SetTest(false);
            Thread.Sleep(50);
            FWC.SetTXMon(false);
            Thread.Sleep(50);
            FWC.SetMOX(false);
            Thread.Sleep(50);
            try
            {
                pm.Stop();
                Thread.Sleep(100);
                pm.Close();
            }
            catch(Exception) { }

            bool pass = true;
            test_pa_bridge = "PA Bridge Test: Passed";
            for(int i=0; i<bands.Length; i++)
            {
                for(int j=0; j<6; j++)
                {
                    if(console.pa_bridge_table[(int)bands[i]][j] == 0.0f)
                    {
                        pass = false;
                        if(!test_pa_bridge.StartsWith("PA Bridge Test: Failed ("))
                            test_pa_bridge = "PA Bridge Test: Failed (";
                        test_pa_bridge += BandToString(bands[i])+", ";
                        j = 6;
                    }
                    else if(j!=0)
                    {
                        if(console.pa_bridge_table[(int)bands[i]][j] <= console.pa_bridge_table[(int)bands[i]][j-1])
                        {
                            pass = false;
                            if(!test_pa_bridge.StartsWith("PA Bridge Test: Failed ("))
                                test_pa_bridge = "PA Bridge Test: Failed (";
                            test_pa_bridge += BandToString(bands[i])+", ";
                            j = 6;
                        }
                    }
                }
            }

            /*if(pass) btnRunPACal.BackColor = Color.Green;
            else btnRunPACal.BackColor = Color.Red;*/

            if(test_pa_bridge.StartsWith("PA Bridge Test: Failed ("))
                test_pa_bridge = test_pa_bridge.Substring(0, test_pa_bridge.Length-2)+")";
            //toolTip1.SetToolTip(btnRunPACal, test_pa_bridge);

            string path = Application.StartupPath+"\\Tests";
            if(!Directory.Exists(path))	Directory.CreateDirectory(path);
            bool file_exists = File.Exists(path+"\\pa_bridge.csv");
            StreamWriter writer = new StreamWriter(path+"\\pa_bridge.csv", true);
            if(!file_exists) writer.WriteLine("PA Serial Num, Date/Time, Version,"
                                 +"160-1, 160-2, 160-5, 160-10, 160-20, 160-90,"
                                 +"80-1, 80-2, 80-5, 80-10, 80-20, 80-90,"
                                 +"60-1, 60-2, 60-5, 60-10, 60-20, 60-90,"
                                 +"40-1, 40-2, 40-5, 40-10, 40-20, 40-90,"
                                 +"30-1, 30-2, 30-5, 30-10, 30-20, 30-90,"
                                 +"20-1, 20-2, 20-5, 20-10, 20-20, 20-90,"
                                 +"17-1, 17-2, 17-5, 17-10, 17-20, 17-90,"
                                 +"15-1, 15-2, 15-5, 15-10, 15-20, 15-90,"
                                 +"12-1, 12-2, 12-5, 12-10, 12-20, 12-90,"
                                 +"10-1, 10-2, 10-5, 10-10, 10-20, 10-90,"
                                 +"6-1, 6-2, 6-5, 6-10, 6-20, 6-90,");
            writer.Write(FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+","
                +DateTime.Now.ToShortDateString()+" "+DateTime.Now.ToShortTimeString()+","
                +console.Text+",");
            for(int i=0; i<bands.Length; i++)
            {
                for(int j=0; j<6; j++)
                    writer.Write(console.pa_bridge_table[(int)bands[i]][j].ToString("f2")+",");
            }
            writer.WriteLine("");
            writer.Close();

            path += "\\PA Bridge";
            if(!Directory.Exists(path)) Directory.CreateDirectory(path);
            writer = new StreamWriter(path+"\\pa_bridge_"+FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+".csv");
            writer.WriteLine("Band, 1w, 2w, 5w, 10w, 20w, 90w");
            for(int i=0; i<bands.Length; i++)
            {
                writer.Write(BandToString(bands[i])+",");
                for(int j=0; j<6; j++)
                    writer.Write(console.pa_bridge_table[(int)bands[i]][j].ToString("f4")+",");
                writer.WriteLine("");
            }
            writer.Close();

            if(progress.Text != "")
            {
                lstDebug.Items.Insert(0, "Saving Bridge data to EEPROM...");
                FWCEEPROM.WritePABridge(console.pa_bridge_table);
                console.FLEX5000SyncCalDateTime();
                lstDebug.Items[0] = "Saving Bridge data to EEPROM...done";
            }
            test_pa_power = "PA Power Test: Passed";

            bool pwr_pass = true;
            for(int i=0; i<bands.Length; i++)
            {
                for(int j=1; j<10; j++)
                {
                    if(console.power_table[(int)bands[i]][j] <= console.power_table[(int)bands[i]][j-1])
                    {
                        if(!test_pa_power.StartsWith("PA Power Test: Failed ("))
                            test_pa_power = "PA Power Test: Failed (";
                        test_pa_power += BandToString(bands[i])+", ";
                        pwr_pass = false;
                    }
                }
            }

            if(test_pa_power.StartsWith("PA Power Test: Failed ("))
                test_pa_power = test_pa_power.Substring(0, test_pa_power.Length-2)+")";
            toolTip1.SetToolTip(btnPAPower, test_pa_bridge+"\n\n"+test_pa_power);

            if(pass && pwr_pass) btnRunPACal.BackColor = Color.Green;
            else btnRunPACal.BackColor = Color.Red;

            path = Application.StartupPath+"\\Tests";
            if(!Directory.Exists(path))	Directory.CreateDirectory(path);
            file_exists = File.Exists(path+"\\pa_power.csv");
            writer = new StreamWriter(path+"\\pa_power.csv", true);
            if(!file_exists) writer.WriteLine("PA Serial Num, Date/Time, Version, "
                                 +"160-1, 160-2, 160-5, 160-10, 160-20, 160-30, 160-40, 160-50, 160-60, 160-70, 160-80, 160-90, 160-100,"
                                 +"80-1, 80-2, 80-5, 80-10, 80-20, 80-30, 80-40, 80-50, 80-60, 80-70, 80-80, 80-90, 80-100,"
                                 +"60-1, 60-2, 60-5, 60-10, 60-20, 60-30, 60-40, 60-50, 60-60, 60-70, 60-80, 60-90, 60-100,"
                                 +"40-1, 40-2, 40-5, 40-10, 40-20, 40-30, 40-40, 40-50, 40-60, 40-70, 40-80, 40-90, 40-100,"
                                 +"30-1, 30-2, 30-5, 30-10, 30-20, 30-30, 30-40, 30-50, 30-60, 30-70, 30-80, 30-90, 30-100,"
                                 +"20-1, 20-2, 20-5, 20-10, 20-20, 20-30, 20-40, 20-50, 20-60, 20-70, 20-80, 20-90, 20-100,"
                                 +"17-1, 17-2, 17-5, 17-10, 17-20, 17-30, 17-40, 17-50, 17-60, 17-70, 17-80, 17-90, 17-100,"
                                 +"15-1, 15-2, 15-5, 15-10, 15-20, 15-30, 15-40, 15-50, 15-60, 15-70, 15-80, 15-90, 15-100,"
                                 +"12-1, 12-2, 12-5, 12-10, 12-20, 12-30, 12-40, 12-50, 12-60, 12-70, 12-80, 12-90, 12-100,"
                                 +"10-1, 10-2, 10-5, 10-10, 10-20, 10-30, 10-40, 10-50, 10-60, 10-70, 10-80, 10-90, 10-100,"
                                 +"6-1, 6-2, 6-5, 6-10, 6-20, 6-30, 6-40, 6-50, 6-60, 6-70, 6-80, 6-90, 6-100");
            writer.Write(FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+","
                +DateTime.Now.ToShortDateString()+" "+DateTime.Now.ToShortTimeString()+","
                +console.Text+",");

            for(int i=0; i<bands.Length; i++)
            {
                for(int j=0; j<13; j++)
                    writer.Write(console.power_table[(int)bands[i]][j].ToString("f5")+",");
            }
            writer.WriteLine("");
            writer.Close();

            path += "\\PA Power";
            if(!Directory.Exists(path)) Directory.CreateDirectory(path);
            writer = new StreamWriter(path+"\\pa_power_"+FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+".csv");
            writer.WriteLine("Band, 1w, 2w, 5w, 10w, 20w, 30w, 40w, 50w, 60w, 70w, 80w, 90w, 100w");
            for(int i=0; i<bands.Length; i++)
            {
                writer.Write(BandToString(bands[i])+",");
                for(int j=0; j<13; j++)
                    writer.Write(console.power_table[(int)bands[i]][j].ToString("f5")+",");
                writer.WriteLine("");
            }
            writer.Close();

            if(progress.Text != "")
            {
                lstDebug.Items.Insert(0, "Saving Power data to EEPROM...");
                FWCEEPROM.WritePAPower(console.power_table);
                console.FLEX5000SyncCalDateTime();
                lstDebug.Items[0] = "Saving Power data to EEPROM...done";
            }

            try
            {
                writer = new StreamWriter(Application.StartupPath+"\\power.csv");
                writer.WriteLine("Band, 1, 2, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100");
                for(int i=1; i<=(int)Band.B6M; i++)
                {
                    writer.Write(((Band)i).ToString()+",");
                    for(int j=0; j<13; j++)
                        writer.Write(console.power_table[i][j].ToString("f4")+",");
                    writer.WriteLine("");
                }
                writer.Close();
            }
            catch(Exception)
            {
                MessageBox.Show("Error writing power.csv file.  Please make sure this file is not open and try again.",
                    "Error writing power.csv",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }

            if(File.Exists(Application.StartupPath+"\\Compression.xls"))
            {
                Process.Start(Application.StartupPath+"\\power.csv");
                Thread.Sleep(100);
                Process.Start(Application.StartupPath+"\\Compression.xls");
            }

            path = Application.StartupPath+"\\Tests";
            if(!Directory.Exists(path))	Directory.CreateDirectory(path);
            file_exists = File.Exists(path+"\\pa_swr.csv");
            writer = new StreamWriter(path+"\\pa_swr.csv", true);
            if(!file_exists) writer.WriteLine("PA Serial Num, Date/Time, Version, "
                                 +"160m, 80m, 60m, 40m, 30m, 20m, 17m, 15m, 12m, 10m, 6m");
            writer.Write(FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+","
                +DateTime.Now.ToShortDateString()+" "+DateTime.Now.ToShortTimeString()+","
                +console.Text+",");

            for(int i=0; i<bands.Length; i++)
                writer.Write(console.swr_table[(int)bands[i]].ToString("f5")+",");
            writer.WriteLine("");
            writer.Close();

            if(progress.Text != "")
            {
                lstDebug.Items.Insert(0, "Saving SWR data to EEPROM...");
                FWCEEPROM.WritePASWR(console.swr_table);
                console.FLEX5000SyncCalDateTime();
                lstDebug.Items[0] = "Saving SWR data to EEPROM...done";
            }

            //progress.Hide();
            grpPA.Enabled = true;
            grpIO.Enabled = true;
            btnRunPACal.Enabled = true;
        }
		private void CalATUSWR()
		{
			/*if(!console.PowerOn)
			{
				MessageBox.Show("Power must be on in order to calibrate SWR.", "Power Is Off",
					MessageBoxButtons.OK, MessageBoxIcon.Stop);
				grpIO.Enabled = true;
				grpPA.Enabled = true;
				progress.Hide();
				btnPASWR.BackColor = Color.Red;
				return;
			}*/

			Band[] bands = { Band.B160M, Band.B80M, Band.B60M, Band.B40M, Band.B30M, Band.B20M, Band.B17M, Band.B15M, Band.B12M, Band.B10M, Band.B6M };
			float[] band_freqs = { 1.85f, 3.75f, 5.357f, 7.15f, 10.125f, 14.175f, 18.1f, 21.300f, 24.9f, 28.4f, 50.11f};

			if(!console.PowerOn)
			{
				console.PowerOn = true;
				Thread.Sleep(500);
			}

			if(console.RXOnly)
			{
				progress.Text = "";
				progress.Hide();
				MessageBox.Show("Cannot run this calibration while RX Only is selected\n(Setup Form -> General Tab)",
					"Error: RX Only is active",
					MessageBoxButtons.OK, MessageBoxIcon.Error);
				btnATUSWR.BackColor = Color.Red;
				grpPA.Enabled = true;
				grpIO.Enabled = true;
				grpATU.Enabled = true;
				return;
			}

            if (!comboCOMPort.Text.StartsWith("COM"))
            {
                progress.Text = "";
                progress.Hide();
                MessageBox.Show("Invalid COM Port selected.  A valid COM Port connected to a PowerMaster is required.",
                    "Error: Invalid COM Port",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                btnRunPACal.BackColor = Color.Red;
                grpPA.Enabled = true;
                grpIO.Enabled = true;
                grpATU.Enabled = true;
                return;
            }

            PowerMaster pm;
            try
            {
                pm = new PowerMaster(comboCOMPort.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Error opening COM Port for Power Master",
                    "COM Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnRunPACal.BackColor = Color.Red;
                return;
            }

            Thread.Sleep(500);
            if (!pm.Present)
            {
                MessageBox.Show("No data received from PowerMaster on " + comboCOMPort.Text + ".\n" +
                    "Please check COM port and PowerMaster connections and settings.\n\n" +
                    "Make sure the PowerMaster shows \"F\" on the upper left of the display.\n" +
                    "Verify the selected COM port is correct.  Verify port in Device Manager.",
                    "No Data From PowerMaster",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnRunPACal.BackColor = Color.Red;
                return;
            }

			if(console.VFOSync)
				console.VFOSync = false;

			double vfoa = console.VFOAFreq;

			DSPMode dsp_mode = console.RX1DSPMode;
			console.RX1DSPMode = DSPMode.USB;

			console.FullDuplex = false;
			console.VFOSplit = false;

			int counter = 0;
			int num_bands = 0;
			for(int i=0; i<band_freqs.Length; i++)
			{
				bool do_band = false;
				switch(bands[i])
				{
					case Band.B160M: do_band = ck160.Checked; break;
					case Band.B80M: do_band = ck80.Checked; break;
					case Band.B60M: do_band = ck60.Checked; break;
					case Band.B40M: do_band = ck40.Checked; break;
					case Band.B30M: do_band = ck30.Checked; break;
					case Band.B20M: do_band = ck20.Checked; break;
					case Band.B17M: do_band = ck17.Checked; break;
					case Band.B15M: do_band = ck15.Checked; break;
					case Band.B12M: do_band = ck12.Checked; break;
					case Band.B10M:	do_band = ck10.Checked; break;
					case Band.B6M: do_band = ck6.Checked; break;
				}
				if(do_band) num_bands++;
			}

			int total_counts = num_bands*15;

			for(int i=0; i<band_freqs.Length; i++)
			{
				bool do_band = false;
				switch(bands[i])
				{
					case Band.B160M: do_band = ck160.Checked; break;
					case Band.B80M: do_band = ck80.Checked; break;
					case Band.B60M: do_band = ck60.Checked; break;
					case Band.B40M: do_band = ck40.Checked; break;
					case Band.B30M: do_band = ck30.Checked; break;
					case Band.B20M: do_band = ck20.Checked; break;
					case Band.B17M: do_band = ck17.Checked; break;
					case Band.B15M: do_band = ck15.Checked; break;
					case Band.B12M: do_band = ck12.Checked; break;
					case Band.B10M:	do_band = ck10.Checked; break;
					case Band.B6M: do_band = ck6.Checked; break;
				}

				if(do_band)
				{					
					console.VFOAFreq = band_freqs[i];

					FWCAnt tx_ant = console.TXAnt;
					console.TXAnt = FWCAnt.ANT2;
					for(int j=0; j<5; j++)
					{
						Thread.Sleep(50);
						if(!progress.Visible) goto end2;
						progress.SetPercent(counter++/(float)total_counts);
					}

					console.atu_swr_table[(int)bands[i]] = 1.0f;
					console.TUN = true;
					int old_tun_pwr = console.PWR;
					console.PWR = 10;
					for(int j=0; j<10; j++)
					{
						Thread.Sleep(50);
						if(!progress.Visible) goto end1;
						progress.SetPercent(counter++/(float)total_counts);
					}
					
					double f = console.ReadFwdPower(3);					
					double r = console.ReadRefPower(3);
					Debug.WriteLine("f: "+f.ToString("f1")+"  r: "+r.ToString("f1"));

					float alpha = (float)(f/r/9);

					console.atu_swr_table[(int)bands[i]] = (float)Math.Round(alpha, 4);
					if(alpha < 0.1f || alpha > 5.0f)
						lstDebug.Items.Insert(0, "ATU SWR Failed - "+BandToString(bands[i])+": "+alpha.ToString("f4"));
					else lstDebug.Items.Insert(0, "ATU SWR Passed - "+BandToString(bands[i])+": "+alpha.ToString("f4"));

				end1:
					console.PWR = old_tun_pwr;
					console.TUN = false;
				end2:
					console.TXAnt = tx_ant;
					if(!progress.Visible) goto end3;
				}
			}
		end3:
			console.VFOAFreq = 0.590;
			console.VFOAFreq = vfoa;
			console.RX1DSPMode = dsp_mode;
			console.FullDuplex = false;
			toolTip1.SetToolTip(btnATUSWR, test_atu_swr);

			bool fail = false;
			for(int i=0; i<11; i++)
			{
				if(console.atu_swr_table[(int)bands[i]] < 0.1f ||
					console.atu_swr_table[(int)bands[i]] > 5.0f)
				{
					btnATUSWR.BackColor = Color.Red;
					fail = true;	
				}
			}

			if(!fail) btnATUSWR.BackColor = Color.Green;

            string path = console.AppDataPath + "\\Tests";
			if(!Directory.Exists(path))	Directory.CreateDirectory(path);
			bool file_exists = File.Exists(path+"\\atu_swr.csv");
			StreamWriter writer = new StreamWriter(path+"\\atu_swr.csv", true);
			if(!file_exists) writer.WriteLine("PA Serial Num, Date/Time, Version, "
								 +"160m, 80m, 60m, 40m, 30m, 20m, 17m, 15m, 12m, 10m, 6m");
			writer.Write(FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+","
				+DateTime.Now.ToShortDateString()+" "+DateTime.Now.ToShortTimeString()+","
				+console.Text+",");

			for(int i=0; i<bands.Length; i++)
				writer.Write(console.atu_swr_table[(int)bands[i]].ToString("f5")+",");
			writer.WriteLine("");
			writer.Close();

			lstDebug.Items.Insert(0, "Saving ATU SWR data to EEPROM...");
			byte checksum;
			FWCEEPROM.WriteATUSWR(console.atu_swr_table, out checksum);
			console.atu_swr_checksum = checksum;
			console.SyncCalDateTime();
			lstDebug.Items[0] = "Saving ATU SWR data to EEPROM...done";

			progress.Hide();
			if(console.CurrentModel == Model.FLEX3000)
				FWC.SetFan(false);
			grpPA.Enabled = true;
			grpIO.Enabled = true;
			grpATU.Enabled = true;
		}
		private void VerifyPA()
		{
			//float tol = 0.05f; // 5%

			/*if(!console.PowerOn)
			{
				MessageBox.Show("Power must be on in order to Verify PA.", "Power Is Off",
					MessageBoxButtons.OK, MessageBoxIcon.Stop);
				grpIO.Enabled = true;
				grpPA.Enabled = true;
				progress.Hide();
				btnPAVerify.BackColor = Color.Red;
				return;
			}*/

			if(!console.PowerOn)
			{
				console.PowerOn = true;
				Thread.Sleep(500);
			}

			if(console.RXOnly)
			{
				progress.Text = "";
				progress.Hide();
				MessageBox.Show("Cannot run this calibration while RX Only is selected\n(Setup Form -> General Tab)",
					"Error: RX Only is active",
					MessageBoxButtons.OK, MessageBoxIcon.Error);
				btnPAVerify.BackColor = Color.Red;
				grpPA.Enabled = true;
				grpIO.Enabled = true;
				grpATU.Enabled = true;
				return;
			}

            if (!comboCOMPort.Text.StartsWith("COM"))
            {
                progress.Text = "";
                progress.Hide();
                MessageBox.Show("Invalid COM Port selection.  A valid COM port connected to a PowerMaster is required.",
                    "Error: Invalid COM Port",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                btnPAVerify.BackColor = Color.Red;
                grpPA.Enabled = true;
                grpIO.Enabled = true;
                grpATU.Enabled = true;
                return;
            }

			if(console.VFOSync)
				console.VFOSync = false;

			bool leveler = console.dsp.GetDSPTX(0).TXLevelerOn;
			console.dsp.GetDSPTX(0).TXLevelerOn = false;

			PowerMaster pm;
			try
			{
				pm = new PowerMaster(comboCOMPort.Text);
			}
			catch(Exception)
			{
				MessageBox.Show("Error opening COM Port for Power Master",
					"COM Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				grpIO.Enabled = true;
				grpPA.Enabled = true;
				progress.Hide();
				btnPAVerify.BackColor = Color.Red;
				return;
			}

            Thread.Sleep(500);
            if (!pm.Present)
            {
                MessageBox.Show("No data received from PowerMaster on " + comboCOMPort.Text + ".\n" +
                    "Please check COM port and PowerMaster connections and settings.\n\n" +
                    "Make sure the PowerMaster shows \"F\" on the upper left of the display.\n" +
                    "Verify the selected COM port is correct.  Verify port in Device Manager.",
                    "No Data From PowerMaster",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnPAVerify.BackColor = Color.Red;
                return;
            }

			Band[] bands = { Band.B6M, Band.B160M, Band.B80M, Band.B60M, Band.B40M, Band.B30M, Band.B20M, Band.B17M, Band.B15M, Band.B12M, Band.B10M};
			float[] band_freqs = { 50.11f, 1.85f, 3.75f, 5.357f, 7.15f, 10.125f, 14.175f, 18.1f, 21.300f, 24.9f, 28.4f};
			int[] targets = { 10, 100 };
			float[][] bridge_power = new float[bands.Length][];
			for(int i=0; i<bands.Length; i++)
				bridge_power[i] = new float[targets.Length];
			float[][] pm_power = new float[bands.Length][];
			for(int i=0; i<bands.Length; i++)
				pm_power[i] = new float[targets.Length];

			float[] pm_trim = { 1.04f, 1.03f, 1.03f, 1.03f, 1.02f, 1.01f, 1.01f, 1.0f, 1.0f, 1.0f, 0.9f };
			try
			{
                string pm_file_path = Path.Combine(common_data_path, "powermaster.txt");
                StreamReader reader = new StreamReader(pm_file_path);
				string temp = reader.ReadLine();

				int start = temp.IndexOf(":")+1;
				int length = temp.Length - start;
				lstDebug.Items.Insert(0, "PowerMaster S/N: "+temp.Substring(start, length).Trim());
				
				for(int i=0; i<11; i++)
				{
					temp = reader.ReadLine();
					start = temp.IndexOf(":")+1;
					length = temp.Length - start;
					int index = i+1;
					if(index == 11) index = 0;
					pm_trim[index] = 1.0f+0.01f*float.Parse(temp.Substring(start, length).Trim());
					lstDebug.Items.Insert(0, BandToString(bands[index])+": "+pm_trim[i].ToString("f2"));
				}
				reader.Close();
			}
			catch(Exception)
			{
				MessageBox.Show("Error reading Array Solutions Power Master calibration file.  Using defaults.");
			}

			double vfoa = console.VFOAFreq;
			double vfob = console.VFOBFreq;

			int tune_power = console.TunePower;
			console.TunePower = 100;

			MeterTXMode tx_meter = console.CurrentMeterTXMode;
			console.CurrentMeterTXMode = MeterTXMode.FORWARD_POWER;

			progress.SetPercent(0.0f);

			int counter = 0;
			int num_bands = 0;
			for(int i=0; i<band_freqs.Length; i++)
			{
				bool do_band = false;
				switch(bands[i])
				{
					case Band.B160M: do_band = ck160.Checked; break;
					case Band.B80M: do_band = ck80.Checked; break;
					case Band.B60M: do_band = ck60.Checked; break;
					case Band.B40M: do_band = ck40.Checked; break;
					case Band.B30M: do_band = ck30.Checked; break;
					case Band.B20M: do_band = ck20.Checked; break;
					case Band.B17M: do_band = ck17.Checked; break;
					case Band.B15M: do_band = ck15.Checked; break;
					case Band.B12M: do_band = ck12.Checked; break;
					case Band.B10M:	do_band = ck10.Checked; break;
					case Band.B6M: do_band = ck6.Checked; break;
				}
				if(do_band) num_bands++;
			}

			int total_counts = num_bands*targets.Length*40;

			switch(console.CurrentModel)
			{
				case Model.FLEX3000:
					FWC.SetAmpTX1(false);
					FWC.SetRCATX1(false);
					break;
			}

			for(int i=0; i<band_freqs.Length; i++)
			{
				bool do_band = false;
				switch(bands[i])
				{
					case Band.B160M: do_band = ck160.Checked; break;
					case Band.B80M: do_band = ck80.Checked; break;
					case Band.B60M: do_band = ck60.Checked; break;
					case Band.B40M: do_band = ck40.Checked; break;
					case Band.B30M: do_band = ck30.Checked; break;
					case Band.B20M: do_band = ck20.Checked; break;
					case Band.B17M: do_band = ck17.Checked; break;
					case Band.B15M: do_band = ck15.Checked; break;
					case Band.B12M: do_band = ck12.Checked; break;
					case Band.B10M:	do_band = ck10.Checked; break;
					case Band.B6M: do_band = ck6.Checked; break;
				}

				if(do_band)
				{
					console.VFOAFreq = band_freqs[i];
					console.VFOBFreq = band_freqs[i];
					
					switch(console.CurrentModel)
					{
						case Model.FLEX5000:
							FWC.SetTXAnt(1);
							break;
					}
					//Thread.Sleep(50);

					DSPMode dsp_mode = console.RX1DSPMode;
					console.RX1DSPMode = DSPMode.USB;

					console.VFOAFreq = band_freqs[i];
					console.VFOBFreq = band_freqs[i];

					for(int k=0; k<targets.Length; k++)
					{
						console.TunePower = targets[k];
						console.TUN = true;
						for(int j=0; j<10; j++)
						{
							progress.SetPercent(++counter/(float)total_counts);
							if(!progress.Visible) goto end;
							Thread.Sleep(50);
						}

						pm_power[i][k] = pm.Watts*pm_trim[i];
						float current = console.ReadFinalBias(3, false);

						//bridge_power[i][k] = console.NewMeterData;
						console.TUN = false;
						for(int j=0; j<20; j++)
						{
							progress.SetPercent(++counter/(float)total_counts);
							if(!progress.Visible) goto end;
							Thread.Sleep(50);
						}						

						if((pm_power[i][k] < targets[k] - 5.0f) ||
							(pm_power[i][k] > targets[k] + 20.0f))
						{
							btnPAVerify.BackColor = Color.Red;
							if(!test_pa_verify.StartsWith("PA Verify Test: Failed ("))
								test_pa_verify = "PA Verify Test: Failed (";
							test_pa_verify += BandToString(bands[i])+"-"+targets[k]+", ";
							lstDebug.Items.Insert(0, "PA Verify - "+BandToString(bands[i])+": Failed ("+
								targets[k]+", "+pm_power[i][k].ToString("f1")+", "+current.ToString("f1")+"A)");
						}
						else
						{
							lstDebug.Items.Insert(0, "PA Verify - "+BandToString(bands[i])+": Passed ("+
								targets[k]+", "+pm_power[i][k].ToString("f1")+", "+current.ToString("f1")+"A)");	
						}
					}
					console.RX1DSPMode = dsp_mode;
				}
			}

		end:
			console.TUN = false;
			console.VFOAFreq = 0.590;
			console.VFOAFreq = vfoa;
			console.VFOBFreq = vfob;
			console.TunePower = tune_power;
			console.FullDuplex = false;

			console.CurrentMeterTXMode = tx_meter;

			switch(console.CurrentModel)
			{
				case Model.FLEX3000:
					FWC.SetAmpTX1(true);
					break;
			}

			try
			{
				pm.Close(); 
			}
			catch(Exception) { }

			console.dsp.GetDSPTX(0).TXLevelerOn = leveler;

			if(test_pa_verify.StartsWith("PA Verify Test: Failed ("))
				test_pa_verify = test_pa_verify.Substring(0, test_pa_verify.Length-2)+")";
			toolTip1.SetToolTip(btnPAVerify, test_pa_verify);

            string path = console.AppDataPath + "\\Tests";
			if(!Directory.Exists(path))	Directory.CreateDirectory(path);
			bool file_exists = File.Exists(path+"\\pa_verify.csv");
			StreamWriter writer = new StreamWriter(path+"\\pa_verify.csv", true);
			if(!file_exists) writer.WriteLine("PA Serial Num, Date/Time, Version,"
								 +"Bridge 6-10, PM 6-10, Bridge 6-100, PM 6-100,"
								 +"Bridge 160-10, PM 160-10, Bridge 160-100, PM 160-100,"
								 +"Bridge 80-10, PM 80-10, Bridge 80-100, PM 80-100,"
								 +"Bridge 60-10, PM 60-10, Bridge 60-100, PM 60-100,"
								 +"Bridge 40-10, PM 40-10, Bridge 40-100, PM 40-100,"
								 +"Bridge 30-10, PM 30-10, Bridge 30-100, PM 30-100,"
								 +"Bridge 20-10, PM 20-10, Bridge 20-100, PM 20-100,"
								 +"Bridge 17-10, PM 17-10, Bridge 17-100, PM 17-100,"
								 +"Bridge 15-10, PM 15-10, Bridge 15-100, PM 15-100,"
								 +"Bridge 12-10, PM 12-10, Bridge 12-100, PM 12-100,"
								 +"Bridge 10-10, PM 10-10, Bridge 10-100, PM 10-100,"								 
								);
			writer.Write(FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+","
				+DateTime.Now.ToShortDateString()+" "+DateTime.Now.ToShortTimeString()+","
				+console.Text+",");
			for(int i=0; i<bands.Length; i++)
			{
				for(int j=0; j<targets.Length; j++)
				{
					writer.Write(bridge_power[i][j].ToString("f1")+",");
					writer.Write(pm_power[i][j].ToString("f1")+",");
				}
			}
			writer.WriteLine("");
			writer.Close();

			path += "\\PA Verify";
			if(!Directory.Exists(path)) Directory.CreateDirectory(path);
			writer = new StreamWriter(path+"\\pa_bridge_"+FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+".csv");
			writer.WriteLine("Band, Bridge 10w, PM 10w, Bridge 100w, PM 100w");
			for(int i=0; i<bands.Length; i++)
			{
				writer.Write(BandToString(bands[i])+",");
				for(int j=0; j<targets.Length; j++)
				{
					writer.Write(bridge_power[i][j].ToString("f1")+",");
					writer.Write(pm_power[i][j].ToString("f1")+",");
				}
				writer.WriteLine("");
			}
			writer.Close();

            string eeprom_file_path = Path.Combine(common_data_path, "EEPROM.exe");
            if(File.Exists(eeprom_file_path))
			{
				DialogResult dr = MessageBox.Show("Would you like to save EEPROM data to a file now?",
					"Save EEPROM Data?",
					MessageBoxButtons.YesNo,
					MessageBoxIcon.Question);
				if(dr == DialogResult.Yes)							
					Process.Start(eeprom_file_path);
			}

			progress.Hide();	
			grpPA.Enabled = true;
			grpIO.Enabled = true;
			grpATU.Enabled = true;
		}
		private void CalPAPower()
		{
			if(!console.PowerOn)
			{
				console.PowerOn = true;
				Thread.Sleep(500);
			}

			if(console.RXOnly)
			{
				progress.Text = "";
				progress.Hide();
				MessageBox.Show("Cannot run this calibration while RX Only is selected\n(Setup Form -> General Tab)",
					"Error: RX Only is active",
					MessageBoxButtons.OK, MessageBoxIcon.Error);
				btnPAPower.BackColor = Color.Red;
				grpPA.Enabled = true;
				grpIO.Enabled = true;
				grpATU.Enabled = true;
				return;
			}

            if (!comboCOMPort.Text.StartsWith("COM"))
            {
                progress.Text = "";
                progress.Hide();
                MessageBox.Show("Invalid COM Port selected.  A valid COM Port connected to a PowerMaster is required.",
                    "Error: Invalid COM Port",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                btnRunPACal.BackColor = Color.Red;
                grpPA.Enabled = true;
                grpIO.Enabled = true;
                grpATU.Enabled = true;
                return;
            }

            PowerMaster pm;
            try
            {
                pm = new PowerMaster(comboCOMPort.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Error opening COM Port for Power Master",
                    "COM Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnRunPACal.BackColor = Color.Red;
                return;
            }

            Thread.Sleep(500);
            if (!pm.Present)
            {
                MessageBox.Show("No data received from PowerMaster on " + comboCOMPort.Text + ".\n" +
                    "Please check COM port and PowerMaster connections and settings.\n\n" +
                    "Make sure the PowerMaster shows \"F\" on the upper left of the display.\n" +
                    "Verify the selected COM port is correct.  Verify port in Device Manager.",
                    "No Data From PowerMaster",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnRunPACal.BackColor = Color.Red;
                return;
            }

            if(console.VFOSync)
				console.VFOSync = false;

			bool leveler = console.dsp.GetDSPTX(0).TXLevelerOn;
			console.dsp.GetDSPTX(0).TXLevelerOn = false;

			bool[] run = new bool[11];
			run[0] = ck160.Checked;
			run[1] = ck80.Checked;
			run[2] = ck60.Checked;
			run[3] = ck40.Checked;
			run[4] = ck30.Checked;
			run[5] = ck20.Checked;
			run[6] = ck17.Checked;
			run[7] = ck15.Checked;
			run[8] = ck12.Checked;
			run[9] = ck10.Checked;
			run[10] = ck6.Checked;
			console.CalibratePAGain2(progress, run, true);

			console.dsp.GetDSPTX(0).TXLevelerOn = leveler;

			test_pa_power = "PA Power Test: Passed";
			Band[] bands = { Band.B160M, Band.B80M, Band.B60M, Band.B40M, Band.B30M, Band.B20M, Band.B17M, Band.B15M, Band.B12M, Band.B10M, Band.B6M };
			bool b = true;
			for(int i=0; i<bands.Length; i++)
			{
				for(int j=1; j<10; j++)
				{
					if(console.power_table[(int)bands[i]][j] == console.power_table[(int)bands[i]][j-1])
					{
						if(!test_pa_power.StartsWith("PA Power Test: Failed ("))
							test_pa_power = "PA Power Test: Failed (";
						test_pa_power += BandToString(bands[i])+", ";
						b = false;
						j = 10;
					}
				}
			}

			if(test_pa_power.StartsWith("PA Power Test: Failed ("))
				test_pa_power = test_pa_power.Substring(0, test_pa_power.Length-2)+")";
			toolTip1.SetToolTip(btnPAPower, test_pa_power);

			if(b) btnPAPower.BackColor = Color.Green;
			else btnPAPower.BackColor = Color.Red;

            string path = console.AppDataPath + "\\Tests";
			if(!Directory.Exists(path))	Directory.CreateDirectory(path);
			bool file_exists = File.Exists(path+"\\pa_power.csv");
			StreamWriter writer = new StreamWriter(path+"\\pa_power.csv", true);
			if(!file_exists) writer.WriteLine("PA Serial Num, Date/Time, Version, "
								+"160-1, 160-2, 160-5, 160-10, 160-20, 160-30, 160-40, 160-50, 160-60, 160-70, 160-80, 160-90, 160-100,"
								+"80-1, 80-2, 80-5, 80-10, 80-20, 80-30, 80-40, 80-50, 80-60, 80-70, 80-80, 80-90, 80-100,"
								+"60-1, 60-2, 60-5, 60-10, 60-20, 60-30, 60-40, 60-50, 60-60, 60-70, 60-80, 60-90, 60-100,"
								+"40-1, 40-2, 40-5, 40-10, 40-20, 40-30, 40-40, 40-50, 40-60, 40-70, 40-80, 40-90, 40-100,"
								+"30-1, 30-2, 30-5, 30-10, 30-20, 30-30, 30-40, 30-50, 30-60, 30-70, 30-80, 30-90, 30-100,"
								+"20-1, 20-2, 20-5, 20-10, 20-20, 20-30, 20-40, 20-50, 20-60, 20-70, 20-80, 20-90, 20-100,"
								+"17-1, 17-2, 17-5, 17-10, 17-20, 17-30, 17-40, 17-50, 17-60, 17-70, 17-80, 17-90, 17-100,"
								+"15-1, 15-2, 15-5, 15-10, 15-20, 15-30, 15-40, 15-50, 15-60, 15-70, 15-80, 15-90, 15-100,"
								+"12-1, 12-2, 12-5, 12-10, 12-20, 12-30, 12-40, 12-50, 12-60, 12-70, 12-80, 12-90, 12-100,"
								+"10-1, 10-2, 10-5, 10-10, 10-20, 10-30, 10-40, 10-50, 10-60, 10-70, 10-80, 10-90, 10-100,"
								+"6-1, 6-2, 6-5, 6-10, 6-20, 6-30, 6-40, 6-50, 6-60, 6-70, 6-80, 6-90, 6-100");
			writer.Write(FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+","
				+DateTime.Now.ToShortDateString()+" "+DateTime.Now.ToShortTimeString()+","
				+console.Text+",");

			for(int i=0; i<bands.Length; i++)
			{
				for(int j=0; j<13; j++)
					writer.Write(console.power_table[(int)bands[i]][j].ToString("f5")+",");
			}
			writer.WriteLine("");
			writer.Close();

			path += "\\PA Power";
			if(!Directory.Exists(path)) Directory.CreateDirectory(path);
			writer = new StreamWriter(path+"\\pa_power_"+FWCEEPROM.SerialToString(FWCEEPROM.PASerial)+".csv");
			writer.WriteLine("Band, 1w, 2w, 5w, 10w, 20w, 30w, 40w, 50w, 60w, 70w, 80w, 90w, 100w");
			for(int i=0; i<bands.Length; i++)
			{
				writer.Write(BandToString(bands[i])+",");
				for(int j=0; j<13; j++)
					writer.Write(console.power_table[(int)bands[i]][j].ToString("f5")+",");
				writer.WriteLine("");
			}
			writer.Close();

			lstDebug.Items.Insert(0, "Saving Power data to EEPROM...");
			byte checksum;
			FWCEEPROM.WritePAPower(console.power_table, out checksum);
			console.pa_power_checksum = checksum;
			console.SyncCalDateTime();
			lstDebug.Items[0] = "Saving Power data to EEPROM...done";

            if (File.Exists(console.AppDataPath + "\\Compression.xls"))
			{
                Process.Start(console.AppDataPath + "\\power.csv");
				Thread.Sleep(100);
                Process.Start(console.AppDataPath + "\\Compression.xls");
			}

			if(console.CurrentModel == Model.FLEX3000)
				FWC.SetFan(false);
			grpPA.Enabled = true;
			grpIO.Enabled = true;
			grpATU.Enabled = true;
		}
		private void NullBridge()
		{
			/*if(!console.PowerOn)
			{
				MessageBox.Show("Power must be on in order to run Null Bridge.", "Power Is Off",
					MessageBoxButtons.OK, MessageBoxIcon.Stop);
				progress.Hide();
				grpPA.Enabled = true;
				grpIO.Enabled = true;
				return;
			}*/

			if(console.RXOnly)
			{
				progress.Text = "";
				progress.Hide();
				MessageBox.Show("Cannot run this calibration while RX Only is selected\n(Setup Form -> General Tab)",
					"Error: RX Only is active",
					MessageBoxButtons.OK, MessageBoxIcon.Error);
				btnNullBridge.BackColor = Color.Red;
				grpPA.Enabled = true;
				grpIO.Enabled = true;
				grpATU.Enabled = true;
				return;
			}

            if(!comboCOMPort.Text.StartsWith("COM"))
            {
                progress.Text = "";
                progress.Hide();
                MessageBox.Show("Invalid COM Port selection.  A valid COM port connected to a PowerMaster is required.",
                    "Invalid COM Port",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                btnNullBridge.BackColor = Color.Red;
                grpPA.Enabled = true;
                grpIO.Enabled = true;
                grpATU.Enabled = true;
                return;
            }

			if(!console.PowerOn)
			{
				console.PowerOn = true;
				Thread.Sleep(500);
			}

			if(console.VFOSync)
				console.VFOSync = false;

			PowerMaster pm;
			try
			{
				pm = new PowerMaster(comboCOMPort.Text);
			}
			catch(Exception)
			{
				MessageBox.Show("Error opening COM Port for Power Master",
					"COM Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				grpIO.Enabled = true;
				grpPA.Enabled = true;
				progress.Hide();
				btnNullBridge.BackColor = Color.Red;
				return;
			}

            Thread.Sleep(500);
            if (!pm.Present)
            {
                MessageBox.Show("No data received from PowerMaster on " + comboCOMPort.Text + ".\n" +
                    "Please check COM port and PowerMaster connections and settings.\n\n" +
                    "Make sure the PowerMaster shows \"F\" on the upper left of the display.\n" +
                    "Verify the selected COM port is correct.  Verify port in Device Manager.",
                    "No Data From PowerMaster",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                grpIO.Enabled = true;
                grpPA.Enabled = true;
                progress.Hide();
                btnNullBridge.BackColor = Color.Red;
                return;
            } 

			Band[] bands = { Band.B160M, Band.B80M, Band.B60M, Band.B40M, Band.B30M, Band.B20M, Band.B17M, Band.B15M, Band.B12M, Band.B10M, Band.B6M };
			float[] pm_trim = { 1.04f, 1.03f, 1.03f, 1.03f, 1.02f, 1.01f, 1.01f, 1.0f, 1.0f, 1.0f, 0.9f };
			try
			{
                string pm_file_path = Path.Combine(common_data_path, "powermaster.txt");
                StreamReader reader = new StreamReader(pm_file_path);
				string temp = reader.ReadLine();

				int start = temp.IndexOf(":")+1;
				int length = temp.Length - start;
				lstDebug.Items.Insert(0, "PowerMaster S/N: "+temp.Substring(start, length).Trim());
				
				for(int i=0; i<11; i++)
				{
					temp = reader.ReadLine();
					start = temp.IndexOf(":")+1;
					length = temp.Length - start;
					pm_trim[i] = 1.0f+0.01f*float.Parse(temp.Substring(start, length).Trim());
					lstDebug.Items.Insert(0, BandToString(bands[i])+": "+pm_trim[i].ToString("f2"));
				}
				reader.Close();
			}
			catch(Exception)
			{
				MessageBox.Show("Error reading Array Solutions Power Master calibration file.  Using defaults.");
			}

			double vfoa = console.VFOAFreq;
			console.VFOAFreq = 28.1;

			double vfob = console.VFOBFreq;
			console.VFOBFreq = 28.1;

			console.FullDuplex = true;

			FWC.SetQSD(true);
			//Thread.Sleep(50);
			FWC.SetQSE(true);
			//Thread.Sleep(50);
			FWC.SetTR(true);
			//Thread.Sleep(50);
			FWC.SetSig(true);
			//Thread.Sleep(50);
			FWC.SetGen(false);
			//Thread.Sleep(50);
			FWC.SetTest(true);
			//Thread.Sleep(50);
			FWC.SetTXMon(false);
			//Thread.Sleep(50);

			FWC.SetTXAnt(1);
			//Thread.Sleep(50);

			DSPMode dsp_mode = console.RX1DSPMode;
			console.RX1DSPMode = DSPMode.USB;

			int power = console.PWR;
			console.PWR = 100;
			
			if(console.CurrentModel == Model.FLEX3000)
				FWC.SetAmpTX1(false);

			FWC.SetMOX(true);
			console.TXCal = true;
			//Thread.Sleep(50);
			Audio.TXInputSignal = Audio.SignalSource.SINE;
			double scale = Audio.SourceScale;
			Audio.SourceScale = 1.0;
			switch(console.CurrentModel)
			{
				case Model.FLEX5000:
					Audio.RadioVolume = 0.05;
					break;
				case Model.FLEX3000:
					Audio.RadioVolume = 0.075;
					break;
			}

			grpBridgeNull.Visible = true;
			Thread.Sleep(1500);

			lstDebug.Items.Insert(0, "PM: "+(pm.Watts*pm_trim[10]).ToString("f1"));
			if(pm.Watts*pm_trim[10] < 10.0f)
			{
				FWC.SetMOX(false);
				//Thread.Sleep(50);
				progress.Hide();
				MessageBox.Show("PA Bridge Null Error: Low Power from PowerMaster.\nCheck COM port and try again.",
					"PA Bridge Null: Low Power",
					MessageBoxButtons.OK,
					MessageBoxIcon.Error);
				pm.Close();
			}
			else
			{
				pm.Close();
				while(progress.Visible)
				{				
					bridge_null_volts = bridge_null_volts*0.8f + console.ReadRefPowerVolts(1)*0.2f;
					picNullBridge.Invalidate();
					Thread.Sleep(100);
				}
			}

			grpBridgeNull.Visible = false;

			FWC.SetMOX(false);
			console.TXCal = false;
			//Thread.Sleep(50);
			FWC.SetQSD(true);
			//Thread.Sleep(50);
			FWC.SetQSE(false);	
			//Thread.Sleep(50);
			FWC.SetTR(false);
			//Thread.Sleep(50);
			FWC.SetSig(false);
			//Thread.Sleep(50);
			FWC.SetGen(false);
			//Thread.Sleep(50);
			FWC.SetTest(false);
			//Thread.Sleep(50);
			FWC.SetTXMon(false);
			//Thread.Sleep(50);
			Audio.TXInputSignal = Audio.SignalSource.RADIO;
			Audio.SourceScale = scale;
			console.RX1DSPMode = dsp_mode;
			console.VFOAFreq = vfoa;
			console.VFOBFreq = vfob;
			console.PWR = power;
			console.FullDuplex = false;

			if(console.CurrentModel == Model.FLEX3000)
			{
				FWC.SetFan(false);
				if(console.CurrentModel == Model.FLEX3000)
					FWC.SetAmpTX1(true);
			}
			grpPA.Enabled = true;
			grpIO.Enabled = true;
			grpATU.Enabled = true;
			btnNullBridge.BackColor = Color.Green;			
		}
        private void Cal1500PA()
        {
            if (!console.PowerOn)
            {
                console.PowerOn = true;
                Thread.Sleep(500);
            }

            if (console.RXOnly)
            {
                p.Text = "";
                p.Hide();
                MessageBox.Show("Cannot run this calibration while RX Only is selected\n(Setup Form -> General Tab)",
                    "Error: RX Only is active",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                btnTX1500PA.BackColor = Color.Red;
                grpGeneral.Enabled = true;
                grpReceiver.Enabled = true;
                grpTransmitter.Enabled = true;
                return;
            }

            if (!comboCOMPort.Text.StartsWith("COM"))
            {
                p.Text = "";
                p.Hide();
                MessageBox.Show("Invalid COM Port selected.  A valid COM Port connected to a PowerMaster is required.",
                    "Error: RX Only is active",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                btnTX1500PA.BackColor = Color.Red;
                grpGeneral.Enabled = true;
                grpReceiver.Enabled = true;
                grpTransmitter.Enabled = true;
                return;
            }

            if (console.VFOSync)
                console.VFOSync = false;

            bool disable_ptt = console.DisablePTT;
            console.DisablePTT = true;

            bool leveler = console.dsp.GetDSPTX(0).TXLevelerOn;
            console.dsp.GetDSPTX(0).TXLevelerOn = false;

            PowerMaster pm;
            try
            {
                pm = new PowerMaster(comboCOMPort.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Error opening COM Port for PowerMaster",
                    "COM Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                grpGeneral.Enabled = true;
                grpReceiver.Enabled = true;
                grpTransmitter.Enabled = true;
                p.Hide();
                btnTX1500PA.BackColor = Color.Red;
                return;
            }

            Thread.Sleep(500);
            if (!pm.Present)
            {
                MessageBox.Show("No data received from PowerMaster on " + comboCOMPort.Text + ".\n" +
                    "Please check COM port and PowerMaster connections and settings.\n\n" +
                    "Make sure the PowerMaster shows \"F\" on the upper left of the display.\n" +
                    "Verify the selected COM port is correct.  Verify port in Device Manager.",
                    "No Data From PowerMaster",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                grpGeneral.Enabled = true;
                grpReceiver.Enabled = true;
                grpTransmitter.Enabled = true;
                p.Hide();
                btnTX1500PA.BackColor = Color.Red;
                return;
            }

            Band[] bands = { Band.B6M, Band.B160M, Band.B80M, Band.B60M, Band.B40M, Band.B30M, Band.B20M, Band.B17M, Band.B15M, Band.B12M, Band.B10M };
            float[] band_freqs = { 50.11f, 1.85f, 3.75f, 5.357f, 7.15f, 10.125f, 14.175f, 18.1f, 21.300f, 24.9f, 28.4f };
            float target = 5.1f; // 5W + some overhead

            float[] pm_trim = { 1.04f, 1.03f, 1.03f, 1.03f, 1.02f, 1.01f, 1.01f, 1.0f, 1.0f, 1.0f, 0.9f };
            try
            {
                string pm_file_path = Path.Combine(common_data_path, "powermaster.txt");
                StreamReader reader = new StreamReader(pm_file_path);
                string temp = reader.ReadLine();

                int start = temp.IndexOf(":") + 1;
                int length = temp.Length - start;
                lstDebug.Items.Insert(0, "PowerMaster S/N: " + temp.Substring(start, length).Trim());

                for (int i = 0; i < 11; i++)
                {
                    temp = reader.ReadLine();
                    start = temp.IndexOf(":") + 1;
                    length = temp.Length - start;
                    int index = i + 1;
                    if (index == 11) index = 0;
                    pm_trim[index] = 1.0f + 0.01f * float.Parse(temp.Substring(start, length).Trim());
                    lstDebug.Items.Insert(0, BandToString(bands[index]) + ": " + pm_trim[index].ToString("f2"));
                }
                reader.Close();
            }
            catch (Exception)
            {
                MessageBox.Show("Error reading Array Solutions Power Master calibration file.  Using defaults.");
            }

            double vfoa = console.VFOAFreq;
            double vfob = console.VFOBFreq;

            p.SetPercent(0.0f);

            int counter = 0;
            int num_bands = 0;
            for (int i = 0; i < band_freqs.Length; i++)
            {
                bool do_band = false;
                switch (bands[i])
                {
                    case Band.B160M: do_band = ck160.Checked; break;
                    case Band.B80M: do_band = ck80.Checked; break;
                    case Band.B60M: do_band = ck60.Checked; break;
                    case Band.B40M: do_band = ck40.Checked; break;
                    case Band.B30M: do_band = ck30.Checked; break;
                    case Band.B20M: do_band = ck20.Checked; break;
                    case Band.B17M: do_band = ck17.Checked; break;
                    case Band.B15M: do_band = ck15.Checked; break;
                    case Band.B12M: do_band = ck12.Checked; break;
                    case Band.B10M: do_band = ck10.Checked; break;
                    case Band.B6M: do_band = ck6.Checked; break;
                }
                if (do_band) num_bands++;
            }

            int total_counts = num_bands * 28;

            for (int i = 0; i < band_freqs.Length; i++) // main loop
            {
                bool do_band = false;
                switch (bands[i])
                {
                    case Band.B160M: do_band = ck160.Checked; break;
                    case Band.B80M: do_band = ck80.Checked; break;
                    case Band.B60M: do_band = ck60.Checked; break;
                    case Band.B40M: do_band = ck40.Checked; break;
                    case Band.B30M: do_band = ck30.Checked; break;
                    case Band.B20M: do_band = ck20.Checked; break;
                    case Band.B17M: do_band = ck17.Checked; break;
                    case Band.B15M: do_band = ck15.Checked; break;
                    case Band.B12M: do_band = ck12.Checked; break;
                    case Band.B10M: do_band = ck10.Checked; break;
                    case Band.B6M: do_band = ck6.Checked; break;
                }

                if (do_band)
                {
                    float saved_value = console.power_table[(int)bands[i]][0];
                    console.power_table[(int)bands[i]][0] = 0.0f;

                    console.VFOAFreq = band_freqs[i];
                    console.VFOBFreq = band_freqs[i];

                    DSPMode dsp_mode = console.RX1DSPMode;
                    console.RX1DSPMode = DSPMode.USB;

                    console.VFOAFreq = band_freqs[i];
                    console.VFOBFreq = band_freqs[i];

                    HIDAnt tx_ant = console.TXAnt1500;
                    console.TXAnt1500 = HIDAnt.PA;

                    int tx_filter_high = console.TXFilterHigh;
                    console.TXFilterHigh = 700;

                    int tx_filter_low = console.TXFilterLow;
                    console.TXFilterLow = 500;

                    bool cpdr = console.CPDR;
                    console.CPDR = false;

                    double freq1 = Audio.SineFreq1;
                    Audio.SineFreq1 = 600.0;

                    Audio.RadioVolume = 0.00;

                    for (int j = 0; j < 10; j++)
                    {
                        if (!p.Visible) goto end;
                        Thread.Sleep(50);
                    }

                    Audio.RadioVolume = 0.16; // need to check on this init value
                    double last_watts = 0.0;

                    int try_again_count = 0;
                    int zero_count = 0;
                    float tol = 0.1f;

                    console.MOX = true;
                    Audio.TXInputSignal = Audio.SignalSource.SINE;
                    Audio.SourceScale = 1.0;

                    float pow = 0.0f;

                    while (Math.Abs(target - pow) > tol)
                    {
                        for (int j = 0; j < 7; j++)
                        {
                            if (!p.Visible) goto end;
                            Thread.Sleep(50);
                        }

                        pow = pm.Watts * pm_trim[i];
                        Debug.WriteLine("pow: " + pow.ToString("f1"));

                        if (pow == 0.0f)
                        {
                            zero_count++;
                            if (zero_count > 2)
                            {
                                console.MOX = false;
                                //Thread.Sleep(50);
                                btnTX1500PA.BackColor = Color.Red;
                                if (!test_pa_power.StartsWith("PA Power Cal: Failed ("))
                                    test_pa_power = "PA Power Cal: Failed(";
                                test_pa_power += BandToString(bands[i]) + ",";
                                lstDebug.Items.Insert(0, "PA - " + BandToString(bands[i]) + ": Failed (" +
                                    Audio.RadioVolume.ToString("f3") + ", " + pow.ToString("f1") + ")");
                                MessageBox.Show("No power read.  If the radio is connected to the PowerMaster \n" +
                                    "coupler correctly, this may indicate a failed PA on this band (" + bands[i].ToString() + ").",
                                    "No Power Read",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
                                console.power_table[(int)bands[i]][0] = 0.0f;
                                break;
                            }
                            pow = 0.01f;
                        }

                        if (Math.Abs(target - pow) > tol) // not within tolerance yet
                        {
                            if ((pow < 5.0f && Audio.RadioVolume == 1.0) || try_again_count++ == 20) // this is as far as we need to go
                            {
                                float limit = 4.9f;
                                switch (bands[i])
                                {
                                    case Band.B40M:
                                        limit = 4.6f;
                                        break;
                                    default:
                                        limit = 4.9f;
                                        break;
                                }

                                if (pow >= limit) // we'll call this a pass
                                {
                                    lstDebug.Items.Insert(0, "PA - " + BandToString(bands[i]) + ": Passed (" +
                                        Audio.RadioVolume.ToString("f3") + ", " + pow.ToString("f1") + ")");
                                    console.power_table[(int)bands[i]][0] = 1.0f;
                                    break;
                                }
                                else // failure 
                                {
                                    btnTX1500PA.BackColor = Color.Red;
                                    if (!test_pa_power.StartsWith("PA Power Cal: Failed ("))
                                        test_pa_power = "PA Power Cal: Failed(";
                                    test_pa_power += BandToString(bands[i]) + ",";
                                    lstDebug.Items.Insert(0, "PA - " + BandToString(bands[i]) + ": Failed (" +
                                        Audio.RadioVolume.ToString("f3") + ", " + pow.ToString("f1") + ")");
                                    console.power_table[(int)bands[i]][0] = 1.0f;
                                    break;
                                }
                            }
                            else // keep going
                            {
                                lstDebug.Items.Insert(0, "PA - " + BandToString(bands[i]) + ": In Progress (" +
                                Audio.RadioVolume.ToString("f3") + ", " + pow.ToString("f1") + ")");

                                double new_val = Audio.RadioVolume * Math.Sqrt(target / pow);
                                if (new_val > Audio.RadioVolume * 2) new_val = Audio.RadioVolume * 2;
                                if (new_val < Audio.RadioVolume / 2) new_val = Audio.RadioVolume / 2;
                                if (new_val > 1.0) new_val = 1.0;
                                Audio.RadioVolume = new_val;
                            }

                            last_watts = pow;
                        }
                        else // passed
                        {
                            lstDebug.Items.Insert(0, "PA - " + BandToString(bands[i]) + ": Passed (" +
                                Audio.RadioVolume.ToString("f3") + ", " + pow.ToString("f1") + ")");
                        }

                        p.SetPercent(++counter / (float)total_counts);

                        console.power_table[(int)bands[i]][0] = (float)Math.Round(Audio.RadioVolume, 4);
                    }

                end:
                    if (!p.Visible)
                        console.power_table[(int)bands[i]][0] = saved_value;

                    console.MOX = false;
                    console.RX1DSPMode = dsp_mode;
                    Audio.SineFreq1 = freq1;
                    console.CPDR = cpdr;
                    console.TXFilterLow = tx_filter_low;
                    console.TXFilterHigh = tx_filter_high;
                    console.TXAnt1500 = tx_ant;

                    if (!p.Visible) break;
                }
            }

        //end2:
            p.Hide();
            console.MOX = false;
            Audio.TXInputSignal = Audio.SignalSource.RADIO;
            console.VFOAFreq = 0.590;
            console.VFOAFreq = vfoa;
            console.VFOBFreq = vfob;

            Thread.Sleep(100);
            console.DisablePTT = disable_ptt;

            try
            {
                pm.Close();
            }
            catch (Exception) { }

            console.dsp.GetDSPTX(0).TXLevelerOn = leveler;

            test_pa_power = "PA Power Test: Passed";

            /*bool pwr_pass = true;
            if (!test_pa_power.StartsWith("PA Power Cal: Failed ("))
                pwr_pass = false;*/

            if (test_pa_power.StartsWith("PA Power Test: Failed ("))
                test_pa_power = test_pa_power.Substring(0, test_pa_power.Length - 2) + ")";
            toolTip1.SetToolTip(btnTX1500PA, test_pa_power);

            string path = console.AppDataPath + "\\Tests";
            if (!Directory.Exists(path)) Directory.CreateDirectory(path);
            bool file_exists = File.Exists(path + "\\pa_power.csv");
            StreamWriter writer = new StreamWriter(path + "\\pa_power.csv", true);
            if (!file_exists) writer.WriteLine("Model, PA Serial Num, Date/Time, Version, "
                                  + "6m, 160m, 80m, 60m, 40m, 30m, 20m, 17m, 15m, 12m, 10m,");
            writer.Write(console.CurrentModel.ToString() + ",");
            writer.Write(HIDEEPROM.SerialToString(HIDEEPROM.SerialNumber) + ","
                + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ","
                + console.Text + ",");

            for (int i = 0; i < bands.Length; i++)
            {
                writer.Write(console.power_table[(int)bands[i]][0].ToString("f4") + ",");
            }
            writer.WriteLine("");
            writer.Close();

            path += "\\PA Power";
            if (!Directory.Exists(path)) Directory.CreateDirectory(path);
            writer = new StreamWriter(path + "\\pa_power_" + HIDEEPROM.SerialToString(HIDEEPROM.SerialNumber) + ".csv");
            writer.WriteLine("Model, Date/Time, Version, 6m, 160m, 80m, 60m, 40m, 30m, 20m, 17m, 15m, 12m, 10m,");
            writer.Write(console.CurrentModel.ToString() + ",");
            writer.Write(DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ",");
            writer.Write(console.Text + ",");

            for (int i = 0; i < bands.Length; i++)
            {
                writer.Write(console.power_table[(int)bands[i]][0].ToString("f4") + ",");
                writer.WriteLine("");
            }
            writer.Close();

            if (p.Text != "")
            {
                lstDebug.Items.Insert(0, "Saving Power data to EEPROM...");
                byte checksum;
                HIDEEPROM.WritePAPower(console.power_table, out checksum);
                console.pa_power_checksum = checksum;
                console.SyncCalDateTime();
                lstDebug.Items[0] = "Saving Power data to EEPROM...done";
            }

            writer.Close();

            //progress.Hide();	
            grpGeneral.Enabled = true;
            grpReceiver.Enabled = true;
            grpTransmitter.Enabled = true;
            grpIO.Enabled = true;
        }