repo time

Dependencies:   mbed MAX14720 MAX30205 USBDevice

Revision:
20:6d2af70c92ab
diff -r 002c398f14cc -r 6d2af70c92ab HspGuiSourceV301/HSPGui/CustomControls/RegisterView.cs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HspGuiSourceV301/HSPGui/CustomControls/RegisterView.cs	Tue Apr 06 06:41:40 2021 +0000
@@ -0,0 +1,765 @@
+/*******************************************************************************
+* 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.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+using System.IO;
+
+using HealthSensorPlatform.DeviceDescriptions;
+using HealthSensorPlatform.CustomControls;
+using RPCSupport.DeviceSupport;
+//using Maxim.MAX30101GUI.DeviceDescriptions;
+//using Maxim.MAX30101;
+
+namespace Maxim.CustomControls
+{
+    public partial class RegisterView : UserControl, IDeviceView
+    {
+        private bool connected = false;
+        public bool Connected
+        {
+            get
+            {
+                return connected;
+            }
+            set 
+            {
+                connected = value;
+            }
+        }
+
+        public string DeviceName;
+
+        public DeviceController Controller
+        {
+            get { return controller; }
+        }
+        private DeviceController controller;
+
+
+        /// <summary>
+        /// Value of current selected register 
+        /// </summary>
+        int RegisterValue;
+
+        Label[] bitLabels = new Label[24];
+        
+        Font RegularFont;
+        Font BoldFont;
+
+        public event RegisterWriteCompleteHandler RegisterWriteComplete;
+        public delegate void RegisterWriteCompleteHandler(object sender, RegisterArgs e);
+
+        public event CellBeginEditHandler CellBeginEdit;
+        public delegate void CellBeginEditHandler(object sender, DataGridViewCellCancelEventArgs e);
+
+        public RegisterView()
+        {
+            //accelDevice = new AccelDevice();
+            InitializeComponent();
+
+            // Initialize font styles for label
+            RegularFont = new Font(lblBit00.Font, FontStyle.Regular); 
+            BoldFont = new Font(lblBit00.Font, FontStyle.Bold);
+
+            // References to all bit labels
+            for(int i = 0; i < 24; i++)
+            {
+                string labelName = "lblBit" + i.ToString("D2");
+                bitLabels[i] = (Label)panelRegisterBits.Controls[labelName];
+            }
+
+            dgv_Registers.CellBeginEdit += OnCellBeginEdit; // Pass thru event
+            dgv_Registers.SelectionChanged += dgv_Registers_SelectionChanged;
+            dgv_Registers.CellEndEdit += dgv_Registers_CellEndEdit;
+        }
+
+        public void SetController(DeviceController controller)
+        {
+            Clear();
+            this.controller = controller;
+        }
+
+        /// <summary>
+        /// RegisterInfo register value to string
+        /// </summary>
+        /// <param name="reg"></param>
+        /// <returns></returns>
+        private string FormatData(RegisterInfo reg)
+        {
+            return reg.dataField.ToString("X" + (reg.numBytes * 2).ToString());
+        }
+
+        /// <summary>
+        /// Populate register tables
+        /// </summary>
+        public void DisplayRegisters()
+        {
+            if (dgv_Registers.RowCount == 0)
+            {
+                //add rows to table
+                foreach (RegisterInfo reg in controller.InfoArray)
+                {
+                    //get the number of bytes of the register
+                    int numBytes = reg.numBytes;
+
+                    String dataStr = FormatData(reg);
+                    //add a row to the table with the register address, name, and value
+                    dgv_Registers.Rows.Add(reg.address.ToString("X2") + "h", reg.detailedName, dataStr);
+                }
+                
+                //resize length of table to the number of rows
+                if (dgv_Registers.RowCount > 8)
+                {
+                    dgv_Registers.Height = (dgv_Registers.RowCount - 1) * 23 + 42;
+                    dgv_RegDes.Height = dgv_Registers.Height;
+                }
+                else
+                {
+                    dgv_Registers.Height = 7 * 23 + 42;
+                    dgv_RegDes.Height = dgv_Registers.Height;
+                }
+            }
+            else //the table has already been populated with rows
+            {
+                //update the value column with the new value in the ADC registers
+                for (int i = 0; i < dgv_Registers.Rows.Count; i++)
+                {
+                    RegisterInfo reg = controller.InfoArray[i];
+                    int numBytes = reg.numBytes;
+                    String dataStr = FormatData(reg);
+                    //add a row to the table with the register address, name, and value
+                    dgv_Registers[col_Value.Index, i].Value = dataStr;
+                }
+            }
+        }
+
+        public void Clear()
+        {
+            dgv_Registers.Rows.Clear();
+            dgv_Registers.Refresh();
+        }
+
+        public string RegistersToString()
+        {
+            //RegisterProcess registerProcess;
+            StringBuilder sb = new StringBuilder();
+            string dataStr;
+            string[][] bitDescriptions;
+            int longestRow;
+
+            //registerProcess = new RegisterProcess(controller.InfoArray);
+            
+            bitDescriptions = new string[controller.InfoArray.Length + 4][];
+
+            UpdateRegisterIndexWidth();
+
+            // Generate register data to string
+            for (int i = 0; i < controller.InfoArray.Length; i++)
+            {
+                RegisterInfo reg = controller.InfoArray[i];
+
+                bitDescriptions[i] = new string[reg.description.list.Count];
+
+                for (int k = 0; k < reg.description.list.Count; k++)
+                {
+                    RegisterBitDescriptions.RegisterBitDescription b = reg.description.list[k];
+                    int bitValue = (reg.dataField >> b.Index) & ((1 << b.Width) - 1); // MAX30001 only
+                    bitDescriptions[i][k] = b.name + " = " + bitValue.ToString("X") + "h";
+                }
+            }
+
+            // Find longest row for how deep to loop to print out all registers bits
+            longestRow = controller.InfoArray.Length + 1;
+            for (int j = 0; j < controller.InfoArray.Length; j++ )
+            {
+                if (controller.InfoArray[j].description.list.Count > longestRow)
+                {
+                    longestRow = controller.InfoArray[j].description.list.Count + 1;
+                }
+            }
+
+            for (int i = 0; i < longestRow; i++)
+            {
+                if (i < controller.InfoArray.Length) // register map
+                {
+                    RegisterInfo reg = controller.InfoArray[i];
+
+                    dataStr = FormatData(reg);
+
+                    sb.Append(this.DeviceName);
+                    sb.Append(", ");
+                    sb.Append(reg.address.ToString("X2"));
+                    sb.Append("h, ");
+                    sb.Append(reg.detailedName);
+                    sb.Append(", ");
+                    sb.Append(dataStr);
+                    sb.Append("h");
+                    sb.Append(", ");
+                    sb.Append(", ");
+                }
+                else // finished with register map, just have descriptions
+                {
+                    sb.Append(", ");
+                    sb.Append(", ");
+                    sb.Append(", ");
+                    sb.Append(", ");
+                    sb.Append(", ");
+                }
+
+                if (i == 0) // Register name and values
+                {
+                    for (int k = 0; k < controller.InfoArray.Length; k++)
+                    {
+                        if (controller.InfoArray[k].type != RegisterInfo.RegisterType.WriteOnly)
+                        {
+                            sb.Append(controller.InfoArray[k].name);
+                            sb.Append(" = ");
+                            sb.Append(FormatData(controller.InfoArray[k]));
+                            sb.Append("h");
+                            sb.Append(", ");
+                        }
+                    }
+                }
+                else // descriptions
+                {
+                    for (int k = 0; k < controller.InfoArray.Length; k++)
+                    {
+                        if (controller.InfoArray[k].type != RegisterInfo.RegisterType.WriteOnly)
+                        {
+                            if (i - 1 < bitDescriptions[k].Length)
+                            {
+                                sb.Append(bitDescriptions[k][i - 1]);
+                            }
+                            sb.Append(',');
+                        }
+                    }
+                }
+                sb.Append(Environment.NewLine);
+            }
+
+            /*
+            foreach(RegisterInfo reg in controller.InfoArray)
+            {
+                if (reg.address == 1 || reg.address == 8 || reg.address == 9 || reg.address == 10)
+                    continue;
+
+                sb.Append("% ");
+                sb.Append(reg.name);
+                sb.Append(" (");
+                sb.Append(reg.address.ToString("X2"));
+                sb.Append("h)");
+                sb.Append(" = ");
+                sb.Append(FormatData(reg));
+                sb.Append("h\n");
+
+                foreach(RegisterBitDescriptions.RegisterBitDescription b in reg.description.list)
+                {
+                    int bitValue = (RegisterData(reg) >> b.Index) & ((1 << b.Width) - 1); // MAX30001 only
+                    sb.Append("% ");
+                    sb.Append(b.name);
+                    sb.Append(" = ");
+                    sb.Append(bitValue.ToString("X"));
+                    sb.Append("h\n");
+                }
+            }
+            */
+            return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray());
+        }
+
+        /// <summary>
+        /// Register selection change display register description and update display bits
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void dgv_Registers_SelectionChanged(object sender, EventArgs e)
+        {
+            UpdateRegisters();
+        }
+
+        private void UpdateRegisters()
+        {
+            //get the index of the row selected
+            int row = dgv_Registers.CurrentRow.Index;
+
+            //make sure there is bit description info and then display it
+            if (controller.InfoArray[row].description != null)
+            {
+                lbl_bitDes.Text = "Bit Description: " + controller.InfoArray[row].name + " Register";
+                UpdateRegisterDesTable(controller.InfoArray[row].description);
+                RegisterValue = Int32.Parse((string)(dgv_Registers[2, row].Value), System.Globalization.NumberStyles.HexNumber);
+                UpdateRegisterBits(controller.InfoArray[row].description, RegisterValue);
+            }
+        }
+
+        /// <summary>
+        /// Fill register description table
+        /// </summary>
+        /// <param name="bitsDes"></param>
+        public void UpdateRegisterDesTable(RegisterBitDescriptions bitsDes)
+        {
+            //int numBits = bitsDes.Count;
+
+            dgv_RegDes.Rows.Clear();
+
+            foreach (RegisterBitDescriptions.RegisterBitDescription b in bitsDes.list)
+            {
+                dgv_RegDes.Rows.Add(b.bit, b.name, b.description);
+            }
+
+        }
+
+        public void UpdateRegisterBits()
+        {
+            int row;
+
+            if (dgv_Registers.CurrentRow != null)
+            {
+                row = dgv_Registers.CurrentRow.Index;
+
+                if (controller.InfoArray[row].description != null)
+                {
+                    RegisterValue = Int32.Parse((string)(dgv_Registers[2, row].Value), System.Globalization.NumberStyles.HexNumber);
+                    UpdateRegisterBits(controller.InfoArray[row].description, RegisterValue);
+                }
+            }
+        }
+
+        public void UpdateRegisterIndexWidth()
+        {
+            RegisterInfo[] info = controller.InfoArray;
+
+            foreach(RegisterInfo regInfo in info) // Registers
+            {
+                foreach (RegisterBitDescriptions.RegisterBitDescription b in regInfo.description.list) // Bits
+                {
+                    string[] numbers = Regex.Split(b.bit, @"\D+"); // Bits [20:17]
+                    string registerBitName;
+                    int number1 = -1;
+                    int number2 = -1;
+
+                    // Find Bit Range
+                    foreach (string value in numbers)
+                    {
+                        if (value != String.Empty)
+                        {
+                            if (number1 == -1) // First number found
+                                number1 = Int32.Parse(value);
+                            else // Second number found
+                                number2 = Int32.Parse(value);
+                        }
+                    }
+
+                    if (number2 == -1) // Single Number: single bit field (example: Bit 20)
+                    {
+                        b.Width = 1;
+                        b.Index = number1;
+                    }
+                    else // Multiple Bits: multiple bit field (example: Bit [20:17])
+                    {
+                        registerBitName = Regex.Replace(b.name, @"\[\d+:\d+\]", String.Empty); // Remove [#.#] from bit field name
+
+                        for (int i = number1; i >= number2; i--)
+                        {
+                            bitLabels[i].Text = registerBitName + "[" + (i - number2) + "]"; // Calculate bit field number
+                        }
+
+                        b.Index = number2;
+                        b.Width = number1 - number2 + 1; 
+
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Fill bit table
+        /// </summary>
+        /// <param name="bitDes"></param>
+        /// <param name="regValue"></param>
+        public void UpdateRegisterBits(RegisterBitDescriptions bitDes, int regValue)
+        {
+            // Reset Bit State
+            for (int i = 0; i < 24; i++ )
+            {
+                bitLabels[i].Text = "-";
+
+                // Set label based on bit state
+                if (((regValue >> i) & 0x01) == 0x01)
+                    bitLabels[i].Font = BoldFont;
+                else
+                    bitLabels[i].Font = RegularFont;
+            }
+
+            foreach (RegisterBitDescriptions.RegisterBitDescription b in bitDes.list)
+            {
+                string[] numbers = Regex.Split(b.bit, @"\D+"); // Bits [20:17]
+                string registerBitName;
+                int number1 = -1;
+                int number2 = -1;
+
+                // Find Bit Range
+                foreach (string value in numbers)
+                {
+                    if (value != String.Empty)
+                    {
+                        if (number1 == -1) // First number found
+                            number1 = Int32.Parse(value);
+                        else // Second number found
+                            number2 = Int32.Parse(value);
+                    }
+                }
+
+                if (number2 == -1) // Single Number: single bit field (example: Bit 20)
+                {
+                    bitLabels[number1].Text = b.name;
+                }
+                else // Multiple Bits: multiple bit field (example: Bit [20:17])
+                {
+                    registerBitName = Regex.Replace(b.name, @"\[\d+:\d+\]", String.Empty); // Remove [#.#] from bit field name
+
+                    for (int i = number1; i >= number2; i--)
+                    {
+                        bitLabels[i].Text = registerBitName + "[" + (i - number2) + "]"; // Calculate bit field number
+                    }
+                    
+                }
+            }
+        }
+
+        /// <summary>
+        /// Parse user input and write register
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void dgv_Registers_CellEndEdit(object sender, DataGridViewCellEventArgs e)
+        {
+            //check if hardware is connected
+            //if (online && !COMMConnected())
+            //    return;
+
+            RegisterInfo reg = controller.InfoArray[e.RowIndex];
+            byte address = (byte)reg.address;
+            byte numBytes = (byte)reg.numBytes;
+
+            int[] data = reg.data;
+
+            string value = (string)dgv_Registers[col_Value.Index, e.RowIndex].Value;
+            string error = ValidateHexValue(value, numBytes);
+
+            if (error == "Valid")
+            {
+                //erase error text if one exist
+                if (dgv_Registers[col_Value.Index, e.RowIndex].ErrorText != String.Empty)
+                    dgv_Registers[col_Value.Index, e.RowIndex].ErrorText = String.Empty;
+
+                //convert string hex to number hex
+                int hex = Int32.Parse(value, System.Globalization.NumberStyles.HexNumber);
+
+                //write value back to GUI with correct number of characters
+                dgv_Registers[col_Value.Index, e.RowIndex].Value = hex.ToString("X" + numBytes * 2);
+
+                WriteRegister(reg, hex);
+
+                if (RegisterWriteComplete != null)
+                {
+                    RegisterWriteComplete(this, new RegisterArgs { Register = address });
+                }
+
+            }
+            else//value is not valid
+            {
+                byte zero = 0;
+                dgv_Registers[col_Value.Index, e.RowIndex].Value = zero.ToString("X" + numBytes * 2); //enter zeros with correct number of characters
+                dgv_Registers[col_Value.Index, e.RowIndex].ErrorText = error;    //add error text
+            }
+
+            UpdateRegisters();
+        }
+
+        /// <summary>
+        /// Write data to register
+        /// </summary>
+        /// <param name="reg"></param>
+        /// <param name="hex"></param>
+        public void WriteRegister(RegisterInfo reg, int hex)
+        {
+            byte numBytes = (byte)reg.numBytes;
+            int[] data = reg.data;
+
+            switch (numBytes)
+            {
+                case 4:
+                    data[0] = (byte)(hex >> 24);
+                    data[1] = (byte)(hex >> 16);
+                    data[2] = (byte)(hex >> 8);
+                    data[3] = (byte)hex;
+                    break;
+                case 3:
+                    hex &= 0x00FFFFFF;//clear bits not used
+                    data[0] = (byte)(hex >> 16);
+                    data[1] = (byte)(hex >> 8);
+                    data[2] = (byte)hex;
+                    break;
+                case 2:
+                    hex &= 0x0000FFFF;//clear bits not used
+                    data[0] = (byte)(hex >> 8);
+                    data[1] = (byte)hex;
+                    break;
+                case 1:
+                    hex &= 0x000000FF;//clear bits not used
+                    data[0] = (byte)hex;
+                    break;
+            }
+            controller.WriteRegister(reg);
+        }
+
+        /// <summary>
+        /// Verify hex
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="numBytes"></param>
+        /// <returns></returns>
+        public String ValidateHexValue(String value, byte numBytes)
+        {
+            char[] character = new char[numBytes * 2];
+            String error = "Valid";
+
+            if (value == null)
+            {
+                error = "Empty Value";
+                return error;
+            }
+
+            //check to see if too many characters were entered
+            if (value.Length > numBytes * 2)
+                error = "Too many characters";
+            else
+            {
+                character = value.ToCharArray();    //split string into character array
+
+                for (int i = 0; i < value.Length; i++)
+                {
+                    if (Char.IsLetterOrDigit(character[i])) //check for letter and digits
+                    {
+                        if (Char.IsLower(character[i]))
+                            character[i] = Char.ToUpper(character[i]); //changed letter to upper case
+
+                        //check A-F
+                        if (character[i] > 'F')
+                            error = "Invalid Letter";
+                    }
+                    else
+                        error = "Invalid Character";
+                }
+            }
+            return error;
+        }
+
+        public void WriteAll()
+        {
+            if (Connected)
+                controller.WriteAll();
+            DisplayRegisters();
+        }
+
+        /// <summary>
+        /// Read all button handler
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void btn_ReadAll_Click(object sender, EventArgs e)
+        {
+            ReadAll();
+        }
+
+        /// <summary>
+        /// Read all registers and display results
+        /// </summary>
+        public void ReadAll()
+        {
+            if (Connected)
+                controller.ReadAll();
+            DisplayRegisters();
+            UpdateRegisterBits();
+        }
+
+        public RegisterInfo RegisterAddress(int address)
+        {
+            for(int i = 0; i < controller.InfoArray.Length; i++)
+            {
+                if (controller.InfoArray[i].address == address)
+                    return controller.InfoArray[i];
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Read register handler
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void btnRead_Click(object sender, EventArgs e)
+        {
+            if (connected)
+            {
+                controller.ReadRegister(controller.InfoArray[dgv_Registers.SelectedRows[0].Index]);
+                DisplayRegisters();
+                UpdateRegisterBits();
+            }
+        }
+
+        /// <summary>
+        /// Toggle register bit handler
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void lblBit_Click(object sender, EventArgs e)
+        {
+            Label lbl = (Label)sender;
+
+            string[] number = Regex.Split(lbl.Name, @"\D+");
+
+            if (lbl.Font.Bold == true)
+                lbl.Font = RegularFont;
+            else
+                lbl.Font = BoldFont;
+
+            foreach(string value in number)
+            {
+                if (value != String.Empty)
+                {
+                    int bitNumber = Int32.Parse(value);
+
+                    RegisterValue &= ~(1 << bitNumber); // clear bit
+                    RegisterValue |= ((lbl.Font.Bold == true ? 1 : 0) << bitNumber); // set bit
+                }
+            }
+        }
+
+        /// <summary>
+        /// Write register button handler
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void btnWrite_Click(object sender, EventArgs e)
+        {
+            if (connected)
+            {
+                WriteRegister(controller.InfoArray[dgv_Registers.SelectedRows[0].Index], RegisterValue);
+                controller.ReadRegister(controller.InfoArray[dgv_Registers.SelectedRows[0].Index]);
+                DisplayRegisters();
+            }
+        }
+
+        /// <summary>
+        /// On cell begin edit
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void OnCellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
+        {
+            if (CellBeginEdit != null)
+            {
+                CellBeginEdit(sender, e);
+            }
+        } 
+
+        private void DataGridViewColumns(DataGridView listview, SizeF factor)
+        {
+            foreach (DataGridViewColumn column in listview.Columns)
+            {
+                column.Width = (int)Math.Round(column.Width * factor.Width);
+            }
+        }
+
+        protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
+        {
+            base.ScaleControl(factor, specified);
+            DataGridViewColumns(dgv_RegDes, factor);
+            DataGridViewColumns(dgv_Registers, factor);
+        }
+        /*
+        public class RegisterProcess
+        {
+            RegisterBit[][] Data;
+
+            public RegisterProcess(RegisterInfo[] info)
+            {
+                Data = new RegisterBit[info.Length][];
+				
+				for (int i = 0; i < info.Length; i++)
+				{
+					Data[i] = new RegisterBit[info[i].description.list.Count];
+					
+					for (int j = 0; j < info[i].description.list.Count; j++)
+					{
+						int fieldValue;
+                        fieldValue = (info[i].dataField >> info[i].description.list[j].Index) & info[i].description.list[j].Width;
+						Data[i][j] = new RegisterBit(info[i].description.list[j].name, fieldValue);
+					}
+				}
+            }
+
+            class RegisterBit
+            {
+                string Name;
+                int Data;
+				
+				public RegisterBit(string name, int data)
+				{
+					Name = name;
+					Data = data;
+				}
+            }
+        }
+        */
+
+        public class RegisterArgs : EventArgs
+        {
+            public int Register;
+        }
+
+
+    }
+}