repo time
Dependencies: mbed MAX14720 MAX30205 USBDevice
HspGuiSourceV301/HSPGui/CustomControls/RegisterView.cs
- Committer:
- darienf
- Date:
- 2021-04-06
- Revision:
- 20:6d2af70c92ab
File content as of revision 20:6d2af70c92ab:
/******************************************************************************* * 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; } } }