// UNCLASSIFIED /*------------------------------------------------------------------------- RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON COMPANY. THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S. GOVERNMENT. UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY. -------------------------------------------------------------------------*/ using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; namespace Raytheon.Common { /// /// A class that reads a memory map upon construction and then serves up the fields of an entry upon request /// public class MemoryMap { #region PrivateClassMembers public struct MemoryMapFields { public readonly uint _page; public readonly uint _address; public readonly int _startBit; public readonly int _numBits; public readonly uint _regDefault; public readonly double _scaleFactor; public MemoryMapFields(uint page, uint address, int startBit, int numBits, uint regDefault, double scaleFactor) { _page = page; _address = address; _startBit = startBit; _numBits = numBits; _regDefault = regDefault; _scaleFactor = scaleFactor; } } private struct BitInfo { public int _start; public int _numOfBits; } private const string _NEWLINE = "\r\n"; private Dictionary _mapData; private double _scaleFactor = 1.0; #endregion #region PrivateFuctions /// /// /// /// /// private Dictionary CreateMemoryMapDictionary(string fileLocation) { Dictionary temp = new Dictionary(); //Open file for processing (read-only) using (FileStream readStream = new FileStream(fileLocation, FileMode.Open, FileAccess.Read)) { //Process the memmap ProcessFile(readStream, temp); } return temp; } /// /// Processes the memory map files into a data structure /// /// /// private void ProcessFile(FileStream fs, Dictionary memoryMap) { uint page = 0; uint address = 0; uint regDefault = 0; char[] delimit = { ' ' }; uint prevPage = 0; uint prevAddress = 0; uint parentRegDefault = 0; using (StreamReader reader = new StreamReader(fs)) { while (!reader.EndOfStream) { //Read a line from the file string line = reader.ReadLine(); //Parse the line by spaces (remove empty entries) string[] fields = line.Split(delimit, StringSplitOptions.RemoveEmptyEntries); //If nothing to read, stop processing if (fields.Length == 0) { break; } //Get the key (Register Name) string key = fields[0].ToUpper(); //Check for duplicates if (memoryMap.ContainsKey(key)) { throw new Exception("Duplicate item found in file: " + fs.Name + ", Item key: " + key); } //Check if the register is a parent or child //A child will use its parent address and gets it default value from its parent if (line.StartsWith(" ")) { regDefault = parentRegDefault; page = prevPage; address = prevAddress; } else { //Get the page number page = ProcessPageNum(fields[1]); //Get register address address = ProcessDecimalHex(fields[1]); //Get register default values regDefault = ProcessDecimalHex(fields[5]); //Get scale factor _scaleFactor = ProcessScaleFactor(line); } //Process bits BitInfo bitInfo = ProcessBitInfo(fields[3]); double scaleFactor = _scaleFactor; // parse out the default value for this child item if (bitInfo._numOfBits < 32) { // clear the upper bits int numBitsToClear = 32 - (bitInfo._start + bitInfo._numOfBits); regDefault = regDefault << numBitsToClear; // clear lower bits and place into position int numBitsForPosition = bitInfo._start + numBitsToClear; regDefault = regDefault >> numBitsForPosition; } else { parentRegDefault = regDefault; } memoryMap.Add(key, new MemoryMapFields(page, address, bitInfo._start, bitInfo._numOfBits, regDefault, scaleFactor)); // hold onto previous values for child items prevPage = page; prevAddress = address; } } } /// /// /// /// /// private uint ProcessPageNum(string pageNumber) { //Delimiter used to parse string char[] delimit = { '.' }; //Array of parsed string string[] strPageValues = pageNumber.Split(delimit); //Convert first array element uint value = uint.Parse(strPageValues[0]); //Return conversion return value; } /// /// /// /// /// private uint ProcessDecimalHex(string address) { //Delimiter used to parse string char[] delimit = { '.' }; //Array of parsed string string[] strValues = address.Split(delimit); string strCombined = ""; //Address = 0.XXXX.XXXX, register values = XXXX.XXXX if (strValues.Length == 3) { strCombined = strValues[1] + strValues[2]; } else { strCombined = strValues[0] + strValues[1]; } //Convert hex number to UInt uint value = uint.Parse(strCombined, System.Globalization.NumberStyles.HexNumber); //Return value return value; } /// /// /// /// /// private BitInfo ProcessBitInfo(string bits) { //Structure for bit information BitInfo temp; //Delimiter used to parse string char[] delimit = { ':' }; char[] trimChar = { '(', ')' }; string trimBits = bits.Trim(trimChar); string[] values = trimBits.Split(delimit); if (values.Length == 2) { //values represents a range of bits int start = int.Parse(values[1]); int end = int.Parse(values[0]); //Add one for zero offset temp._start = start; temp._numOfBits = end - start + 1; } else { //Only a single bit temp._numOfBits = 1; temp._start = int.Parse(values[0]); } return temp; } /// /// /// /// /// private double ProcessScaleFactor(string scaleFactor) { const string PATTERN = @"[+-]?[0-9]{1,}\.[0-9]{1,}[e][+-]?[0-9]{1,}"; //Find Scale Factor (default = 1) string sf = "1"; foreach (Match match in Regex.Matches(scaleFactor, PATTERN)) { sf = match.Value; } double value = double.Parse(sf); return value; } #endregion #region PublicFuctions /// /// The constructor /// /// The memory map file public MemoryMap(string memMapLocation) { _mapData = CreateMemoryMapDictionary(memMapLocation); } /// /// /// /// The name of the register /// public MemoryMapFields GetRegisterInfoByString(string registerName) { if (_mapData.ContainsKey(registerName.ToUpper()) == false) { throw new Exception("The requested register: " + registerName + " is not in the memory map"); } return _mapData[registerName.ToUpper()]; } #endregion } }