Big changes
This commit is contained in:
@@ -0,0 +1,384 @@
|
||||
// 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 NLog;
|
||||
using Raytheon.Common;
|
||||
using Raytheon.Instruments;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MeasurementManagerLib
|
||||
{
|
||||
/// <summary>
|
||||
/// This class manages IFpgaComm instruments and provides an abstraction
|
||||
/// </summary>
|
||||
public class FpgaMeasurementManager : IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
// fpga name to object
|
||||
private readonly Dictionary<string, IFpgaComm> _fpgaDeviceMap;
|
||||
// fpga to MemoryMap
|
||||
private readonly Dictionary<string, MemoryMap> _fpgaMemMaps;
|
||||
|
||||
private static NLog.ILogger _logger;
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// Finalizer.
|
||||
/// </summary>
|
||||
~FpgaMeasurementManager()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposing
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
foreach (KeyValuePair<string, IFpgaComm> entry in _fpgaDeviceMap)
|
||||
{
|
||||
try
|
||||
{
|
||||
entry.Value.Shutdown();
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the communication to the fpga
|
||||
/// </summary>
|
||||
/// <param name="fpga">the name of the fpga as defined in the config file</param>
|
||||
private void Initialize(string fpga)
|
||||
{
|
||||
if (_fpgaDeviceMap.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("could not find device: " + fpga);
|
||||
}
|
||||
|
||||
_fpgaDeviceMap[fpga].Initialize(fpga);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// constructor with instrument manager
|
||||
/// </summary>
|
||||
/// <param name="instrumentManager"></param>
|
||||
/// <param name="instrumentNames"></param>
|
||||
/// <param name="instrumentDefFile"></param>
|
||||
public FpgaMeasurementManager(IInstrumentManager instrumentManager, List<string> instrumentNames, string instrumentDefFile)
|
||||
{
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
_fpgaDeviceMap = new Dictionary<string, IFpgaComm>();
|
||||
|
||||
foreach (string name in instrumentNames)
|
||||
{
|
||||
_fpgaDeviceMap[name] = instrumentManager.GetInstrument<IFpgaComm>(name);
|
||||
_fpgaDeviceMap[name]?.Initialize(name);
|
||||
}
|
||||
|
||||
// setup the memory maps
|
||||
_fpgaMemMaps = new Dictionary<string, MemoryMap>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
ConfigurationFile ini = new ConfigurationFile(instrumentDefFile);
|
||||
|
||||
foreach (KeyValuePair<string, IFpgaComm> entry in _fpgaDeviceMap)
|
||||
{
|
||||
string memMapFile = ini.ReadValue<string>(entry.Key, "MEM_MAP");
|
||||
|
||||
if (memMapFile.ToUpper().Trim() != "NONE")
|
||||
{
|
||||
_fpgaMemMaps.Add(entry.Key.ToUpper(), new MemoryMap(memMapFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the comm device
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <returns></returns>
|
||||
public IFpgaComm GetFpgaCommDevice(string fpga)
|
||||
{
|
||||
if (_fpgaDeviceMap.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("could not find device: " + fpga);
|
||||
}
|
||||
|
||||
return _fpgaDeviceMap[fpga.ToUpper()];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all of the fpga names
|
||||
/// </summary>
|
||||
/// <returns>A list of fpga device names</returns>
|
||||
public List<string> GetFpgaNames()
|
||||
{
|
||||
List<string> fpgaList = new List<string>();
|
||||
|
||||
foreach (KeyValuePair<string, IFpgaComm> entry in _fpgaDeviceMap)
|
||||
{
|
||||
fpgaList.Add(entry.Key);
|
||||
}
|
||||
|
||||
return fpgaList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a register that is defined by a memory map logical name
|
||||
/// If a subitem is commanded, this returns just the value of the subitems
|
||||
/// </summary>
|
||||
/// <param name="fpga">the name of the fpga as defined in the config file</param>
|
||||
/// <param name="memMapItemName">The name of the mem map item in the memory map file</param>
|
||||
/// <returns></returns>
|
||||
public uint RegisterRead(string fpga, string memMapItemName)
|
||||
{
|
||||
if (_fpgaMemMaps.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("no memory map exists for fpga: " + fpga);
|
||||
}
|
||||
|
||||
MemoryMap.MemoryMapFields fields = _fpgaMemMaps[fpga.ToUpper()].GetRegisterInfoByString(memMapItemName);
|
||||
|
||||
uint registerValue = _fpgaDeviceMap[fpga.ToUpper()].Read(fpga, fields._address);
|
||||
|
||||
uint itemValue = Util.ParseRegisterItem(registerValue, fields._startBit, fields._numBits);
|
||||
|
||||
return itemValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a register given an address
|
||||
/// </summary>
|
||||
/// <param name="fpga">the name of the fpga as defined in the config file</param>
|
||||
/// <param name="address">the address to read</param>
|
||||
/// <returns></returns>
|
||||
public uint RegisterRead(string fpga, uint address)
|
||||
{
|
||||
if (_fpgaDeviceMap.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("could not find device: " + fpga);
|
||||
}
|
||||
|
||||
return _fpgaDeviceMap[fpga.ToUpper()].Read(fpga, address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a register given an address with optional offset
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <param name="memMapItemName"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public uint RegisterRead(string fpga, string memMapItemName, uint offset = 0)
|
||||
{
|
||||
if (_fpgaMemMaps.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("no memory map exists for fpga: " + fpga);
|
||||
}
|
||||
|
||||
MemoryMap.MemoryMapFields fields = _fpgaMemMaps[fpga.ToUpper()].GetRegisterInfoByString(memMapItemName);
|
||||
|
||||
uint registerValue = _fpgaDeviceMap[fpga.ToUpper()].Read(fpga, fields._address + offset);
|
||||
|
||||
uint itemValue = Util.ParseRegisterItem(registerValue, fields._startBit, fields._numBits);
|
||||
|
||||
return itemValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads block from fpga
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public void ReadBlock(string fpga, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
if (_fpgaDeviceMap.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("FpgaMeasurementManager::ReadBlock - could not find device: " + fpga);
|
||||
}
|
||||
|
||||
if (address == 0)
|
||||
{
|
||||
_fpgaDeviceMap[fpga.ToUpper()].ReadBlock(fpga, address, numberOfWordsToRead, shallWeIncrementAddress, ref dataRead);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a register given an address
|
||||
/// </summary>
|
||||
/// <param name="fpga">the name of the fpga as defined in the config file</param>
|
||||
/// <param name="address">The address to write to</param>
|
||||
/// <param name="dataToWrite">The data to write to the register</param>
|
||||
public void RegisterWrite(string fpga, uint address, uint dataToWrite)
|
||||
{
|
||||
if (_fpgaDeviceMap.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("could not find device: " + fpga);
|
||||
}
|
||||
|
||||
_fpgaDeviceMap[fpga.ToUpper().ToUpper()].Write(fpga, address, dataToWrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// write a register that is defined by a memory map logical name
|
||||
/// If a sub item is commanded, the current values of the other items remain unchanged
|
||||
/// </summary>
|
||||
/// <param name="fpga">the name of the fpga as defined in the config file</param>
|
||||
/// <param name="memMapItemName">The name of the mem map item in the memory map file</param>
|
||||
/// <param name="dataToWrite">The data to write to the register</param>
|
||||
/// <param name="offset">The offset off of memMapItemName</param>
|
||||
public void RegisterWrite(string fpga, string memMapItemName, uint dataToWrite, uint offset = 0)
|
||||
{
|
||||
if (_fpgaMemMaps.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("no memory map exists for fpga: " + fpga);
|
||||
}
|
||||
|
||||
MemoryMap.MemoryMapFields fields = _fpgaMemMaps[fpga.ToUpper()].GetRegisterInfoByString(memMapItemName);
|
||||
|
||||
uint address = fields._address + offset;
|
||||
|
||||
// if commanded to write to a sub register, only write out those bits
|
||||
if (fields._numBits < 32)
|
||||
{
|
||||
// read existing value
|
||||
uint originalValue = RegisterRead(fpga, address);
|
||||
|
||||
//Apply inverse mask to current register contents to zero out just the bits we want to write
|
||||
uint maskValue = Util.ApplyBitMask(originalValue, fields._startBit, fields._numBits, true);
|
||||
|
||||
// Shift the desired data to set to match the zeroed register
|
||||
dataToWrite = dataToWrite << fields._startBit;
|
||||
|
||||
dataToWrite = maskValue | dataToWrite;
|
||||
}
|
||||
|
||||
_fpgaDeviceMap[fpga.ToUpper()].Write(fpga, address, dataToWrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <param name="memMapItemName"></param>
|
||||
/// <param name="dataToWrite"></param>
|
||||
/// <param name="offset"></param>
|
||||
public void RegisterWriteBlock(string fpga, string memMapItemName, uint numWordsToWrite, uint[] dataToWrite, bool shallWeIncrementAddress, uint offset = 0)
|
||||
{
|
||||
if (_fpgaMemMaps.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("no memory map exists for fpga: " + fpga);
|
||||
}
|
||||
|
||||
MemoryMap.MemoryMapFields fields = _fpgaMemMaps[fpga.ToUpper()].GetRegisterInfoByString(memMapItemName);
|
||||
|
||||
uint address = fields._address + offset;
|
||||
|
||||
// if commanded to write to a sub register, only write out those bits
|
||||
if (fields._numBits < 32)
|
||||
{
|
||||
throw new Exception("can only write a block of data to a 32 bit register. fpga: " + fpga);
|
||||
}
|
||||
|
||||
_fpgaDeviceMap[fpga.ToUpper()].WriteBlock(fpga, address, numWordsToWrite, dataToWrite, shallWeIncrementAddress);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the default value (as specified in the memory map) to the register
|
||||
/// If a sub item is commanded, the current values of the other items remain unchanged
|
||||
/// </summary>
|
||||
/// <param name="fpga">The name of the FPGA</param>
|
||||
/// <param name="memMapItemName">The memory map item which we will restore the default.</param>
|
||||
public void RegisterWriteDefault(string fpga, string memMapItemName)
|
||||
{
|
||||
if (_fpgaMemMaps.ContainsKey(fpga.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("no memory map exists for fpga: " + fpga);
|
||||
}
|
||||
|
||||
MemoryMap.MemoryMapFields fields = _fpgaMemMaps[fpga.ToUpper()].GetRegisterInfoByString(memMapItemName);
|
||||
|
||||
uint dataToWrite = fields._regDefault;
|
||||
|
||||
// if commanded to write to a sub register, only write out those bits
|
||||
if (fields._numBits < 32)
|
||||
{
|
||||
// read existing value
|
||||
uint originalValue = RegisterRead(fpga, fields._address);
|
||||
|
||||
//Apply inverse mask to current register contents to zero out just the bits we want to write
|
||||
uint maskValue = Util.ApplyBitMask(originalValue, fields._startBit, fields._numBits, true);
|
||||
|
||||
// Shift the desired data to set to match the zeroed register
|
||||
dataToWrite = dataToWrite << fields._startBit;
|
||||
|
||||
dataToWrite = maskValue | dataToWrite;
|
||||
}
|
||||
|
||||
_fpgaDeviceMap[fpga.ToUpper()].Write(fpga, fields._address, dataToWrite);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user