This is the latest working repository used in our demo video for the Maxim to display temperature readings on Bluetooth

Dependencies:   USBDevice

Revision:
3:36de8b9e4b1a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hspguisourcev301/HspGuiSourceV301/HSPGui/ECGChannel.cs	Sat Apr 10 03:05:42 2021 +0000
@@ -0,0 +1,607 @@
+/*******************************************************************************
+* Copyright (C) 2016 Maxim Integrated Products, Inc., All rights Reserved.
+* 
+* This software is protected by copyright laws of the United States and
+* of foreign countries. This material may also be protected by patent laws
+* and technology transfer regulations of the United States and of foreign
+* countries. This software is furnished under a license agreement and/or a
+* nondisclosure agreement and may only be used or reproduced in accordance
+* with the terms of those agreements. Dissemination of this information to
+* any party or parties not specified in the license agreement and/or
+* nondisclosure agreement is expressly prohibited.
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************
+*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+namespace HealthSensorPlatform
+{
+     // Code for ECG Configuration Tab
+    public partial class HspForm 
+    {
+        List<RegisterField> ecgChannelField = new List<RegisterField>(); 
+        List<RegisterField> ecgGlobalField = new List<RegisterField>();
+        List<RegisterField> rToRField = new List<RegisterField>();
+
+        List<RegisterField> channelEnableField = new List<RegisterField>();
+
+        // Needed for dynamic changing of options
+        RegisterField ecgSampleRateField; 
+        RegisterField ecgDlpfField;
+
+        string[][] ecgSampleRateOptions = new string[][] 
+            { 
+                new string[] { "512 sps", "256 sps", "128 sps*" }, 
+                new string[] { "500 sps", "250 sps", "125 sps*" }, 
+                new string[] { "N/A", "N/A", "200 sps*" }, 
+                new string[] { "N/A", "N/A", "199.8 sps*" } 
+            };
+
+        double[][] ecgSampleRates = new double[][]
+            {
+                new double[] {512, 256, 128, 128},
+                new double[] {500, 250, 125, 125},
+                new double[] {200, 200, 200, 200},
+                new double[] {199.8, 199.8, 199.8, 199.8} // using 200, the error is 0.1%
+            };
+
+        string[][][] ecgDlpfOptions;
+
+
+        void initalizeECGConfigFields()
+        {
+			ecgDlpfOptions = new string[4][][];
+			
+			for	(int i = 0; i < 4; i++)
+			{
+				ecgDlpfOptions[i] = new string[4][];
+			}
+			
+			// 32768 Hz
+			ecgDlpfOptions[0][0] = new string[] {"Bypass (00)", "40.96 Hz (01)*", "102.4 Hz (10)", "153.6 Hz (11)"};
+			ecgDlpfOptions[0][1] = new string[] {"Bypass (00)", "40.96 Hz (01)*", "102.4 Hz (10)"};//, "40.96 Hz (11)"};
+			ecgDlpfOptions[0][2] = new string[] {"Bypass (00)", "40.96 Hz (01)*"}; //, "40.96 Hz (10)", "40.96 Hz (11)"};
+			ecgDlpfOptions[0][3] = new string[] {"Bypass (00)", "40.96 Hz (01)*"}; //, "40.96 Hz (10)", "40.96 Hz (11)"};
+			// 32000 Hz
+            ecgDlpfOptions[1][0] = new string[] { "Bypass (00)", "40.00 Hz (01)*", "100.0 Hz (10)", "150.0 Hz (11)"};
+			ecgDlpfOptions[1][1] = new string[] {"Bypass (00)", "40.00 Hz (01)*", "100.0 Hz (10)"}; //, "40.00 Hz (11)"};
+			ecgDlpfOptions[1][2] = new string[] {"Bypass (00)", "40.00 Hz (01)*"}; //, "40.00 Hz (10)", "40.00 Hz (11)"};
+			ecgDlpfOptions[1][3] = new string[] {"Bypass (00)", "40.00 Hz (01)*"}; //, "40.00 Hz (10)", "40.00 Hz (11)"};
+			//32000 Hz
+            ecgDlpfOptions[2][0] = new string[] { "Bypass", "40.00 Hz"}; //, "40.00 Hz", "40.00 Hz" };
+            ecgDlpfOptions[2][1] = new string[] { "Bypass", "40.00 Hz"}; //, "40.00 Hz", "40.00 Hz" };
+            ecgDlpfOptions[2][2] = new string[] { "Bypass", "40.00 Hz"}; //, "40.00 Hz", "40.00 Hz" };
+            ecgDlpfOptions[2][3] = new string[] { "Bypass", "40.00 Hz"}; //, "40.00 Hz", "40.00 Hz" };
+			// 31968 Hz
+            ecgDlpfOptions[3][0] = new string[] { "Bypass (00)", "39.96 Hz (01)" }; //, "39.96 Hz (10)", "39.96 Hz (11)" };
+            ecgDlpfOptions[3][1] = new string[] { "Bypass", "39.96 Hz"}; //, "39.96 Hz", "39.96 Hz" };
+            ecgDlpfOptions[3][2] = new string[] { "Bypass", "39.96 Hz"};//, "39.96 Hz", "39.96 Hz" };
+            ecgDlpfOptions[3][3] = new string[] { "Bypass", "39.96 Hz"};//, "39.96 Hz", "39.96 Hz" };
+			
+            string[] fastOptions = { "Normal*", "Manual Fast Recovery", "Automatic Fast Recovery" };
+            string[] fastThOptions = new string[64];
+            for (int i = 0; i < 64; i++)
+            {
+                fastThOptions[i] = i.ToString() + " * 2048 LSB";
+            }
+            fastThOptions[0x3F] += "*"; // Default option
+
+            string[] channelGainOptions = { "20 V/V*", "40 V/V", "80 V/V", "160 V/V" };
+
+            //string[] sampleRateOptions = { "512 sps", "256 sps", "128 sps*"}; // Assume FMSTR = 32768 Hz
+
+            string[] dlpfOptions = { "Bypass", "40.96 Hz*", "102.4 Hz", "153.6 Hz" };
+            string[] dhpfOptions = { "Bypass", "0.50 Hz*" };
+
+            RegisterField fastField = new RegisterField { Name = "FAST", Register = 5, Index = 22, Width = 2, Descriptions = fastOptions, Label = lblFast, Control = cboFast, Device = max30001};
+            RegisterField fastThField = new RegisterField { Name = "FAST_TH", Register = 5, Index = 16, Width = 6, Descriptions = fastThOptions, Label = lblFastTh, Control = cboFastTh, Device = max30001};
+            ecgChannelField.Add(fastField);
+            ecgChannelField.Add(fastThField);
+
+            RegisterField channelGainField = new RegisterField { Name = "ECG_GAIN", Register = 0x15, Index = 16, Width = 2, Descriptions = channelGainOptions, Label = lblChannelGain, Control = cboChannelGain, Device = max30001};
+            ecgChannelField.Add(channelGainField);
+
+            ecgSampleRateField = new RegisterField { Name = "ECG_RATE", Register = 0x15, Index = 22, Width = 2, Descriptions = ecgSampleRateOptions[0], Label = lblSampleRate, Control = cboSampleRate, Device = max30001};
+            ecgChannelField.Add(ecgSampleRateField);
+
+            ecgDlpfField = new RegisterField { Name = "ECG_DLPF", Register = 0x15, Index = 12, Width = 2, Descriptions = dlpfOptions, Label = lblDlpf,  Control = cboDlpf, Device = max30001};
+            RegisterField dhpfField = new RegisterField { Name = "ECG_DHPF", Register = 0x15, Index = 14, Width = 1, Descriptions = dhpfOptions, Label = lblDhpf, Control = cboDhpf, Device = max30001};
+            ecgChannelField.Add(ecgDlpfField);
+            ecgChannelField.Add(dhpfField);
+        }
+
+        void initalizeECGGlobalControls()
+        {
+            string[] fmstrDescription = { "32768 Hz (00)*", "32000 Hz (01)", "32000 Hz (10)", "31968 Hz (11)" };
+            string[] enECGDescription = { "Disabled*", "Enabled" };
+
+            RegisterField fmstrField = new RegisterField { Name = "FMSTR", Register = 0x10, Index = 20, Width = 2, Descriptions = fmstrDescription, Control = cboMasterClock, Device = max30001};
+            ecgGlobalField.Add(fmstrField);
+
+            //RegisterField enECGField = new RegisterField { Name = "EN_ECG", Register = 0x10, Index = 19, Width = 1, Descriptions = enECGDescription, Label = lblECGChannelEnable };
+            //enECGField.Control = cboECGChannelEnable;
+            //ecgGlobalField.Add(enECGField);
+            RegisterField enECGField = new RegisterField { Name = "EN_ECG", Register = 0x10, Index = 19, Width = 1, Control = chkEnECG, Device = max30001};
+            RegisterField enBioZField = new RegisterField { Name = "EN_BIOZ", Register = 0x10, Index = 18, Width = 1, Control = chkEnBioZ, Device = max30001};
+            RegisterField enPaceField = new RegisterField { Name = "EN_PACE", Register = 0x10, Index = 17, Width = 1, Control = chkEnPace, Device = max30001};
+            RegisterField enRtorField = new RegisterField { Name = "EN_RTOR", Register = 0x1d, Index = 15, Width = 1, Control = chkEnRtor, Device = max30001};
+            channelEnableField.Add(enECGField);
+            channelEnableField.Add(enBioZField);
+            channelEnableField.Add(enPaceField);
+            channelEnableField.Add(enRtorField);
+        }
+
+        void initalizeRToRFields()
+        {
+            string[] wndwOptions = {"6 * 8ms", "8 * 8ms", "10 * 8ms", "12 * 8ms*", "14 * 8ms", "16 * 8ms", "18 * 8ms", "20 * 8ms", 
+                                   "22 * 8ms", "24 * 8ms", "26 * 8ms", "28 * 8ms"};
+            string[] gainOptions = { "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "Auto-Scale*" };
+            string[] enableOptions = { "Disable*", "Enable" };
+            string[] pavgOptions = { "2", "4", "8*", "16" };
+            string[] ptsfOptions = { "1/16", "2/16", "3/16", "4/16*", "5/16", "6/16", "7/16", "8/16",
+                                   "9/16", "10/16", "11/16", "12/16", "13/16", "14/16", "15/16", "16/16"};
+            string[] hoffOptions = new string[64];
+            for(int i = 0; i < 64; i ++)
+            {
+                hoffOptions[i] = i.ToString();
+                if (i == 32)
+                    hoffOptions[i] += "*";
+            }
+            string[] ravgOptions = { "2", "4", "8*", "16" };
+            string[] rhsfOptions = { "0/8", "1/8", "2/8", "3/8", "4/8*", "5/8", "6/8", "7/8" };
+
+            RegisterField wndwField = new RegisterField { Name = "RTOR_WNDW", Register = 0x1d, Index = 20, Width = 4, Descriptions = wndwOptions, Control = cboRRWndw, Label = lblRRWndw, Device = max30001 };
+            RegisterField gainField = new RegisterField { Name = "RTOR_GAIN", Register = 0x1d, Index = 16, Width = 4, Descriptions = gainOptions, Control = cboRRGain, Label = lblRRGain, Device = max30001 };
+            RegisterField enableField = new RegisterField { Name = "EN_RTOR", Register = 0x1d, Index = 15, Width = 1, Descriptions = enableOptions, Control = cboEnRToR, Label = lblEnRToR, Device = max30001 };
+            RegisterField pavgField = new RegisterField { Name = "RTOR_PAVG", Register = 0x1d, Index = 12, Width = 2, Descriptions = pavgOptions, Control = cboRRPavg, Label = lblRRPavg, Device = max30001 };
+            RegisterField ptsfField = new RegisterField { Name = "RTOR_PTSF", Register = 0x1d, Index = 8, Width = 4, Descriptions = ptsfOptions, Control = cboRRPtsf, Label = lblRRPtsf, Device = max30001};
+            RegisterField hoffField = new RegisterField { Name = "RTOR_HOFF", Register = 0x1e, Index = 16, Width = 6, Descriptions = hoffOptions, Control = cboRRHoff, Label = lblRRHoff, Device = max30001 };
+            RegisterField ravgField = new RegisterField { Name = "RTOR_RAVG", Register = 0x1e, Index = 12, Width = 2, Descriptions = ravgOptions, Control = cboRRRavg, Label = lblRRRavg, Device = max30001 };
+            RegisterField rhsfField = new RegisterField { Name = "RTOR_RHSF", Register = 0x1e, Index = 8, Width = 3, Descriptions = rhsfOptions, Control = cboRRRhsf, Label = lblRRRhsf, Device = max30001 };
+
+            rToRField.Add(wndwField);
+            rToRField.Add(gainField);
+            rToRField.Add(enableField);
+            rToRField.Add(pavgField);
+            rToRField.Add(ptsfField);
+            rToRField.Add(hoffField);
+            rToRField.Add(ravgField);
+            rToRField.Add(rhsfField);
+        }
+
+        /// <summary>
+        /// Read register values and update GUI accordingly
+        /// </summary>
+        void ECGChannelUpdateRegisters()
+        {
+            internalUpdate = true;
+            ReadComboBoxesRegisters(ecgChannelField);
+            ReadComboBoxesRegisters(rToRField);
+            internalUpdate = false;
+        }
+
+        /// <summary>
+        /// Read and update all the MAX30001 global GUI settings (enable bits and clock)
+        /// </summary>
+        void ECGGlobalUpdateRegisters()
+        {
+            internalUpdate = true;
+            ReadComboBoxesRegisters(ecgGlobalField);
+            ReadCheckBoxRegisters(channelEnableField);
+            channelEnableMask(chkEnECG);
+            internalUpdate = false;
+            
+            // Update EcgView to maintain consistent state
+            ecgView1.EnableBioZ = chkEnBioZ.Checked;
+            ecgView1.EnableECG = chkEnECG.Checked;
+            ecgView1.EnablePace = chkEnPace.Checked;
+            ecgView1.EnableRToR = chkEnRtor.Checked;
+        }
+
+        /// <summary>
+        /// Mask enable bits for features which depend on EN_ECG = 1 and EN_BIOZ = 1
+        /// </summary>
+        /// <param name="enEcg">Checkbox representing EN_ECG bit</param>
+        void channelEnableMask(MaximStyle.MaximCheckBox enEcg)
+        {
+            if (enEcg.Checked == false)
+            {
+                chkEnRtor.Enabled = false;
+                chkEnPace.Enabled = false;
+            }
+            else
+            {
+                chkEnRtor.Enabled = true;
+                if (max30001Model.PartID == Model.MAX30001Model.Part.MAX30001)
+                    chkEnPace.Enabled = true;
+            }
+
+            /*if (chkEnBioZ.Checked == false)
+            { 
+                chkEnPace.Enabled = false;
+            }
+            else
+            {
+                chkEnPace.Enabled = true;
+            }*/
+
+        }
+
+        void ReadComboBoxesRegisters(List<RegisterField> fields)
+        {
+            int bitValue;
+            MaximStyle.MaximComboBox cbox;
+
+            foreach (RegisterField rf in fields)
+            {
+                cbox = (MaximStyle.MaximComboBox)rf.Control;
+
+                if (rf.AutoUpdate == true)
+                {
+                    //for (int i = 0; i < 3; i++)
+                    //{
+                    //    try
+                    //    {
+                           bitValue = rf.ReadField();
+
+
+                           if (bitValue < cbox.Items.Count && cbox.Items.Count != 0) // Bit setting matches combobox setting
+                           {
+                               cbox.SelectedItem = rf.Descriptions[bitValue];
+                           }
+                           else // Bit setting value outside of combobox item range
+                           {
+                               cbox.Text = "0b" + Convert.ToString(bitValue, 2);
+                           }
+
+                    //    }
+                    //    catch (System.TimeoutException)
+                    //    {
+                    //        if (i == 2)
+                    //            throw;
+                    //    }
+                    //}
+
+                }
+            }
+
+        }
+
+        void ReadComboBoxesRegister(RegisterField rf)
+        {
+            int bitValue;
+            MaximStyle.MaximComboBox cbox;
+
+            cbox = (MaximStyle.MaximComboBox)rf.Control;
+
+            if (rf.AutoUpdate == true)
+            {
+                bitValue = rf.ReadField();
+
+                if (bitValue < cbox.Items.Count && cbox.Items.Count != 0) // Bit setting matches combobox setting
+                {
+                    cbox.SelectedItem = rf.Descriptions[bitValue];
+                }
+                else // Bit setting value outside of combobox item range
+                {
+                    cbox.Text = "0b" + Convert.ToString(bitValue, 2);
+                }
+            }
+        }
+
+        void ReadCheckBoxRegisters(List<RegisterField> fields)
+        {
+            int bitValue;
+            MaximStyle.MaximCheckBox chk;
+
+            foreach (RegisterField rf in fields)
+            {
+                chk = (MaximStyle.MaximCheckBox)rf.Control;
+
+                if (rf.AutoUpdate == true)
+                {
+                    bitValue = rf.ReadField();
+
+                    if (bitValue == 0)
+                        chk.Checked = false;
+                    else
+                        chk.Checked = true;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Get bit value from register 
+        /// </summary>
+        /// <param name="field"></param>
+        /// <returns></returns>
+        /*int BitValue(RegisterField field)
+        {
+            int registerData;
+
+            registerData = max30001.ReadReg((byte)field.Register);
+
+            return (registerData >> field.Index) & ((1 << field.Width) - 1);
+        }*/
+
+        /// <summary>
+        /// Add tool tips to combo boxes and event to write registers
+        /// </summary>
+        /// <param name="list"></param>
+        void initalizeToolTipEvents(List<RegisterField> list)
+        {
+            MaximStyle.MaximComboBox cbox;
+            Label lbl;
+            StringBuilder strBuilder = new StringBuilder();
+
+            foreach (RegisterField field in list)
+            {
+                cbox = (MaximStyle.MaximComboBox)field.Control;
+                lbl = field.Label;
+
+                // Tool Tip String
+                strBuilder.Append("Bit ");
+                strBuilder.Append(field.Name.Replace("\n", String.Empty));
+                strBuilder.Append(" in Register 0x");
+                strBuilder.Append(field.Register.ToString("X2"));
+                toolTip1.SetToolTip(cbox, strBuilder.ToString());
+                if (lbl != null)
+                    toolTip1.SetToolTip(lbl, strBuilder.ToString());
+                strBuilder.Clear();
+
+                // Event to Write Registers
+                if (cbox != cboMasterClock && cbox != cboSampleRate && cbox != cboBioZSampleRate) // cboMasterClock has a special handler to support repopulation of comboboxes
+                    cbox.SelectedIndexChanged += new System.EventHandler(cboECGChannel_SelectedIndexChanged);
+            }
+        }
+
+        /// <summary>
+        /// Write corresponding register of cbox 
+        /// </summary>
+        /// <param name="cbox"></param>
+        void writeComboBox(MaximStyle.MaximComboBox cbox)
+        {
+            List<RegisterField>[] fieldLists = { ecgChannelField, ecgInputMuxField, ecgGlobalField, rToRField, bioZChannelField, bioZInputMuxField, bioZLoadField, paceChannelField};
+            RegisterField field = null;
+            //int val;
+
+            foreach (List<RegisterField> list in fieldLists)
+            {
+                foreach (RegisterField f in list)
+                {
+                    if (f.Control == cbox)
+                    {
+                        field = f;
+                        break;
+                    }
+                }
+
+                if (field != null)
+                    break;
+            }
+
+            field.WriteField((((MaximStyle.MaximComboBox)field.Control).SelectedIndex));
+        }
+
+        void writeCheckBox(MaximStyle.MaximCheckBox chk)
+        {
+            List<RegisterField>[] fieldLists = { channelEnableField };
+            RegisterField field = null;
+            //int val;
+
+            foreach (List<RegisterField> list in fieldLists)
+            {
+                foreach (RegisterField f in list)
+                {
+                    if (f.Control == chk)
+                    {
+                        field = f;
+                        break;
+                    }
+                }
+
+                if (field != null)
+                    break;
+            }
+
+            field.WriteField(((MaximStyle.MaximCheckBox)field.Control).Checked == true ? 1 : 0);
+        }
+
+        /// <summary>
+        /// Event to handle when a new item is selected in the comboboxes for ECG Channel tabs
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void cboECGChannel_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            MaximStyle.MaximComboBox cbox = (MaximStyle.MaximComboBox)sender;
+
+            if (connected && !internalUpdate)
+                writeComboBox(cbox);
+        }
+
+        /// <summary>
+        /// Update sample rate for ECG View
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void cboSampleRate_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            MaximStyle.MaximComboBox cbox = (MaximStyle.MaximComboBox)sender;
+
+            if (connected && !internalUpdate)
+                writeComboBox(cbox);
+
+            if (cboMasterClock.SelectedIndex > -1)
+            {
+                // Set sample rate based on clock
+                ecgView1.SampleRateEcg = ecgSampleRates[cboMasterClock.SelectedIndex][cbox.SelectedIndex];
+
+                // Set digital low pass filter
+                cboDlpf.Items.Clear();
+                ecgDlpfField.Descriptions = ecgDlpfOptions[cboMasterClock.SelectedIndex][cboSampleRate.SelectedIndex];
+                ecgDlpfField.Control = cboDlpf; // Trigger updating of descriptions
+
+                //internalUpdate = true;
+                if (connected)
+                    cboDlpf.SelectedIndex = ecgDlpfField.ReadField();
+                //internalUpdate = false;
+                //ReadComboBoxesRegisters(cboDlpf);
+            }
+
+        }
+
+        private void cboChannelGain_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            MaximStyle.MaximComboBox cbox = (MaximStyle.MaximComboBox)sender;
+
+            switch (cbox.SelectedIndex)
+            {
+                case 0:
+                    ecgView1.GainECG = 20;
+                    break;
+                case 1:
+                    ecgView1.GainECG = 40;
+                    break;
+                case 2:
+                    ecgView1.GainECG = 80;
+                    break;
+                case 3:
+                    ecgView1.GainECG = 160;
+                    break;
+            }
+        }
+
+        private void chkChannelEnable_CheckedChanged(object sender, EventArgs e)
+        {
+            MaximStyle.MaximCheckBox chk = (MaximStyle.MaximCheckBox)sender;
+
+            // Write bit
+            if (connected && !internalUpdate)
+            {
+                writeCheckBox(chk);
+
+                // Do not allow user to change masked enable bits
+                channelEnableMask(chkEnECG);
+
+                // Tell ECG View the status
+                if (chk == chkEnECG)
+                {
+                    ecgView1.EnableECG = chk.Checked;
+                }
+                else if (chk == chkEnBioZ)
+                {
+                    ecgView1.EnableBioZ = chk.Checked;
+                }
+                else if (chk == chkEnPace)
+                {
+                    ecgView1.EnablePace = chk.Checked;
+                }
+                else if (chk == chkEnRtor)
+                {
+                    ecgView1.EnableRToR = chk.Checked;
+                }
+
+                // Read all enable bits
+                internalUpdate = true;
+                ReadCheckBoxRegisters(channelEnableField);
+                internalUpdate = false;
+            }
+        }
+
+        private void cboMasterClock_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            MaximStyle.MaximComboBox cbo = (MaximStyle.MaximComboBox)sender;
+            int[] clock = { 32768, 32000, 32000, 31968 };
+
+            if (connected && !internalUpdate)
+                writeComboBox(cbo);
+
+            ecgView1.FrequencyMasterField = cbo.SelectedIndex;
+            //ecgView1.TimeResolution = 1.0/(2*clock[cbo.SelectedIndex]);
+
+            ecgSampleRateField.Descriptions = ecgSampleRateOptions[cbo.SelectedIndex];
+            ecgSampleRateField.Control = cboSampleRate; // Trigger updating of descriptions
+
+            cboBioZSampleRate.Items.Clear();
+            bioZSampleRateField.Descriptions = bioZSampleRateOptions[cbo.SelectedIndex];
+            bioZSampleRateField.Control = cboBioZSampleRate; // Trigger updating of descriptions
+
+            // Trigger update of current selection to new description
+            internalUpdate = true;
+            if (connected)
+            {
+                cboSampleRate.SelectedIndex = ecgSampleRateField.ReadField();
+                cboDlpf.SelectedIndex = ecgDlpfField.ReadField();
+                cboBioZSampleRate.SelectedIndex = bioZSampleRateField.ReadField();
+                cboBioZDigitalLpf.SelectedIndex = bioZDlpfField.ReadField();
+            }
+            internalUpdate = false;
+        }
+
+        private void cboRRWndw_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            MaximStyle.MaximComboBox cbo = (MaximStyle.MaximComboBox)sender;
+            ecgView1.RToRWindowField = cbo.SelectedIndex;
+        }
+
+        private CustomControls.InitArgs.RToRInitStart getRToRArgs()
+        {
+            CustomControls.InitArgs.RToRInitStart initArgs = new CustomControls.InitArgs.RToRInitStart();
+
+            initArgs.Wndw = cboRRWndw.SelectedIndex;
+            initArgs.Gain = cboRRGain.SelectedIndex;
+            initArgs.En_rtor = chkEnRtor.Checked == true ? 1 : 0; 
+            initArgs.Pavg = cboRRPavg.SelectedIndex;
+            initArgs.Ptsf = cboRRPtsf.SelectedIndex;
+            initArgs.Hoff = cboRRHoff.SelectedIndex;
+            initArgs.Ravg = cboRRRavg.SelectedIndex;
+            initArgs.Rhsf = cboRRRhsf.SelectedIndex;
+            initArgs.Clr_rrint = 1; // Default from Jerry's GUI
+
+            return initArgs;
+        }
+
+        private void setRToRArgs(CustomControls.InitArgs.RToRInitStart initArgs)
+        {
+            cboRRWndw.SelectedIndex = initArgs.Wndw;
+            cboRRGain.SelectedIndex = initArgs.Gain;
+            //initArgs.En_rtor = chkEnRtor.Checked == true ? 1 : 0; //cboEnRToR.SelectedIndex;
+            cboRRPavg.SelectedIndex = initArgs.Pavg;
+            cboRRPtsf.SelectedIndex = initArgs.Ptsf;
+            cboRRHoff.SelectedIndex = initArgs.Hoff;
+            cboRRRavg.SelectedIndex = initArgs.Ravg;
+            cboRRRhsf.SelectedIndex = initArgs.Rhsf;
+            //initArgs.Clr_rrint = 2; // Default from Jerry's GUI
+        }
+        
+    }
+}