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 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;
        }