Big changes
This commit is contained in:
@@ -0,0 +1,565 @@
|
||||
// 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.IO.Ports;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A class the provides an interface for read/write to registers on an FPGA that implement a custom ascii serial interface
|
||||
/// </summary>
|
||||
public class CommFpgaCustomAsciiSerial : IFpgaComm, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private SerialPort _serialPort;
|
||||
private byte[] _readBuf;
|
||||
private static object _syncObj = new Object();
|
||||
private uint _delayBeforeReadMs;
|
||||
private string _readFormat;
|
||||
private string _writeFormat;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommFpgaCustomAsciiSerial()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads the serial port until it is empty
|
||||
/// </summary>
|
||||
private void ClearBuffer()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
bool isClearComplete = false;
|
||||
|
||||
while (isClearComplete == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
int numBytesRead = _serialPort.Read(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
if (numBytesRead < _readBuf.Length)
|
||||
{
|
||||
isClearComplete = true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//expected if buffer is already cleared
|
||||
isClearComplete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_serialPort.Dispose();
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// ELoadScpiKeysight factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaCustomAsciiSerial(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
const int READ_BUF_SIZE = 1024;
|
||||
|
||||
try
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
|
||||
string comPortName = _configuration.GetConfigurationValue("CommFpgaCustomAsciiSerial", "ComPortName", "COM1");
|
||||
int baudRate = _configuration.GetConfigurationValue("CommFpgaCustomAsciiSerial", "BaudRate", 9600);
|
||||
Parity parity = _configuration.GetConfigurationValue("CommFpgaCustomAsciiSerial", "Parity", Parity.None);
|
||||
int dataBits = _configuration.GetConfigurationValue("CommFpgaCustomAsciiSerial", "DataBits", 8);
|
||||
StopBits stopBits = _configuration.GetConfigurationValue("CommFpgaCustomAsciiSerial", "StopBits", StopBits.None);
|
||||
|
||||
_serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits);
|
||||
_readFormat = _configuration.GetConfigurationValue("CommFpgaCustomAsciiSerial", "ReadFormat", "");
|
||||
_writeFormat = _configuration.GetConfigurationValue("CommFpgaCustomAsciiSerial", "WriteFormat", "");
|
||||
_serialPort.ReadTimeout = _configuration.GetConfigurationValue("CommFpgaCustomAsciiSerial", "ReadTimeout", 100);
|
||||
_delayBeforeReadMs = _configuration.GetConfigurationValue<uint>("CommFpgaCustomAsciiSerial", "DelayBeforeReadMs", 0);
|
||||
|
||||
_readBuf = new byte[READ_BUF_SIZE];
|
||||
|
||||
//check format of readFormat and writeFormat
|
||||
if (!_readFormat.Contains("<ADDRESS>"))
|
||||
{
|
||||
throw new Exception("the read format input for card " + _name + " does not contain the <ADDRESS> tag");
|
||||
}
|
||||
|
||||
if (!_writeFormat.Contains("<ADDRESS>"))
|
||||
{
|
||||
throw new Exception("the write format input for card " + _name + " does not contain the <ADDRESS> tag");
|
||||
}
|
||||
|
||||
if (!_writeFormat.Contains("<DATA>"))
|
||||
{
|
||||
throw new Exception("the write format input for card " + _name + " does not contain the <DATA> tag");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex);
|
||||
|
||||
if (_serialPort.IsOpen == true)
|
||||
{
|
||||
_serialPort.Close();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor which opens up a serial port
|
||||
/// </summary>
|
||||
/// <param name="comPortName">The port name. "Com1' for example</param>
|
||||
/// <param name="delayBeforeReadMs">The num of ms to wait before a read</param>
|
||||
/// <param name="baudRate">The baud rate</param>
|
||||
/// <param name="parity">The parity</param>
|
||||
/// <param name="dataBits">Number of data bits</param>
|
||||
/// <param name="stopBits">Number of Stop Bits</param>
|
||||
public CommFpgaCustomAsciiSerial(string name, string comPortName, uint delayBeforeReadMs, string readFormat, string writeFormat, int baudRate = 115200, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
|
||||
{
|
||||
const int READ_BUF_SIZE = 1024;
|
||||
|
||||
try
|
||||
{
|
||||
_name = name;
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits);
|
||||
|
||||
_readFormat = readFormat;
|
||||
|
||||
_writeFormat = writeFormat;
|
||||
|
||||
_serialPort.ReadTimeout = 100;
|
||||
|
||||
_delayBeforeReadMs = delayBeforeReadMs;
|
||||
|
||||
_readBuf = new byte[READ_BUF_SIZE];
|
||||
|
||||
Array.Clear(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
//check format of readFormat and writeFormat
|
||||
if (readFormat.Contains("<ADDRESS>") == false)
|
||||
{
|
||||
throw new Exception("the read format input for card " + _name + " does not contain the <ADDRESS> tag");
|
||||
}
|
||||
|
||||
if (writeFormat.Contains("<ADDRESS>") == false)
|
||||
{
|
||||
throw new Exception("the write format input for card " + _name + " does not contain the <ADDRESS> tag");
|
||||
}
|
||||
|
||||
if (writeFormat.Contains("<DATA>") == false)
|
||||
{
|
||||
throw new Exception("the write format input for card " + _name + " does not contain the <DATA> tag");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex);
|
||||
|
||||
if (_serialPort.IsOpen == true)
|
||||
{
|
||||
_serialPort.Close();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a FPGA Custom Ascii called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
Initialize(string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
public void Initialize(string fpga)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
if (_serialPort.IsOpen == false)
|
||||
{
|
||||
_serialPort.Open();
|
||||
}
|
||||
|
||||
//ClearBuffer();
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
return _selfTestResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <returns></returns>
|
||||
public uint Read(string fpga, uint address)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
|
||||
string hexAddress = "0x" + address.ToString("X8");
|
||||
|
||||
string commandToSend = _readFormat.Replace("<ADDRESS>", hexAddress);
|
||||
|
||||
commandToSend = commandToSend.Trim();
|
||||
|
||||
_serialPort.Write(commandToSend);
|
||||
|
||||
Thread.Sleep((int)_delayBeforeReadMs);
|
||||
|
||||
int numBytesRead = _serialPort.Read(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
string data = Encoding.UTF8.GetString(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
// get rid of new lines
|
||||
data = data.Replace("\r", " ");
|
||||
data = data.Replace("\n", " ");
|
||||
data = data.Trim();
|
||||
|
||||
uint dataToReturn = Convert.ToUInt32(data, 16);
|
||||
|
||||
return dataToReturn;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
Thread.Sleep((int)_delayBeforeReadMs);
|
||||
|
||||
int bytesRead = _serialPort.Read(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
int bytesToCopy = Math.Min(bytesRead, dataRead.Length);
|
||||
|
||||
Array.Copy(_readBuf, dataRead, bytesToCopy);
|
||||
|
||||
Array.Clear(_readBuf, 0, _readBuf.Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_serialPort.Dispose();
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="data"></param>
|
||||
public void Write(string fpga, uint address, uint data)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
string hexAddress = "0x" + address.ToString("X8");
|
||||
|
||||
string hexData = "0x" + data.ToString("X8");
|
||||
|
||||
string commandToSend = _writeFormat.Replace("<ADDRESS>", hexAddress);
|
||||
|
||||
commandToSend = commandToSend.Replace("<DATA>", hexData);
|
||||
|
||||
commandToSend = commandToSend.Trim();
|
||||
|
||||
_serialPort.Write(commandToSend);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToWrite"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new Exception("Not Implemented");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads firmware
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
Initialize(fpgaName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaCustomAsciiSerialFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaCustomAsciiSerialFactory")]
|
||||
public class CommFpgaCustomAsciiSerialFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaCustomAsciiSerialFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaCustomAsciiSerialFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaCustomAsciiSerial(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
else
|
||||
return new CommFpgaCustomAsciiSerial(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGA.CustomAsciiSerial</AssemblyName>
|
||||
<Product>Custom Ascii Serial implementation</Product>
|
||||
<Description>FPGA Custom Ascii Serial implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FpgaSim\FpgaSim.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,593 @@
|
||||
// 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 FpgaMeasurementInstrumentsLib;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// This class serves as an interface to FPGAs that implement a UDP interface.
|
||||
/// It allows for the ability to read and write to registers.
|
||||
/// </summary>
|
||||
public class CommFpgaEthernet : IFpgaComm, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private UdpClient _udpClient;
|
||||
private readonly int _localPort;
|
||||
private readonly int _remotePort;
|
||||
private readonly string _remoteAddress;
|
||||
private static object _syncObj = new Object();
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommFpgaEthernet()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_udpClient.Close();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data off of the socket
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The data that was read</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
private int ReadData(ref byte[] dataRead)
|
||||
{
|
||||
IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, _localPort);
|
||||
|
||||
dataRead = _udpClient.Receive(ref remoteIPEndPoint);
|
||||
|
||||
int numBytesRead = dataRead.Length;
|
||||
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a command message and get a response message
|
||||
/// </summary>
|
||||
/// <param name="commandMsg">The message to send</param>
|
||||
/// <param name="rspMsg">The response</param>
|
||||
private void SendCommandGetResponse(FPGACmdMessage commandMsg, ref FPGARspMessage rspMsg)
|
||||
{
|
||||
uint rxBufferSize = rspMsg.GetEntireMsgLength();
|
||||
uint rxNumBytesExpected = rxBufferSize;
|
||||
|
||||
uint dataToSendNumBytes = commandMsg.GetEntireMsgLength();
|
||||
|
||||
// send the command
|
||||
byte[] dataToSend = new byte[dataToSendNumBytes];
|
||||
|
||||
// get a pointer to the data
|
||||
GCHandle sendPinnedArray = GCHandle.Alloc(dataToSend, GCHandleType.Pinned);
|
||||
IntPtr pByte = sendPinnedArray.AddrOfPinnedObject();
|
||||
commandMsg.Format(pByte);
|
||||
sendPinnedArray.Free();
|
||||
|
||||
// send the data
|
||||
int numBytesSent = SendData(dataToSend);
|
||||
|
||||
if (dataToSendNumBytes != numBytesSent)
|
||||
{
|
||||
throw new Exception("wanted to send: " + dataToSendNumBytes.ToString() + " bytes, SendData() reported that it sent: " + numBytesSent.ToString());
|
||||
}
|
||||
|
||||
// read the response
|
||||
byte[] rspBuffer = new byte[rxBufferSize];
|
||||
int numBytesRead = ReadData(ref rspBuffer);
|
||||
|
||||
if (numBytesRead != rxNumBytesExpected)
|
||||
{
|
||||
throw new Exception("received " + numBytesRead.ToString() + " bytes, expected " + rxNumBytesExpected.ToString());
|
||||
}
|
||||
|
||||
// populate the rspMsg object
|
||||
GCHandle rxPinnedArray = GCHandle.Alloc(rspBuffer, GCHandleType.Pinned);
|
||||
IntPtr pBytePtr = rxPinnedArray.AddrOfPinnedObject();
|
||||
rspMsg.Parse(pBytePtr);
|
||||
rxPinnedArray.Free();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send data out of the socket
|
||||
/// </summary>
|
||||
/// <param name="dataToSend">The data to send</param>
|
||||
/// <returns>The number of bytes sent</returns>
|
||||
private int SendData(byte[] dataToSend)
|
||||
{
|
||||
IPAddress addy = IPAddress.Parse(_remoteAddress);
|
||||
|
||||
IPEndPoint ipEndPoint = new IPEndPoint(addy, _remotePort);
|
||||
|
||||
int numBytesSent = _udpClient.Send(dataToSend, dataToSend.Length, ipEndPoint);
|
||||
|
||||
return numBytesSent;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommFpgaEthernet factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaEthernet(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_localPort = _configuration.GetConfigurationValue("CommFpgaEthernet", "LocalPort", 0);
|
||||
_remotePort = _configuration.GetConfigurationValue("CommFpgaEthernet", "RemotePort", 0);
|
||||
_remoteAddress = _configuration.GetConfigurationValue("CommFpgaEthernet", "RemoteAddress", "127.0.0.1");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="localPort">The port on the local computer</param>
|
||||
/// <param name="remotePort">The port that the FPGA is using</param>
|
||||
/// <param name="remoteAddress">The address that the FPGA is using</param>
|
||||
public CommFpgaEthernet(string name, int localPort, int remotePort, string remoteAddress)
|
||||
{
|
||||
_name = name;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_localPort = localPort;
|
||||
_remotePort = remotePort;
|
||||
_remoteAddress = remoteAddress;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a FPGA Ethernet called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
Initialize(string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
public void Initialize(string fpga)
|
||||
{
|
||||
//5 second timeout
|
||||
const int TIMEOUT = 5000;
|
||||
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_udpClient = new UdpClient(_localPort);
|
||||
|
||||
_udpClient.Client.ReceiveBufferSize = int.MaxValue;
|
||||
|
||||
_udpClient.Client.SendBufferSize = int.MaxValue;
|
||||
|
||||
_udpClient.Client.SendTimeout = TIMEOUT;
|
||||
|
||||
_udpClient.Client.ReceiveTimeout = TIMEOUT;
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
return _selfTestResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a single register
|
||||
/// </summary>
|
||||
/// <param name="page">The page of the register to read from</param>
|
||||
/// <param name="address">The register address to read from</param>
|
||||
/// <returns>The data at the address</returns>
|
||||
public uint Read(string fpgaName, uint address)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
FPGACmdMessage cmd = new FPGAReadRegisterCmdMessage((FPGACmdMessage.Page)0, address);
|
||||
|
||||
// this get populated in SendCommandGetResponse()
|
||||
FPGARspMessage rsp = new FPGAReadRegisterRspMessage(0, 0);
|
||||
|
||||
SendCommandGetResponse(cmd, ref rsp);
|
||||
|
||||
return rsp.GetData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (shallWeIncrementAddress)
|
||||
{
|
||||
FPGACmdMessage cmd = new FPGAReadRegisterCmdBlockIncrMessage((FPGACmdMessage.Page)0, address, numberOfWordsToRead, false);
|
||||
|
||||
// this get populated in SendCommandGetResponse()
|
||||
FPGARspMessage rsp = new FPGAReadRegisterBlockIncrRspMessage(0, ref dataRead);
|
||||
|
||||
SendCommandGetResponse(cmd, ref rsp);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Not Implemented");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_udpClient.Close();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write to a single register
|
||||
/// </summary>
|
||||
/// <param name="page">The page of the register to read from</param>
|
||||
/// <param name="address">The address to write to</param>
|
||||
/// <param name="value">The data to write</param>
|
||||
public void Write(string fpgaName, uint address, uint value)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
FPGACmdMessage cmd = new FPGAWriteRegisterCmdMessage((FPGACmdMessage.Page)0, address, value);
|
||||
|
||||
// this get populated in SendCommandGetResponse()
|
||||
FPGARspMessage rsp = new FPGAWriteRegisterRspMessage(0, 0);
|
||||
|
||||
SendCommandGetResponse(cmd, ref rsp);
|
||||
|
||||
if (rsp.GetAddress() != address)
|
||||
{
|
||||
throw new Exception("Command write on address: " + address.ToString("X8") + ", received address: " + rsp.GetAddress().ToString("X8"));
|
||||
}
|
||||
else if (rsp.GetData() != 0xace0beef)
|
||||
{
|
||||
throw new Exception("Command write on address: " + address.ToString("X8") + " returned value: " + rsp.GetData().ToString("X8"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfBytes"></param>
|
||||
/// <param name="data"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
FPGACmdMessage cmd = null;
|
||||
|
||||
if (shallWeIncrementAddress)
|
||||
{
|
||||
cmd = new FPGAWriteRegisterCmdBlockIncrMessage((FPGACmdMessage.Page)0, address, data, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd = new FPGAWriteRegisterCmdBlockMessage((FPGACmdMessage.Page)0, address, data, false);
|
||||
}
|
||||
|
||||
// this get populated in SendCommandGetResponse()
|
||||
FPGARspMessage rsp = new FPGAWriteRegisterRspMessage(0, 0);
|
||||
|
||||
SendCommandGetResponse(cmd, ref rsp);
|
||||
|
||||
if (rsp.GetAddress() != address)
|
||||
{
|
||||
throw new Exception("Command write on address: " + address.ToString("X8") + ", received address: " + rsp.GetAddress().ToString("X8"));
|
||||
}
|
||||
else if (rsp.GetData() != 0xace0beef)
|
||||
{
|
||||
throw new Exception("Command write on address: " + address.ToString("X8") + " returned value: " + rsp.GetData().ToString("X8"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="page"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="incrementAddress"></param>
|
||||
/// <param name="byteSwap"></param>
|
||||
public void WriteRegister(uint page, uint address, uint[] data, bool incrementAddress = true, bool byteSwap = true)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (page > (uint)FPGACmdMessage.Page.PAGE3)
|
||||
{
|
||||
throw new Exception("input parameter 'page' is out of range: " + page.ToString());
|
||||
}
|
||||
|
||||
FPGACmdMessage cmd;
|
||||
|
||||
if (incrementAddress)
|
||||
{
|
||||
cmd = new FPGAWriteRegisterCmdBlockIncrMessage((FPGACmdMessage.Page)page, address, data, byteSwap);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd = new FPGAWriteRegisterCmdBlockMessage((FPGACmdMessage.Page)page, address, data, byteSwap);
|
||||
}
|
||||
|
||||
|
||||
// this get populated in SendCommandGetResponse()
|
||||
FPGARspMessage rsp = new FPGAWriteRegisterRspMessage(0, 0);
|
||||
|
||||
SendCommandGetResponse(cmd, ref rsp);
|
||||
|
||||
if (rsp.GetAddress() != address)
|
||||
{
|
||||
throw new Exception("Command write on address: " + address.ToString("X8") + ", received address: " + rsp.GetAddress().ToString("X8"));
|
||||
}
|
||||
else if (rsp.GetData() != 0xace0beef)
|
||||
{
|
||||
throw new Exception("Command write on address: " + address.ToString("X8") + " returned value: " + rsp.GetData().ToString("X8"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads firmware
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
Initialize(fpgaName);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaEthernetFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaEthernetFactory")]
|
||||
public class CommFpgaEthernetFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaEthernetFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaEthernetFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaEthernet(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
else
|
||||
return new CommFpgaEthernet(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGA.Ethernet</AssemblyName>
|
||||
<Product>FPGA Ethernet implementation</Product>
|
||||
<Description>FPGA Ethernet implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FpgaSim\FpgaSim.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,227 @@
|
||||
// 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;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract base class for FPGACmdMessages that go between the client and server
|
||||
/// </summary>
|
||||
internal abstract class FPGACmdMessage : ICloneable
|
||||
{
|
||||
#region PublicClassMembers
|
||||
public enum Page
|
||||
{
|
||||
PAGE0,
|
||||
PAGE1,
|
||||
PAGE2,
|
||||
PAGE3
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PrivateClassMembers
|
||||
private readonly string m_description;
|
||||
|
||||
protected FPGACmdMessageHeader m_header;
|
||||
|
||||
protected static void SwapWord(ref byte[] input)
|
||||
{
|
||||
//Word Size
|
||||
int WORD_SIZE = 4;
|
||||
|
||||
for (int i = 0; i < input.Length; i = i + WORD_SIZE)
|
||||
{
|
||||
//Temp array for swap
|
||||
byte[] temp = new byte[WORD_SIZE];
|
||||
|
||||
//Copy a word into temp
|
||||
Buffer.BlockCopy(input, i, temp, 0, WORD_SIZE);
|
||||
|
||||
//Swap bytes
|
||||
Array.Reverse(temp);
|
||||
|
||||
//Replace word
|
||||
Buffer.BlockCopy(temp, 0, input, i, WORD_SIZE);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
/// <summary>
|
||||
/// A command message constructor for all children to invoke
|
||||
/// </summary>
|
||||
/// <param name="commandType">The command message id</param>
|
||||
/// <param name="page">The page of the command message</param>
|
||||
/// <param name="description">The description of the command message</param>
|
||||
protected FPGACmdMessage(FPGACmdMsgIds commandType, Page page, string description)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_description = description;
|
||||
m_header = new FPGACmdMessageHeader(commandType, page);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy Constructor
|
||||
/// </summary>
|
||||
/// <param name="FPGACmdMessage">The FPGACmdMessage to copy from</param>
|
||||
protected FPGACmdMessage(FPGACmdMessage FPGACmdMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_header = new FPGACmdMessageHeader(FPGACmdMessage.m_header);
|
||||
m_description = FPGACmdMessage.m_description;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A clone function for the children to implement
|
||||
/// </summary>
|
||||
/// <returns>a clone of the child object</returns>
|
||||
protected abstract object CloneSelf();
|
||||
|
||||
/// <summary>
|
||||
/// A function to encode outgoing data
|
||||
/// </summary>
|
||||
/// <param name="pData">a pointer to the encoded data</param>
|
||||
protected abstract void FormatData(IntPtr pData);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected abstract int GetPayloadSize();
|
||||
|
||||
/// <summary>
|
||||
/// a function to decode incoming data
|
||||
/// </summary>
|
||||
/// <param name="pData">A pointer to data to populate this object with</param>
|
||||
protected abstract void ParseData(IntPtr pData);
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// Get a copy of the FPGACmdMessage object
|
||||
/// </summary>
|
||||
/// <returns>A clone of this object</returns>
|
||||
public object Clone()
|
||||
{
|
||||
// tell the child to clone itself
|
||||
return this.CloneSelf();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the FPGACmdMessage into a byte array for sending
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the FPGACmdMessage items</param>
|
||||
public void Format(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_header.Format(pData);
|
||||
|
||||
IntPtr pPayload = IntPtr.Add(pData, (int)GetHeaderLength());
|
||||
|
||||
// ask child class to format its data
|
||||
FormatData(pPayload);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Getter for the description
|
||||
/// </summary>
|
||||
/// <returns>The description</returns>
|
||||
public string GetDescription()
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the message id
|
||||
/// </summary>
|
||||
/// <returns>The id</returns>
|
||||
public FPGACmdMsgIds GetMessageId()
|
||||
{
|
||||
return m_header.GetMessageId();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the header length
|
||||
/// </summary>
|
||||
/// <returns>The number of bytes in the header</returns>
|
||||
public uint GetHeaderLength()
|
||||
{
|
||||
return m_header.GetHeaderLength();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public uint GetEntireMsgLength()
|
||||
{
|
||||
return m_header.GetHeaderLength() + (uint)GetPayloadSize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the FPGACmdMessage object
|
||||
/// </summary>
|
||||
/// <param name="pData">The FPGACmdMessage in byte form</param>
|
||||
public void Parse(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_header.Parse(pData);
|
||||
|
||||
IntPtr pPayLoad = IntPtr.Add(pData, (int)GetHeaderLength());
|
||||
|
||||
ParseData(pPayLoad);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this FPGACmdMessage into string form
|
||||
/// </summary>
|
||||
/// <returns>The FPGACmdMessage in string form</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string desc = "Description: " + GetDescription() + "\n" + m_header.ToString();
|
||||
|
||||
return desc;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// The header for all command messages
|
||||
/// </summary>
|
||||
internal class FPGACmdMessageHeader
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private const int m_HEADER_SIZE = 1;
|
||||
private byte m_headerCmd;
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="header">The header to copy</param>
|
||||
public FPGACmdMessageHeader(FPGACmdMessageHeader header)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_headerCmd = header.m_headerCmd;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for when receiving data.
|
||||
/// Use this constructor and then parse to populate it
|
||||
/// </summary>
|
||||
public FPGACmdMessageHeader()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_headerCmd = 0;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for sending
|
||||
/// </summary>
|
||||
/// <param name="commandType">the type of the message</param>
|
||||
/// <param name="page">The page to read or write to</param>
|
||||
public FPGACmdMessageHeader(FPGACmdMsgIds commandType, FPGACmdMessage.Page page)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_headerCmd = (byte)((byte)commandType | (byte)page);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the header into a byte array for sending
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
public void Format(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
Marshal.StructureToPtr(m_headerCmd, pData, true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the number of bytes in the header
|
||||
/// </summary>
|
||||
/// <returns>The header length in bytes</returns>
|
||||
public uint GetHeaderLength()
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_HEADER_SIZE;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the message id
|
||||
/// </summary>
|
||||
/// <returns>The message id</returns>
|
||||
public FPGACmdMsgIds GetMessageId()
|
||||
{
|
||||
byte temp = (byte)(m_headerCmd >> 4);
|
||||
return (FPGACmdMsgIds)temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the header object
|
||||
/// </summary>
|
||||
/// <param name="pData">The header in byte form</param>
|
||||
public void Parse(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_headerCmd = System.Runtime.InteropServices.Marshal.ReadByte(pData, 0);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string version of the header members
|
||||
/// </summary>
|
||||
/// <returns>A string containning the header data</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string msg = "Header Data:\r\n";
|
||||
msg += "Command: " + m_headerCmd.ToString("X") + "\r\n";
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 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.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
#region PublicClassMembers
|
||||
/// <summary>
|
||||
/// The command message IDs for messages that go between the host pc and the fpga
|
||||
/// </summary>
|
||||
internal enum FPGACmdMsgIds
|
||||
{
|
||||
TYPE_TWO_READ_CMD_ID = 0x40,
|
||||
TYPE_TWO_WRITE_CMD_ID = 0xC0,
|
||||
TYPE_THREE_READ_CMD_ID = 0x58,
|
||||
TYPE_THREE_WRITE_CMD_ID = 0xD8
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The command message IDs for messages that go between the host pc and the fpga
|
||||
/// </summary>
|
||||
internal enum FPGARspMsgIds
|
||||
{
|
||||
TYPE_TWO_READ_RSP_ID = 0xC0,
|
||||
TYPE_TWO_WRITE_RSP_ID = 0xAA,
|
||||
TYPE_THREE_WRITE_RSP_ID = 0x0
|
||||
};
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// A message to read a register of the FPGA
|
||||
/// </summary>
|
||||
internal class FPGAReadRegisterCmdBlockIncrMessage : FPGACmdMessage
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
private struct Data
|
||||
{
|
||||
public uint m_address;
|
||||
};
|
||||
|
||||
private Data m_dataStruct;
|
||||
|
||||
//Dummy Array used to identify how much data will be sent back
|
||||
private byte[] m_data;
|
||||
|
||||
private bool m_byteSwap;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Create a copy of this object
|
||||
/// </summary>
|
||||
/// <returns>A copy of this object</returns>
|
||||
protected override object CloneSelf()
|
||||
{
|
||||
FPGAReadRegisterCmdBlockIncrMessage msg = new FPGAReadRegisterCmdBlockIncrMessage(this);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the message into a byte array for sending.
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
protected override void FormatData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// perform byte swapping and copy data into the buffer
|
||||
Data dataTemp = m_dataStruct;
|
||||
|
||||
//Swap address bytes
|
||||
dataTemp.m_address = Util.Swap(dataTemp.m_address);
|
||||
|
||||
//Create a pointer to message we want to send
|
||||
Marshal.StructureToPtr(dataTemp, pData, true);
|
||||
|
||||
//Increment pointer to account for the m_dataStruct struct
|
||||
pData = IntPtr.Add(pData, Marshal.SizeOf(typeof(Data)));
|
||||
|
||||
//Copy array into pointer
|
||||
Marshal.Copy(m_data, 0, pData, m_data.Length);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override int GetPayloadSize()
|
||||
{
|
||||
return Marshal.SizeOf(m_dataStruct) + m_data.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the message object
|
||||
/// </summary>
|
||||
/// <param name="pData">The message in byte form</param>
|
||||
protected override void ParseData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// copy data into our structure
|
||||
m_dataStruct = (Data)(Marshal.PtrToStructure(pData, typeof(Data)));
|
||||
|
||||
//Increment point address to end of structure
|
||||
pData = IntPtr.Add(pData, Marshal.SizeOf(typeof(Data)));
|
||||
|
||||
//Copy data from pointer to array
|
||||
Marshal.Copy(pData, m_data, 0, m_data.Length);
|
||||
|
||||
//swap address
|
||||
m_dataStruct.m_address = Util.Swap(m_dataStruct.m_address);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="rhs">The object to copy</param>
|
||||
public FPGAReadRegisterCmdBlockIncrMessage(FPGAReadRegisterCmdBlockIncrMessage rhs)
|
||||
: base(rhs)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct = rhs.m_dataStruct;
|
||||
m_byteSwap = rhs.m_byteSwap;
|
||||
m_data = rhs.m_data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor for sending
|
||||
/// </summary>
|
||||
/// <param name="page">The page to read from</param>
|
||||
/// <param name="address">The address to read</param>
|
||||
public FPGAReadRegisterCmdBlockIncrMessage(Page page, uint address, uint numWords, bool swapDataBytes)
|
||||
: base(FPGACmdMsgIds.TYPE_THREE_READ_CMD_ID, page, "Read Register Command")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct.m_address = address;
|
||||
m_byteSwap = swapDataBytes;
|
||||
|
||||
//Create an empty array the size of numWords
|
||||
m_data = new byte[numWords * sizeof(uint)];
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this object into string form
|
||||
/// </summary>
|
||||
/// <returns>A string representing this message</returns>
|
||||
public override String ToString()
|
||||
{
|
||||
string msg = base.ToString();
|
||||
msg += " address: " + m_dataStruct.m_address.ToString() + "\r\n\r\n";
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
// 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 Raytheon.Common;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// A message to read a register of the FPGA
|
||||
/// </summary>
|
||||
internal class FPGAReadRegisterCmdMessage : FPGACmdMessage
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
private struct Data
|
||||
{
|
||||
public uint m_address;
|
||||
public uint m_spare;
|
||||
};
|
||||
|
||||
private Data m_dataStruct;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Create a copy of this object
|
||||
/// </summary>
|
||||
/// <returns>A copy of this object</returns>
|
||||
protected override object CloneSelf()
|
||||
{
|
||||
FPGAReadRegisterCmdMessage msg = new FPGAReadRegisterCmdMessage(this);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the message into a byte array for sending.
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
protected override void FormatData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// perform byte swapping and copy data into the buffer
|
||||
Data dataTemp = m_dataStruct;
|
||||
dataTemp.m_address = Util.Swap(dataTemp.m_address);
|
||||
Marshal.StructureToPtr(dataTemp, pData, true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override int GetPayloadSize()
|
||||
{
|
||||
return Marshal.SizeOf(m_dataStruct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the message object
|
||||
/// </summary>
|
||||
/// <param name="pData">The message in byte form</param>
|
||||
protected override void ParseData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// copy data into our structure and byte swap
|
||||
m_dataStruct = (Data)(Marshal.PtrToStructure(pData, typeof(Data)));
|
||||
m_dataStruct.m_address = Util.Swap(m_dataStruct.m_address);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="rhs">The object to copy</param>
|
||||
public FPGAReadRegisterCmdMessage(FPGAReadRegisterCmdMessage rhs)
|
||||
: base(rhs)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct = rhs.m_dataStruct;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor for sending
|
||||
/// </summary>
|
||||
/// <param name="page">The page to read from</param>
|
||||
/// <param name="address">The address to read</param>
|
||||
public FPGAReadRegisterCmdMessage(Page page, uint address)
|
||||
: base(FPGACmdMsgIds.TYPE_TWO_READ_CMD_ID, page, "Read Register Command")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct.m_address = address;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this object into string form
|
||||
/// </summary>
|
||||
/// <returns>A string representing this message</returns>
|
||||
public override String ToString()
|
||||
{
|
||||
string msg = base.ToString();
|
||||
msg += " address: " + m_dataStruct.m_address.ToString("X8") + "\r\n\r\n";
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// The response message for the FPGAReadRegisterCmdMessage
|
||||
/// </summary>
|
||||
internal class FPGAReadRegisterBlockIncrRspMessage : FPGARspMessage
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
private struct Data
|
||||
{
|
||||
public uint m_address;
|
||||
public uint m_data;
|
||||
};
|
||||
|
||||
//array for all received data (address/data)
|
||||
private Data[] m_dataArray;
|
||||
|
||||
//Array(ref) for received data (data only)
|
||||
private uint[] m_refArray;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Create a copy of this object
|
||||
/// </summary>
|
||||
/// <returns>A copy of this object</returns>
|
||||
protected override object CloneSelf()
|
||||
{
|
||||
FPGAReadRegisterBlockIncrRspMessage msg = new FPGAReadRegisterBlockIncrRspMessage(this);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the message into a byte array for sending.
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
protected override void FormatData(IntPtr pData)
|
||||
{
|
||||
//From base class. Data does not need to be formatted (will not be sent out)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override int GetPayloadSize()
|
||||
{
|
||||
//Size of Data (address and data) * number of elements
|
||||
return Marshal.SizeOf(typeof(Data)) * m_dataArray.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the message object
|
||||
/// </summary>
|
||||
/// <param name="pData">The message in byte form</param>
|
||||
protected override void ParseData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < m_dataArray.Length; i++)
|
||||
{
|
||||
//Copy data into the structure
|
||||
m_dataArray[i] = (Data)(Marshal.PtrToStructure(pData, typeof(Data)));
|
||||
|
||||
//Increment pointer
|
||||
pData = IntPtr.Add(pData, Marshal.SizeOf(typeof(Data)));
|
||||
|
||||
//Swap Address
|
||||
m_dataArray[i].m_address = Util.Swap(m_dataArray[i].m_address);
|
||||
|
||||
//Swap Data
|
||||
m_dataArray[i].m_data = Util.Swap(m_dataArray[i].m_data);
|
||||
|
||||
//Move data into referenced array
|
||||
m_refArray[i] = m_dataArray[i].m_data;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="rhs">The object to copy</param>
|
||||
public FPGAReadRegisterBlockIncrRspMessage(FPGAReadRegisterBlockIncrRspMessage rhs)
|
||||
: base(rhs)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataArray = rhs.m_dataArray;
|
||||
m_refArray = rhs.m_refArray;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor
|
||||
/// </summary>
|
||||
/// <param name="address">The address that was read from from</param>
|
||||
/// <param name="data">The data that was read</param>
|
||||
public FPGAReadRegisterBlockIncrRspMessage(uint address, ref uint[] data)
|
||||
: base(FPGARspMsgIds.TYPE_TWO_READ_RSP_ID, "Read Register Response Message")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataArray = new Data[data.Length];
|
||||
|
||||
m_refArray = data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the address
|
||||
/// </summary>
|
||||
/// <returns>TThe address</returns>
|
||||
public override uint GetAddress()
|
||||
{
|
||||
//Array of data. This function would need to change
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the data
|
||||
/// </summary>
|
||||
/// <returns>The data</returns>
|
||||
public override uint GetData()
|
||||
{
|
||||
//Array of data. This function would need to change
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this object into string form
|
||||
/// </summary>
|
||||
/// <returns>The string form of this object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string msg = base.ToString();
|
||||
for (int i = 0; i < m_dataArray.Length; i++)
|
||||
{
|
||||
msg += " address: " + m_dataArray[i].m_address.ToString("X8") + "\r\n";
|
||||
msg += " data: " + m_dataArray[i].m_data.ToString("X8") + "\r\n\r\n";
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// The response message for the FPGAReadRegisterCmdMessage
|
||||
/// </summary>
|
||||
internal class FPGAReadRegisterRspMessage : FPGARspMessage
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
private struct Data
|
||||
{
|
||||
public uint m_address;
|
||||
public uint m_data;
|
||||
};
|
||||
|
||||
private Data m_dataStruct;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Create a copy of this object
|
||||
/// </summary>
|
||||
/// <returns>A copy of this object</returns>
|
||||
protected override object CloneSelf()
|
||||
{
|
||||
FPGAReadRegisterRspMessage msg = new FPGAReadRegisterRspMessage(this);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the message into a byte array for sending.
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
protected override void FormatData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// perform byte swapping and copy data into the buffer
|
||||
Data dataTemp = m_dataStruct;
|
||||
dataTemp.m_address = Util.Swap(dataTemp.m_address);
|
||||
dataTemp.m_data = Util.Swap(dataTemp.m_data);
|
||||
Marshal.StructureToPtr(dataTemp, pData, true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override int GetPayloadSize()
|
||||
{
|
||||
return Marshal.SizeOf(typeof(Data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the message object
|
||||
/// </summary>
|
||||
/// <param name="pData">The message in byte form</param>
|
||||
protected override void ParseData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// copy data into our structure and byte swap
|
||||
m_dataStruct = (Data)(Marshal.PtrToStructure(pData, typeof(Data)));
|
||||
m_dataStruct.m_address = Util.Swap(m_dataStruct.m_address);
|
||||
m_dataStruct.m_data = Util.Swap(m_dataStruct.m_data);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="rhs">The object to copy</param>
|
||||
public FPGAReadRegisterRspMessage(FPGAReadRegisterRspMessage rhs)
|
||||
: base(rhs)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct = rhs.m_dataStruct;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor
|
||||
/// </summary>
|
||||
/// <param name="address">The address that was read from from</param>
|
||||
/// <param name="data">The data that was read</param>
|
||||
public FPGAReadRegisterRspMessage(uint address, uint data)
|
||||
: base(FPGARspMsgIds.TYPE_TWO_READ_RSP_ID, "Read Register Response Message")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct.m_address = address;
|
||||
m_dataStruct.m_data = data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the address
|
||||
/// </summary>
|
||||
/// <returns>TThe address</returns>
|
||||
public override uint GetAddress()
|
||||
{
|
||||
return m_dataStruct.m_address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the data
|
||||
/// </summary>
|
||||
/// <returns>The data</returns>
|
||||
public override uint GetData()
|
||||
{
|
||||
return m_dataStruct.m_data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this object into string form
|
||||
/// </summary>
|
||||
/// <returns>The string form of this object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string msg = base.ToString();
|
||||
msg += " address: " + m_dataStruct.m_address.ToString("X8") + "\r\n";
|
||||
msg += " data: " + m_dataStruct.m_data.ToString("X8") + "\r\n\r\n";
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
// 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;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract base class for FPGARspMessages that go between the client and server
|
||||
/// </summary>
|
||||
internal abstract class FPGARspMessage : ICloneable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
protected FPGARspMessageHeader m_header;
|
||||
private readonly string m_description;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
/// The constructor that the children will call
|
||||
/// </summary>
|
||||
/// <param name="commandType">The message id</param>
|
||||
/// <param name="description">The message description</param>
|
||||
protected FPGARspMessage(FPGARspMsgIds commandType, string description)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_description = description;
|
||||
m_header = new FPGARspMessageHeader(commandType);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy Constructor
|
||||
/// </summary>
|
||||
/// <param name="FPGARspMessage">The FPGARspMessage to copy from</param>
|
||||
protected FPGARspMessage(FPGARspMessage FPGARspMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_header = new FPGARspMessageHeader(FPGARspMessage.m_header);
|
||||
m_description = FPGARspMessage.m_description;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A function to create a copy of the object for all children to implement
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected abstract object CloneSelf();
|
||||
|
||||
/// <summary>
|
||||
/// A function to encode data for sending
|
||||
/// </summary>
|
||||
/// <param name="pData">A pointer to the spot to put the encoded data</param>
|
||||
protected abstract void FormatData(IntPtr pData);
|
||||
|
||||
/// <summary>
|
||||
/// Get the size of the payload
|
||||
/// </summary>
|
||||
/// <returns>The size of the message payload</returns>
|
||||
protected abstract int GetPayloadSize();
|
||||
|
||||
/// <summary>
|
||||
/// A function to decode data that was received
|
||||
/// </summary>
|
||||
/// <param name="pData">A pointer to the data to decode</param>
|
||||
protected abstract void ParseData(IntPtr pData);
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Get a copy of the FPGARspMessage object
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public object Clone()
|
||||
{
|
||||
// tell the child to clone itself
|
||||
return this.CloneSelf();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the FPGARspMessage into a byte array for sending
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the FPGARspMessage items</param>
|
||||
public void Format(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_header.Format(pData);
|
||||
|
||||
IntPtr pPayload = IntPtr.Add(pData, (int)GetHeaderLength());
|
||||
|
||||
// ask child class to format its data
|
||||
FormatData(pPayload);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A getter function for the children to implement
|
||||
/// </summary>
|
||||
/// <returns>The address that was read</returns>
|
||||
public abstract uint GetAddress();
|
||||
|
||||
/// <summary>
|
||||
/// A getter function for the children to implement
|
||||
/// </summary>
|
||||
/// <returns>The data that was read</returns>
|
||||
public abstract uint GetData();
|
||||
|
||||
/// <summary>
|
||||
/// Getter for this message description
|
||||
/// </summary>
|
||||
/// <returns>The description</returns>
|
||||
public string GetDescription()
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Getter for the number of bytes in the entire message
|
||||
/// </summary>
|
||||
/// <returns>The number of bytes in the FPGARspMessage, including header</returns>
|
||||
public uint GetEntireMsgLength()
|
||||
{
|
||||
return GetHeaderLength() + (uint)GetPayloadSize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the number of bytes in the header
|
||||
/// </summary>
|
||||
/// <returns>The number of bytes in the head</returns>
|
||||
public uint GetHeaderLength()
|
||||
{
|
||||
return m_header.GetHeaderLength();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the FPGARspMessage object
|
||||
/// </summary>
|
||||
/// <param name="pData">The FPGARspMessage in byte form</param>
|
||||
public void Parse(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_header.Parse(pData);
|
||||
|
||||
IntPtr pPayLoad = IntPtr.Add(pData, (int)GetHeaderLength());
|
||||
|
||||
ParseData(pPayLoad);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this FPGARspMessage into string form
|
||||
/// </summary>
|
||||
/// <returns>The FPGARspMessage in string form</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "Description: " + GetDescription() + "\n" + m_header.ToString();
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// 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;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// The header for the response messages
|
||||
/// </summary>
|
||||
internal class FPGARspMessageHeader
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private const int m_HEADER_SIZE = 0;
|
||||
private const uint m_ENTIRE_MSG_SIZE = 8;
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="header">The header to copy</param>
|
||||
public FPGARspMessageHeader(FPGARspMessageHeader header)
|
||||
{
|
||||
try
|
||||
{
|
||||
// m_data = header.m_data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for when receiving data.
|
||||
/// Use this constructor and then parse to populate it
|
||||
/// </summary>
|
||||
public FPGARspMessageHeader()
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for sending
|
||||
/// </summary>
|
||||
/// <param name="commandType">the type of the message</param>
|
||||
public FPGARspMessageHeader(FPGARspMsgIds commandType)
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the header into a byte array for sending
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
public void Format(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Getter for the entire message length in bytes
|
||||
/// </summary>
|
||||
/// <returns>The number of bytes in the message, including header</returns>
|
||||
public uint GetEntireMsgLength()
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_ENTIRE_MSG_SIZE;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the header length in bytes
|
||||
/// </summary>
|
||||
/// <returns>The header length in bytes</returns>
|
||||
public uint GetHeaderLength()
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_HEADER_SIZE;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the header object
|
||||
/// </summary>
|
||||
/// <param name="pData">The header in byte form</param>
|
||||
public void Parse(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// copy data into our structure and byte swap
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string version of the header members
|
||||
/// </summary>
|
||||
/// <returns>A string containning the header data</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string msg = "Header Data:\r\n\r\n";
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
// 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 Raytheon.Common;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal class FPGAWriteRegisterCmdBlockIncrMessage : FPGACmdMessage
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
private struct Data
|
||||
{
|
||||
public uint m_address;
|
||||
};
|
||||
|
||||
private byte[] m_data;
|
||||
|
||||
private Data m_dataStruct;
|
||||
|
||||
private bool m_byteSwap;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Create a copy of this object
|
||||
/// </summary>
|
||||
/// <returns>A copy of this object</returns>
|
||||
protected override object CloneSelf()
|
||||
{
|
||||
FPGAWriteRegisterCmdBlockIncrMessage msg = new FPGAWriteRegisterCmdBlockIncrMessage(this);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the message into a byte array for sending.
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
protected override void FormatData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Temporary storage for message data
|
||||
Data dataTemp = m_dataStruct;
|
||||
|
||||
//address swap
|
||||
dataTemp.m_address = Util.Swap(dataTemp.m_address);
|
||||
|
||||
//Do we need to swap bytes
|
||||
if (m_byteSwap == true)
|
||||
{
|
||||
SwapWord(ref m_data);
|
||||
}
|
||||
|
||||
//Pointer to message
|
||||
Marshal.StructureToPtr(dataTemp, pData, true);
|
||||
pData = IntPtr.Add(pData, Marshal.SizeOf(typeof(Data)));
|
||||
Marshal.Copy(m_data, 0, pData, m_data.Length);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override int GetPayloadSize()
|
||||
{
|
||||
return Marshal.SizeOf(m_dataStruct) + m_data.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the message object
|
||||
/// </summary>
|
||||
/// <param name="pData">The message in byte form</param>
|
||||
protected override void ParseData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
//copy data into our structure
|
||||
m_dataStruct = (Data)(Marshal.PtrToStructure(pData, typeof(Data)));
|
||||
pData = IntPtr.Add(pData, Marshal.SizeOf(typeof(Data)));
|
||||
Marshal.Copy(pData, m_data, 0, m_data.Length);
|
||||
|
||||
m_dataStruct.m_address = Util.Swap(m_dataStruct.m_address);
|
||||
|
||||
//Swap data if required
|
||||
if (m_byteSwap)
|
||||
{
|
||||
SwapWord(ref m_data);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="rhs">The object to copy</param>
|
||||
public FPGAWriteRegisterCmdBlockIncrMessage(FPGAWriteRegisterCmdBlockIncrMessage rhs)
|
||||
: base(rhs)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct = rhs.m_dataStruct;
|
||||
m_byteSwap = rhs.m_byteSwap;
|
||||
m_data = rhs.m_data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor for sending
|
||||
/// </summary>
|
||||
public FPGAWriteRegisterCmdBlockIncrMessage(Page page, uint address, byte[] data, bool swapDataBytes)
|
||||
: base(FPGACmdMsgIds.TYPE_THREE_WRITE_CMD_ID, page, "Write Register Command Increment Block")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct.m_address = address;
|
||||
m_data = data;
|
||||
m_byteSwap = swapDataBytes;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="page"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="swapDataBytes"></param>
|
||||
public FPGAWriteRegisterCmdBlockIncrMessage(Page page, uint address, uint[] data, bool swapDataBytes)
|
||||
: base(FPGACmdMsgIds.TYPE_THREE_WRITE_CMD_ID, page, "Write Register Command Increment Block")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct.m_address = address;
|
||||
m_byteSwap = swapDataBytes;
|
||||
|
||||
//Convert to Byte Array
|
||||
m_data = new byte[data.Length * sizeof(uint)];
|
||||
Buffer.BlockCopy(data, 0, m_data, 0, m_data.Length);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this object into string form
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string msg = base.ToString();
|
||||
msg += " address: " + m_dataStruct.m_address.ToString("X8") + "\r\n\r\n";
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
// 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 Raytheon.Common;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal class FPGAWriteRegisterCmdBlockMessage : FPGACmdMessage
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
private struct Data
|
||||
{
|
||||
public uint m_address;
|
||||
};
|
||||
|
||||
private byte[] m_data;
|
||||
|
||||
private Data m_dataStruct;
|
||||
|
||||
private bool m_byteSwap;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Create a copy of this object
|
||||
/// </summary>
|
||||
/// <returns>A copy of this object</returns>
|
||||
protected override object CloneSelf()
|
||||
{
|
||||
FPGAWriteRegisterCmdBlockMessage msg = new FPGAWriteRegisterCmdBlockMessage(this);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the message into a byte array for sending.
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
protected override void FormatData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Temporary storage for message data
|
||||
Data dataTemp = m_dataStruct;
|
||||
|
||||
//address swap
|
||||
dataTemp.m_address = Util.Swap(dataTemp.m_address);
|
||||
|
||||
//Do we need to swap bytes
|
||||
if (m_byteSwap)
|
||||
{
|
||||
//Swap
|
||||
SwapWord(ref m_data);
|
||||
}
|
||||
|
||||
//Pointer to message
|
||||
Marshal.StructureToPtr(dataTemp, pData, true);
|
||||
pData = IntPtr.Add(pData, Marshal.SizeOf(typeof(Data)));
|
||||
Marshal.Copy(m_data, 0, pData, m_data.Length);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override int GetPayloadSize()
|
||||
{
|
||||
return Marshal.SizeOf(m_dataStruct) + m_data.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the message object
|
||||
/// </summary>
|
||||
/// <param name="pData">The message in byte form</param>
|
||||
protected override void ParseData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
//copy data into our structure
|
||||
m_dataStruct = (Data)(Marshal.PtrToStructure(pData, typeof(Data)));
|
||||
pData = IntPtr.Add(pData, Marshal.SizeOf(typeof(Data)));
|
||||
Marshal.Copy(pData, m_data, 0, m_data.Length);
|
||||
|
||||
m_dataStruct.m_address = Util.Swap(m_dataStruct.m_address);
|
||||
|
||||
//Swap data if required
|
||||
if (m_byteSwap)
|
||||
{
|
||||
SwapWord(ref m_data);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="rhs">The object to copy</param>
|
||||
public FPGAWriteRegisterCmdBlockMessage(FPGAWriteRegisterCmdBlockMessage rhs)
|
||||
: base(rhs)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct = rhs.m_dataStruct;
|
||||
m_byteSwap = rhs.m_byteSwap;
|
||||
m_data = rhs.m_data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor for sending
|
||||
/// </summary>
|
||||
public FPGAWriteRegisterCmdBlockMessage(Page page, uint address, byte[] data, bool swapDataBytes)
|
||||
: base(FPGACmdMsgIds.TYPE_TWO_WRITE_CMD_ID, page, "Write Register Command Block")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct.m_address = address;
|
||||
m_byteSwap = swapDataBytes;
|
||||
m_data = data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="page"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="swapDataBytes"></param>
|
||||
public FPGAWriteRegisterCmdBlockMessage(Page page, uint address, uint[] data, bool swapDataBytes)
|
||||
: base(FPGACmdMsgIds.TYPE_TWO_WRITE_CMD_ID, page, "Write Register Command Block")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct.m_address = address;
|
||||
m_byteSwap = swapDataBytes;
|
||||
|
||||
m_data = new byte[data.Length * sizeof(uint)];
|
||||
Buffer.BlockCopy(data, 0, m_data, 0, m_data.Length);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this object into string form
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string msg = base.ToString();
|
||||
msg += " address: " + m_dataStruct.m_address.ToString("X8") + "\r\n\r\n";
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// 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 Raytheon.Common;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// The message that targets the VRSUI to make a connection
|
||||
/// </summary>
|
||||
internal class FPGAWriteRegisterCmdMessage : FPGACmdMessage
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
private struct Data
|
||||
{
|
||||
public uint m_address;
|
||||
public uint m_data;
|
||||
};
|
||||
|
||||
private Data m_dataStruct;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Create a copy of this object
|
||||
/// </summary>
|
||||
/// <returns>A copy of this object</returns>
|
||||
protected override object CloneSelf()
|
||||
{
|
||||
FPGAWriteRegisterCmdMessage msg = new FPGAWriteRegisterCmdMessage(this);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the message into a byte array for sending.
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
protected override void FormatData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// perform byte swapping and copy data into the buffer
|
||||
Data dataTemp = m_dataStruct;
|
||||
dataTemp.m_address = Util.Swap(dataTemp.m_address);
|
||||
dataTemp.m_data = Util.Swap(dataTemp.m_data);
|
||||
Marshal.StructureToPtr(dataTemp, pData, true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override int GetPayloadSize()
|
||||
{
|
||||
return Marshal.SizeOf(m_dataStruct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the message object
|
||||
/// </summary>
|
||||
/// <param name="pData">The message in byte form</param>
|
||||
protected override void ParseData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// copy data into our structure and byte swap
|
||||
m_dataStruct = (Data)(Marshal.PtrToStructure(pData, typeof(Data)));
|
||||
m_dataStruct.m_address = Util.Swap(m_dataStruct.m_address);
|
||||
m_dataStruct.m_data = Util.Swap(m_dataStruct.m_data);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="rhs">The object to copy</param>
|
||||
public FPGAWriteRegisterCmdMessage(FPGAWriteRegisterCmdMessage rhs)
|
||||
: base(rhs)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct = rhs.m_dataStruct;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor for sending
|
||||
/// </summary>
|
||||
public FPGAWriteRegisterCmdMessage(Page page, uint address, uint data)
|
||||
: base(FPGACmdMsgIds.TYPE_TWO_WRITE_CMD_ID, page, "Write Register Command")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct.m_address = address;
|
||||
m_dataStruct.m_data = data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this object into string form
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string msg = base.ToString();
|
||||
msg += " address: " + m_dataStruct.m_address.ToString("X8") + "\r\n";
|
||||
msg += " data: " + m_dataStruct.m_data.ToString("X8") + "\r\n\r\n";
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// The response message from the VRSUI upon receiving a VrsConnectCmdMessage
|
||||
/// </summary>
|
||||
internal class FPGAWriteRegisterRspMessage : FPGARspMessage
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
private struct Data
|
||||
{
|
||||
public uint m_address;
|
||||
public uint m_data;
|
||||
};
|
||||
|
||||
private Data m_dataStruct;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Create a copy of this object
|
||||
/// </summary>
|
||||
/// <returns>A copy of this object</returns>
|
||||
protected override object CloneSelf()
|
||||
{
|
||||
FPGAWriteRegisterRspMessage msg = new FPGAWriteRegisterRspMessage(this);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the message into a byte array for sending.
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
protected override void FormatData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// perform byte swapping and copy data into the buffer
|
||||
Data dataTemp = m_dataStruct;
|
||||
dataTemp.m_address = Util.Swap(dataTemp.m_address);
|
||||
dataTemp.m_data = Util.Swap(dataTemp.m_data);
|
||||
Marshal.StructureToPtr(dataTemp, pData, true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override int GetPayloadSize()
|
||||
{
|
||||
return Marshal.SizeOf(typeof(Data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the message object
|
||||
/// </summary>
|
||||
/// <param name="pData">The message in byte form</param>
|
||||
protected override void ParseData(IntPtr pData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// copy data into our structure and byte swap
|
||||
m_dataStruct = (Data)(Marshal.PtrToStructure(pData, typeof(Data)));
|
||||
m_dataStruct.m_address = Util.Swap(m_dataStruct.m_address);
|
||||
m_dataStruct.m_data = Util.Swap(m_dataStruct.m_data);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="rhs">The object to copy</param>
|
||||
public FPGAWriteRegisterRspMessage(FPGAWriteRegisterRspMessage rhs)
|
||||
: base(rhs)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct = rhs.m_dataStruct;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor for sending
|
||||
/// </summary>
|
||||
/// <param name="address">The address to write to</param>
|
||||
/// <param name="data">The data to write</param>
|
||||
public FPGAWriteRegisterRspMessage(uint address, uint data)
|
||||
: base(FPGARspMsgIds.TYPE_TWO_WRITE_RSP_ID, "Write Register Response Message")
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dataStruct.m_address = address;
|
||||
m_dataStruct.m_data = data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the address
|
||||
/// </summary>
|
||||
/// <returns>The address</returns>
|
||||
public override uint GetAddress()
|
||||
{
|
||||
return m_dataStruct.m_address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter for the data
|
||||
/// </summary>
|
||||
/// <returns>The data</returns>
|
||||
public override uint GetData()
|
||||
{
|
||||
return m_dataStruct.m_data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this object into string form
|
||||
/// </summary>
|
||||
/// <returns>The string form of this object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string msg = base.ToString();
|
||||
msg += " address: " + m_dataStruct.m_address.ToString("X8") + "\r\n";
|
||||
msg += " data: " + m_dataStruct.m_data.ToString("X8") + "\r\n\r\n";
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,499 @@
|
||||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that implements the Teradyne HSS Sub System Chassis
|
||||
/// </summary>
|
||||
public unsafe class CommFpgaHssubChassisSs : IFpgaComm
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
#pragma warning disable CS0649
|
||||
public struct CardInfo
|
||||
{
|
||||
internal string cardName;
|
||||
internal string cardAddress;
|
||||
internal int startingOffset;
|
||||
internal string cardFirmwareFile;
|
||||
internal string memMap;
|
||||
}
|
||||
#pragma warning restore
|
||||
|
||||
private static object _syncObj = new Object();
|
||||
|
||||
private SortedDictionary<string, CommFpgaHssubCardSs> _hssCardNameMap;
|
||||
private List<CardInfo> _cardList;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer.
|
||||
/// </summary>
|
||||
~CommFpgaHssubChassisSs()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="cardName"></param>
|
||||
/// <param name="cardAddress"></param>
|
||||
/// <param name="cardOffset"></param>
|
||||
/// <param name="cardFirmwareFile"></param>
|
||||
private void CreateCard(string cardName, string cardAddress, int startingOffset, string cardFirmwareFile, string memMap)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
// create the card
|
||||
CommFpgaHssubCardSs card = new CommFpgaHssubCardSs(cardName, cardAddress, startingOffset, cardFirmwareFile, memMap);
|
||||
|
||||
// hold onto the card
|
||||
_hssCardNameMap[cardName] = card;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_hssCardNameMap[fpgaName].LoadFirmware();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void SelfTest()
|
||||
{
|
||||
// loop through each card and command self test
|
||||
|
||||
/*short testResults = -1;
|
||||
|
||||
StringBuilder errorStrTemp = new StringBuilder(512);
|
||||
|
||||
int ret = HssubNativeMethods.terHss_self_test(_chassisHandle, ref testResults, errorStrTemp);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _chassisLogicalName);
|
||||
|
||||
throw new Exception("terHss_self_test returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
else if (testResults != 0)
|
||||
{
|
||||
throw new Exception("HSSub Self Test returned an error: " + testResults.ToString() + ": " + errorStrTemp.ToString());
|
||||
}*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object's resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing">True = currently disposing, False = not disposing.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
foreach (KeyValuePair<string, CommFpgaHssubCardSs> entry in _hssCardNameMap)
|
||||
{
|
||||
entry.Value.Dispose();
|
||||
}
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommFpgaHssubChassisSs factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaHssubChassisSs(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_cardList = new List<CardInfo>();
|
||||
|
||||
// hold onto the card objects
|
||||
_hssCardNameMap = new SortedDictionary<string, CommFpgaHssubCardSs>();
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public CommFpgaHssubChassisSs(string name)
|
||||
{
|
||||
_name = name;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_cardList = new List<CardInfo>();
|
||||
|
||||
// hold onto the card objects
|
||||
_hssCardNameMap = new SortedDictionary<string, CommFpgaHssubCardSs>();
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="cardInfo"></param>
|
||||
public void AddCard(CardInfo cardInfo)
|
||||
{
|
||||
_cardList.Add(cardInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a FPGA HSS Chassis SS " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object's resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <returns></returns>
|
||||
public string GetMemMap(string fpga)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
return _hssCardNameMap[fpga].GetMemMap();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
Initialize(string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
public void Initialize(string fpga)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
// init each card
|
||||
for (int i = 0; i < _cardList.Count; i++)
|
||||
{
|
||||
CreateCard(_cardList[i].cardName, _cardList[i].cardAddress, _cardList[i].startingOffset, _cardList[i].cardFirmwareFile, _cardList[i].memMap);
|
||||
}
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
return _selfTestResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <returns></returns>
|
||||
public uint Read(string fpgaName, uint address)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
return _hssCardNameMap[fpgaName].Read(fpgaName, address);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_hssCardNameMap[fpgaName].ReadBlock(fpgaName, address, numberOfWordsToRead, shallWeIncrementAddress, ref dataRead);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
foreach (KeyValuePair<string, CommFpgaHssubCardSs> entry in _hssCardNameMap)
|
||||
{
|
||||
entry.Value.Dispose();
|
||||
}
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="value"></param>
|
||||
public void Write(string fpgaName, uint address, uint value)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_hssCardNameMap[fpgaName].Write(fpgaName, address, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToWrite"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_hssCardNameMap[fpgaName].WriteBlock(fpgaName, address, numberOfWordsToWrite, data, shallWeIncrementAddress);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaHssubCardSsFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaHssubChassisSsFactory")]
|
||||
public class CommFpgaHssubChassisSsFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaHssubChassisSsFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaHssubChassisSsFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaHssubChassisSs(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
else
|
||||
return new CommFpgaHssubChassisSs(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGA.HssubChassisSs</AssemblyName>
|
||||
<Product>FPGA Hssub Chassis Ss implementation</Product>
|
||||
<Description>FPGA Hssub Chassis Ss implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FpgaSim\FpgaSim.csproj" />
|
||||
<ProjectReference Include="..\HssubCardSs\HssubCardSs.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,717 @@
|
||||
// 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 FpgaMeasurementInstrumentsLib;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that implements the Teradyne HSS Test Station Chassis
|
||||
/// </summary>
|
||||
public unsafe class CommFpgaHssubChassisTs : IFpgaComm
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
public struct LocalBusParams
|
||||
{
|
||||
public int cardHandle;
|
||||
public int address;
|
||||
public int data;
|
||||
}
|
||||
|
||||
public struct CardInfo
|
||||
{
|
||||
public string cardName;
|
||||
public string cardAddress;
|
||||
public int startingOffset;
|
||||
public string cardFirmwareFile;
|
||||
public string memMap;
|
||||
}
|
||||
|
||||
private static object _syncObj = new Object();
|
||||
|
||||
private SortedDictionary<string, CommFpgaHssubCardTs> _hssCardNameMap;
|
||||
private SortedDictionary<int, CommFpgaHssubCardTs> _hssCardHandleMap;
|
||||
|
||||
private readonly string _chassisAddress;
|
||||
private readonly string _killHandlerAppName;
|
||||
private readonly string _msgHandlerAppName;
|
||||
private uint _chassisHandle;
|
||||
private int _hssubAppInit;
|
||||
private int _hssubSubSystemApp;
|
||||
private int _hssubSubSystemAppSync;
|
||||
private int _hssubCloseAppSync;
|
||||
private int _hssubKillApp;
|
||||
private int _hsiHandle;
|
||||
private List<CardInfo> _cardList;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private string _name;
|
||||
|
||||
private HssubNativeMethods.MessageCallbackDelagate _callBack;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer.
|
||||
/// </summary>
|
||||
~CommFpgaHssubChassisTs()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="cardName"></param>
|
||||
/// <param name="cardAddress"></param>
|
||||
/// <param name="cardOffset"></param>
|
||||
/// <param name="cardFirmwareFile"></param>
|
||||
private void CreateCard(string cardName, string cardAddress, int startingOffset, string cardFirmwareFile, string memMap)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
// create the card
|
||||
CommFpgaHssubCardTs card = new CommFpgaHssubCardTs(cardName, cardAddress, startingOffset, cardFirmwareFile, _chassisHandle, _hssubSubSystemApp, _hssubSubSystemAppSync, memMap);
|
||||
|
||||
// wait for the chassis to respond
|
||||
HssUtilTs.WaitForSync(_chassisHandle, _hssubSubSystemAppSync, _name);
|
||||
|
||||
// make sure the chassis gave us a good card handle
|
||||
if (_hsiHandle == 0)
|
||||
{
|
||||
throw new Exception("_hsiHandle is 0");
|
||||
}
|
||||
|
||||
// give the card its handle
|
||||
card.SetHandle(_hsiHandle);
|
||||
|
||||
// hold onto the card
|
||||
_hssCardNameMap[cardName] = card;
|
||||
_hssCardHandleMap[_hsiHandle] = card;
|
||||
|
||||
// set the _hsiHandle back to zero for the next card
|
||||
_hsiHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object's resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing">True = currently disposing, False = not disposing.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
int ret = HssubNativeMethods.terHss_close(_chassisHandle);
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void InitChassis()
|
||||
{
|
||||
//0 is VI_FALSE, 1 is VI_TRUE
|
||||
int ret = HssubNativeMethods.terHss_init(_chassisAddress, 0, 1, ref _chassisHandle);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_init returned returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
// start the message application
|
||||
LoadMessageApp();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void LoadMessageApp()
|
||||
{
|
||||
int ret = HssubNativeMethods.terHss_Application_CreateSyncObject(_chassisHandle, "AppInit", ref _hssubAppInit);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_CreateSyncObject(AppInit) returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
ret = HssubNativeMethods.terHss_Application_CreateSyncObject(_chassisHandle, "AppSync", ref _hssubSubSystemAppSync);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_CreateSyncObject(AppSync) returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
ret = HssubNativeMethods.terHss_Application_CreateSyncObject(_chassisHandle, "SubAppQuit", ref _hssubCloseAppSync);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_CreateSyncObject(SubAppQuit) returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
ret = HssubNativeMethods.terHss_Application_RegisterMessageCallback(_chassisHandle, _callBack);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_RegisterMessageCallback() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
ret = HssubNativeMethods.terHss_Subsystem_SendFile(_chassisHandle, _killHandlerAppName, "c:\\temp\\killhndlr.bat", HssubNativeMethods.TERHSS_OPTION_ALLOW_OVERWRITE);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_SubSyste_SendFile(Killer App) returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
ret = HssubNativeMethods.terHss_Application_Load(_chassisHandle, "Killer App", "c:\\temp\\killhndlr.bat", ref _hssubKillApp);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_Load(Killer App) returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
ret = HssubNativeMethods.terHss_Application_Start(_chassisHandle, _hssubKillApp, "", 1);
|
||||
/*if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtil.BuildErrorString(_chassisHandle, ret, _chassisLogicalName);
|
||||
|
||||
throw new Exception("terHss_Application_Start(Killer App) returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}*/
|
||||
|
||||
ret = HssubNativeMethods.terHss_Subsystem_SendFile(_chassisHandle, _msgHandlerAppName, "c:\\temp\\hndlr.exe", HssubNativeMethods.TERHSS_OPTION_ALLOW_OVERWRITE);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_SubSyste_SendFile(Msg Handler App) returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
ret = HssubNativeMethods.terHss_Application_Load(_chassisHandle, "Subsystem App", "c:\\temp\\hndlr.exe", ref _hssubSubSystemApp);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_Load(Msg Handler App) returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
ret = HssubNativeMethods.terHss_Application_Start(_chassisHandle, _hssubSubSystemApp, "", HssubNativeMethods.TERHSS_TIMEOUT_60SEC);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_Start(Msg Handler App) returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
// wait for the chassis to respond
|
||||
HssUtilTs.WaitForSync(_chassisHandle, _hssubAppInit, _name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sessionHandle"></param>
|
||||
/// <param name="applicationHandle"></param>
|
||||
/// <param name="messageContext"></param>
|
||||
/// <param name="messageSize"></param>
|
||||
/// <param name="message"></param>
|
||||
private void MessageCallback(uint sessionHandle, int applicationHandle, int messageContext, uint messageSize, byte* pMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write("received message ID: " + messageContext.ToString(), ErrorLogger.LogLevel.INFO);
|
||||
|
||||
if (messageContext == HssubNativeMethods.MESSAGE_CONTEXT_INIT_INSTRUMENT)
|
||||
{
|
||||
int* pTemp = (int*)pMessage;
|
||||
_hsiHandle = *pTemp;
|
||||
}
|
||||
else if (messageContext == HssubNativeMethods.MESSAGE_CONTEXT_LB_READ32)
|
||||
{
|
||||
// get data into array and convert to the LocalBusParams structure
|
||||
byte[] arr = new byte[messageSize];
|
||||
|
||||
Marshal.Copy((IntPtr)pMessage, arr, 0, (int)messageSize);
|
||||
|
||||
HssUtilTs.LocalBusParams lbParams = HssUtilTs.ByteArrayToLocalBusParms(arr);
|
||||
|
||||
_hssCardHandleMap[lbParams.cardHandle].SetLocalBusRxData(lbParams.address, lbParams.data);
|
||||
}
|
||||
/*else if (messageContext == HssubNativeMethods.MESSAGE_CONTEXT_LB_WRITE32)//@@@ this case does not exist...
|
||||
{
|
||||
//HssubChassis.LocalBusParams lbParams = HssUtil.ByteArrayToLocalBusParms(message);
|
||||
|
||||
//_hssCardHandleMap[lbParams.cardHandle].SetLocalBusRxData(lbParams.address, lbParams.data);
|
||||
}*/
|
||||
else
|
||||
{
|
||||
//ErrorLogger.Instance().Write("" + messageContext + " not yet handled");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//ErrorLogger.Instance().Write("" + err.Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommFpgaHssubChassisTs factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaHssubChassisTs(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_chassisAddress = _configuration.GetConfigurationValue("CommFpgaHssubChassisTs", "ChassisAddress", "127.0.0.1");
|
||||
_killHandlerAppName = _configuration.GetConfigurationValue("CommFpgaHssubChassisTs", "KillHandlerAppName", "");
|
||||
_msgHandlerAppName = _configuration.GetConfigurationValue("CommFpgaHssubChassisTs", "MsgHandlerAppName", "");
|
||||
|
||||
_cardList = new List<CardInfo>();
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
|
||||
// hold onto callback
|
||||
_callBack = new HssubNativeMethods.MessageCallbackDelagate(MessageCallback);
|
||||
|
||||
// _chassisHandle gets set in Initialize
|
||||
_chassisHandle = 0;
|
||||
|
||||
// these get initialized in LoadMessageApp()
|
||||
_hssubAppInit = 0;
|
||||
_hssubSubSystemApp = 0;
|
||||
_hssubSubSystemAppSync = 0;
|
||||
_hssubCloseAppSync = 0;
|
||||
_hssubKillApp = 0;
|
||||
|
||||
// this is for card handles, it gets set in the MessageCallback() and passed over to the card object
|
||||
_hsiHandle = 0;
|
||||
|
||||
// hold onto the card objects
|
||||
_hssCardNameMap = new SortedDictionary<string, CommFpgaHssubCardTs>();
|
||||
_hssCardHandleMap = new SortedDictionary<int, CommFpgaHssubCardTs>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="chassisLogicalName"></param>
|
||||
/// <param name="chassisAddress"></param>
|
||||
/// <param name="killHandlerAppName"></param>
|
||||
/// <param name="msgHandlerAppName"></param>
|
||||
public CommFpgaHssubChassisTs(string name, string chassisAddress, string killHandlerAppName, string msgHandlerAppName)
|
||||
{
|
||||
// hang onto passed in args
|
||||
_name = name;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_chassisAddress = chassisAddress;
|
||||
_killHandlerAppName = killHandlerAppName;
|
||||
_msgHandlerAppName = msgHandlerAppName;
|
||||
_cardList = new List<CardInfo>();
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
|
||||
// hold onto callback
|
||||
_callBack = new HssubNativeMethods.MessageCallbackDelagate(MessageCallback);
|
||||
|
||||
// _chassisHandle gets set in Initialize
|
||||
_chassisHandle = 0;
|
||||
|
||||
// these get initialized in LoadMessageApp()
|
||||
_hssubAppInit = 0;
|
||||
_hssubSubSystemApp = 0;
|
||||
_hssubSubSystemAppSync = 0;
|
||||
_hssubCloseAppSync = 0;
|
||||
_hssubKillApp = 0;
|
||||
|
||||
// this is for card handles, it gets set in the MessageCallback() and passed over to the card object
|
||||
_hsiHandle = 0;
|
||||
|
||||
// hold onto the card objects
|
||||
_hssCardNameMap = new SortedDictionary<string, CommFpgaHssubCardTs>();
|
||||
_hssCardHandleMap = new SortedDictionary<int, CommFpgaHssubCardTs>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="cardInfo"></param>
|
||||
public void AddCard(CardInfo cardInfo)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_cardList.Add(cardInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a FPGA HSS TS called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object's resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
public void Initialize(string fpga)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
InitChassis();
|
||||
|
||||
// init each card
|
||||
for (int i = 0; i < _cardList.Count; i++)
|
||||
{
|
||||
CreateCard(_cardList[i].cardName, _cardList[i].cardAddress, _cardList[i].startingOffset, _cardList[i].cardFirmwareFile, _cardList[i].memMap);
|
||||
}
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
short testResults = -1;
|
||||
|
||||
StringBuilder errorStrTemp = new StringBuilder(512);
|
||||
|
||||
int ret = HssubNativeMethods.terHss_self_test(_chassisHandle, ref testResults, errorStrTemp);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_self_test returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
else if (testResults != 0)
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Fail;
|
||||
throw new Exception("HSSub Self Test returned an error: " + testResults.ToString() + ": " + errorStrTemp.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Pass;
|
||||
}
|
||||
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <returns></returns>
|
||||
public uint Read(string fpgaName, uint address)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
return _hssCardNameMap[fpgaName].Read(fpgaName, address);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_hssCardNameMap[fpgaName].ReadBlock(fpgaName, address, numberOfWordsToRead, shallWeIncrementAddress, ref dataRead);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
int ret = HssubNativeMethods.terHss_close(_chassisHandle);
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="value"></param>
|
||||
public void Write(string fpgaName, uint address, uint value)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_hssCardNameMap[fpgaName].Write(fpgaName, address, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToWrite"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_hssCardNameMap[fpgaName].WriteBlock(fpgaName, address, numberOfWordsToWrite, data, shallWeIncrementAddress);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads firmware
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
Initialize(fpgaName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaHssubCardSsFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaHssubChassisTsFactory")]
|
||||
public class CommFpgaHssubChassisTsFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaHssubChassisTsFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaHssubChassisTsFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaHssubChassisTs(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
else
|
||||
return new CommFpgaHssubChassisTs(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGA.HssubChassisTs</AssemblyName>
|
||||
<Product>FPGA Hssub Chassis Ts implementation</Product>
|
||||
<Description>FPGA Hssub Chassis Ts implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FpgaSim\FpgaSim.csproj" />
|
||||
<ProjectReference Include="..\HssubCardTs\HssubCardTs.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
403
Source/TSRealLib/HAL/Implementations/FPGA/FpgaSim/CommFpgaSim.cs
Normal file
403
Source/TSRealLib/HAL/Implementations/FPGA/FpgaSim/CommFpgaSim.cs
Normal file
@@ -0,0 +1,403 @@
|
||||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A simulated fpga
|
||||
/// </summary>
|
||||
public class CommFpgaSim : IFpgaComm
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private Dictionary<uint, uint> _registers;
|
||||
private static object _syncObj = new Object();
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
/// <summary>
|
||||
/// The finalizer.
|
||||
/// </summary>
|
||||
~CommFpgaSim()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommFpgaSim factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaSim(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
_registers = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public CommFpgaSim(string name)
|
||||
{
|
||||
_name = name;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
_registers = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a FPGA Sim called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
public void Initialize(string fpga)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_state = State.Ready;
|
||||
_registers = new Dictionary<uint, uint>();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
return _selfTestResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <returns></returns>
|
||||
public uint Read(string fpgaName, uint address)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
|
||||
if (_registers.ContainsKey(address) == true)
|
||||
{
|
||||
return _registers[address];
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0xffffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
|
||||
for (int i = 0; i < numberOfWordsToRead; i++)
|
||||
{
|
||||
dataRead[i] = Read(fpgaName, address);
|
||||
|
||||
if (shallWeIncrementAddress == true)
|
||||
{
|
||||
address += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="value"></param>
|
||||
public void Write(string fpgaName, uint address, uint value)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
|
||||
_registers[address] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToWrite"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
|
||||
for (int i = 0; i < numberOfWordsToWrite; i++)
|
||||
{
|
||||
uint dataItem = data[i];
|
||||
|
||||
Write(fpgaName, address, dataItem);
|
||||
|
||||
if (shallWeIncrementAddress == true)
|
||||
{
|
||||
address += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads firmware
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
Initialize(fpgaName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaSimFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaSimFactory")]
|
||||
public class CommFpgaSimFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaSimFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaSimFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGASim</AssemblyName>
|
||||
<Product>FPGA SIM implementation</Product>
|
||||
<Description>FPGA SIM implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,308 @@
|
||||
// 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 FpgaMeasurementInstrumentsLib;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that implements the Teradyne HSS Sub System Card
|
||||
/// </summary>
|
||||
public class CommFpgaHssubCardSs : IFpgaComm
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private readonly string _name;
|
||||
private readonly string _cardAddress;
|
||||
private readonly uint _startingOffset;
|
||||
private readonly string _firmware;
|
||||
private readonly string _memMap;
|
||||
private uint _cardHandle;
|
||||
private SelfTestResult _selfTestResult;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public string DetailedStatus => throw new NotImplementedException();
|
||||
|
||||
public bool DisplayEnabled { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public bool FrontPanelEnabled { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public SelfTestResult SelfTestResult => throw new NotImplementedException();
|
||||
|
||||
public State Status => throw new NotImplementedException();
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
int ret = HssubNativeMethods.terHsi_close(_cardHandle);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void LoadFirmware()
|
||||
{
|
||||
ushort customerId = 0;
|
||||
ushort appId = 0;
|
||||
uint revId = 0;
|
||||
|
||||
int ret = HssubNativeMethods.terHsi_Firmware_Load(_cardHandle, HssubNativeMethods.TERHSI_FPGA_TEST_DEFINED, _firmware, ref customerId, ref appId, ref revId);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilSs.BuildErrorString(_cardHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHsi_Firmware_Load() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommFpgaHssubCardSs factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaHssubCardSs(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_cardAddress = _configuration.GetConfigurationValue("CommFpgaHssubCardSs", "CardAddress", "127.0.0.1");
|
||||
_startingOffset = _configuration.GetConfigurationValue<uint>("CommFpgaHssubCardSs", "StartingOffset", 0);
|
||||
_firmware = _configuration.GetConfigurationValue("CommFpgaHssubCardSs", "Firmware", "");
|
||||
_memMap = _configuration.GetConfigurationValue("CommFpgaHssubCardSs", "MemMap", "");
|
||||
_cardHandle = 0;
|
||||
|
||||
LoadFirmware();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="cardAddress"></param>
|
||||
/// <param name="startingOffset"></param>
|
||||
/// <param name="firmware"></param>
|
||||
/// <param name="memMap"></param>
|
||||
public CommFpgaHssubCardSs(string name, string cardAddress, int startingOffset, string firmware, string memMap)
|
||||
{
|
||||
// hold onto args
|
||||
_name = name;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_cardAddress = cardAddress;
|
||||
_startingOffset = (uint)startingOffset;
|
||||
_firmware = firmware;
|
||||
_memMap = memMap;
|
||||
_cardHandle = 0;
|
||||
|
||||
LoadFirmware();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer.
|
||||
/// </summary>
|
||||
~CommFpgaHssubCardSs()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetMemMap()
|
||||
{
|
||||
return _memMap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads FPGA value from address
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public uint Read(string fpgaName, uint address)
|
||||
{
|
||||
uint dataRead = 0;
|
||||
int ret = HssubNativeMethods.terHsi_LB_Read32(_cardHandle, _startingOffset + address, ref dataRead);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilSs.BuildErrorString(_cardHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHsi_LB_Read32() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
return dataRead;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads block
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes value to fpga address
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="value"></param>
|
||||
public void Write(string fpgaName, uint address, uint value)
|
||||
{
|
||||
int ret = HssubNativeMethods.terHsi_LB_Write32(_cardHandle, _startingOffset + address, value);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilSs.BuildErrorString(_cardHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHsi_LB_Write32() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes block
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToWrite"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
throw new Exception("Not Implemented");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initialize fpga
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void Initialize(string fpgaName)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads firmware
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
Initialize(fpgaName);
|
||||
}
|
||||
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
LoadFirmware();
|
||||
}
|
||||
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
return _selfTestResult;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaHssubCardSsFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaHssubCardSsFactory")]
|
||||
public class CommFpgaHssubCardSsFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaHssubCardSsFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaHssubCardSsFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaHssubCardSs(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
else
|
||||
return new CommFpgaHssubCardSs(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGA.HssubCardSs</AssemblyName>
|
||||
<Product>FPGA Hssub Card Ss implementation</Product>
|
||||
<Description>FPGA Hssub Card Ss implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FpgaSim\FpgaSim.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,561 @@
|
||||
// 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 FpgaMeasurementInstrumentsLib;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that implements the Teradyne HSS Sub System Card with the HSI Library
|
||||
/// </summary>
|
||||
public unsafe class CommFpgaHssubCardSsHsi : IFpgaComm
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private enum Mode
|
||||
{
|
||||
PRIMARY_CONTROL,
|
||||
SECONDARY_CONTROL
|
||||
};
|
||||
|
||||
private readonly string _cardAddress;
|
||||
private readonly uint _startingOffset;
|
||||
private readonly string _cardFirmwareFile;
|
||||
private uint _cardHandle;
|
||||
private static object _syncObj = new Object();
|
||||
private readonly Mode __mode;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer.
|
||||
/// </summary>
|
||||
~CommFpgaHssubCardSsHsi()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void LoadFirmware()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
//ErrorLogger.Instance().Write("begin for " + _cardAddress.ToString(), ErrorLogger.LogLevel.INFO);
|
||||
|
||||
ushort customerId = 0;
|
||||
ushort appId = 0;
|
||||
uint revId = 0;
|
||||
|
||||
int ret = HssubNativeMethods.terHsi_Firmware_Load(_cardHandle, HssubNativeMethods.TERHSI_FPGA_TEST_DEFINED, _cardFirmwareFile, ref customerId, ref appId, ref revId);
|
||||
if ((uint)ret == 0xbffa4442)
|
||||
{
|
||||
// expected, load still seems to work
|
||||
}
|
||||
else if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilSs.BuildErrorString(_cardHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHsi_Firmware_Load() returned an error(" + ret + ")" + ": " + errorStr + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void SelfTest()
|
||||
{
|
||||
// loop through each card and command self test
|
||||
|
||||
/*short testResults = -1;
|
||||
|
||||
StringBuilder errorStrTemp = new StringBuilder(512);
|
||||
|
||||
int ret = HssubNativeMethods.terHss_self_test(_chassisHandle, ref testResults, errorStrTemp);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _chassisLogicalName);
|
||||
|
||||
throw new Exception("terHss_self_test returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
else if (testResults != 0)
|
||||
{
|
||||
throw new Exception("HSSub Self Test returned an error: " + testResults.ToString() + ": " + errorStrTemp.ToString());
|
||||
}*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object's resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing">True = currently disposing, False = not disposing.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
int ret = HssubNativeMethods.terHsi_close(_cardHandle);
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommFpgaHssubCardSsHsi factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaHssubCardSsHsi(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_cardAddress = _configuration.GetConfigurationValue("CommFpgaHssubCardSsHsi", "CardAddress", "127.0.0.1");
|
||||
_startingOffset = _configuration.GetConfigurationValue<uint>("CommFpgaHssubCardSsHsi", "StartingOffset", 0);
|
||||
_cardFirmwareFile = _configuration.GetConfigurationValue("CommFpgaHssubCardSsHsi", "CardFirmwareFile", "");
|
||||
_cardHandle = 0;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
__mode = Mode.PRIMARY_CONTROL;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="cardName"></param>
|
||||
/// <param name="cardAddress"></param>
|
||||
/// <param name="startingOffset"></param>
|
||||
/// <param name="cardFirmwareFile"></param>
|
||||
public CommFpgaHssubCardSsHsi(string name, string cardAddress, uint startingOffset, string cardFirmwareFile)
|
||||
{
|
||||
_name = name;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_cardAddress = cardAddress;
|
||||
_startingOffset = startingOffset;
|
||||
_cardFirmwareFile = cardFirmwareFile;
|
||||
_cardHandle = 0;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
__mode = Mode.PRIMARY_CONTROL;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overloaded constructor for a secondary hsi control. (Firmware load done elsewhere, device reset done elsewhere)
|
||||
/// Using this constructor will allow the hsot access to the HSS, but it will not load firmware or reset the device
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="cardAddress"></param>
|
||||
/// <param name="startingOffset"></param>
|
||||
public CommFpgaHssubCardSsHsi(string name, string cardAddress, uint startingOffset)
|
||||
{
|
||||
_name = name;
|
||||
_cardAddress = cardAddress;
|
||||
_startingOffset = startingOffset;
|
||||
_cardFirmwareFile = null;
|
||||
_cardHandle = 0;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
__mode = Mode.SECONDARY_CONTROL;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a FPGA HSS HSI called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object's resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
Initialize(string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void Initialize(string fpgaName)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
int ret = HssubNativeMethods.terHsi_init(_cardAddress, 0, 0, ref _cardHandle);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilSs.BuildErrorString(0, ret, _name);
|
||||
|
||||
throw new Exception("terHsi_init returned an error(" + ret + ")" + ": " + errorStr + " on card " + _name + " on card " + _name);
|
||||
}
|
||||
|
||||
// reset it and load firmware if this is the primary controller of the HSS
|
||||
if (__mode == Mode.PRIMARY_CONTROL)
|
||||
{
|
||||
Reset();
|
||||
|
||||
LoadFirmware();
|
||||
}
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
return _selfTestResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <returns></returns>
|
||||
public uint Read(string fpgaName, uint address)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint dataRead = 0;
|
||||
int ret = HssubNativeMethods.terHsi_LB_Read32(_cardHandle, _startingOffset + address, ref dataRead);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilSs.BuildErrorString(_cardHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHsi_LB_Read32() returned an error(" + ret + ")" + ": " + errorStr + " on card " + _name);
|
||||
}
|
||||
|
||||
return dataRead;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
int ret = HssubNativeMethods.terHsi_reset(_cardHandle);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilSs.BuildErrorString(_cardHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHsi_reset() returned an error(" + ret + ")" + ": " + errorStr + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
string errorMsg = "";
|
||||
bool wasThereAnError = false;
|
||||
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// reset it if this is the primary controller of the HSS
|
||||
if (__mode == Mode.PRIMARY_CONTROL)
|
||||
{
|
||||
ret = HssubNativeMethods.terHsi_reset(_cardHandle);
|
||||
if (ret != 0)
|
||||
{
|
||||
wasThereAnError = true;
|
||||
errorMsg += "terHsi_reset returned error code: " + ret.ToString() + ". ";
|
||||
}
|
||||
}
|
||||
|
||||
ret = HssubNativeMethods.terHsi_close(_cardHandle);
|
||||
if (ret != 0)
|
||||
{
|
||||
wasThereAnError = true;
|
||||
errorMsg += "terHsi_close returned error code: " + ret.ToString();
|
||||
}
|
||||
_state = State.Uninitialized;
|
||||
|
||||
if (wasThereAnError == true)
|
||||
{
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="value"></param>
|
||||
public void Write(string fpgaName, uint address, uint value)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
int ret = HssubNativeMethods.terHsi_LB_Write32(_cardHandle, _startingOffset + address, value);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilSs.BuildErrorString(_cardHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHsi_LB_Write32() returned an error(" + ret + ")" + ": " + errorStr + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToWrite"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (shallWeIncrementAddress == false)
|
||||
{
|
||||
throw new Exception("terHsi_LB_WriteBlock32() does not support shallWeIncrementAddress = false command on card " + _name);
|
||||
}
|
||||
else
|
||||
{
|
||||
int ret = HssubNativeMethods.terHsi_LB_WriteBlock32(_cardHandle, _startingOffset + address, numberOfWordsToWrite, data);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilSs.BuildErrorString(_cardHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHsi_LB_WriteBlock32() returned an error(" + ret + ")" + ": " + errorStr + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads firmware
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
LoadFirmware();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaHssubCardSsHsiFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaHssubCardSsHsiFactory")]
|
||||
public class CommFpgaHssubCardSsHsiFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaHssubCardSsHsiFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaHssubCardSsHsiFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaHssubCardSsHsi(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
else
|
||||
return new CommFpgaHssubCardSsHsi(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGA.HssubCardSsHsi</AssemblyName>
|
||||
<Product>FPGA HssubCardSsHsi implementation</Product>
|
||||
<Description>FPGA HsSub Card SS HSI implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FpgaSim\FpgaSim.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,441 @@
|
||||
// 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 FpgaMeasurementInstrumentsLib;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that implements the Teradyne HSS Test Station Card
|
||||
/// </summary>
|
||||
public class CommFpgaHssubCardTs : IFpgaComm
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private string _name;
|
||||
private readonly string _cardAddress;
|
||||
private readonly int _startingOffset;
|
||||
private readonly string _firmware;
|
||||
private readonly uint _chassisHandle;
|
||||
private readonly int _hssubAppSyncHandle;
|
||||
private readonly int _hssubAppHandle;
|
||||
private readonly string _memMap;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private int _cardHandle;
|
||||
|
||||
private int _latestLbAddress;
|
||||
private int _latestLbData;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public string DetailedStatus => throw new NotImplementedException();
|
||||
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
|
||||
public string Name { get => _name; set { _name = value; } }
|
||||
|
||||
public SelfTestResult SelfTestResult => PerformSelfTest();
|
||||
|
||||
public State Status => State.Ready;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
HssubNativeMethods.terHss_close(_chassisHandle);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
int ret = HssubNativeMethods.terHss_Application_SendMessage(_chassisHandle, _hssubAppHandle, HssubNativeMethods.MESSAGE_CONTEXT_INIT_INSTRUMENT, _cardAddress.Length, Encoding.ASCII.GetBytes(_cardAddress), HssubNativeMethods.TERHSS_TIMEOUT_60SEC);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_SendMessage() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
LoadFirmware();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void LoadFirmware()
|
||||
{
|
||||
// send the file to the subsystem
|
||||
int ret = HssubNativeMethods.terHss_Subsystem_SendFile(_chassisHandle, _firmware, "c:\\temp\\FPGAFile.hsi", HssubNativeMethods.TERHSS_OPTION_ALLOW_OVERWRITE);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_SubSyste_SendFile() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
// load the instrument
|
||||
ret = HssubNativeMethods.terHss_Application_SendMessage(_chassisHandle, _hssubAppHandle, HssubNativeMethods.MESSAGE_CONTEXT_LOAD_INSTRUMENT, 4, BitConverter.GetBytes(_cardHandle), HssubNativeMethods.TERHSS_TIMEOUT_60SEC);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_SendMessage() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
// wait for the callback event
|
||||
HssUtilTs.WaitForSync(_chassisHandle, _hssubAppSyncHandle, _name);
|
||||
|
||||
// delete the file
|
||||
ret = HssubNativeMethods.terHss_Subsystem_DeleteFile(_chassisHandle, "c:\\temp\\FPGAFile.hsi", HssubNativeMethods.TERHSS_OPTION_NONE);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_SubSyste_DeleteFile() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommFpgaHssubCardTs factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaHssubCardTs(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_cardAddress = _configuration.GetConfigurationValue("CommFpgaHssubCardTs", "CardAddress", "127.0.0.1");
|
||||
_startingOffset = _configuration.GetConfigurationValue("CommFpgaHssubCardTs", "StartingOffset", 0);
|
||||
_firmware = _configuration.GetConfigurationValue("CommFpgaHssubCardTs", "Firmware", "");
|
||||
_chassisHandle = _configuration.GetConfigurationValue<uint>("CommFpgaHssubCardTs", "ChassisHandle", 0);
|
||||
_hssubAppHandle = _configuration.GetConfigurationValue("CommFpgaHssubCardTs", "HssubAppHandle", 0);
|
||||
_hssubAppSyncHandle = _configuration.GetConfigurationValue("CommFpgaHssubCardTs", "HssubAppSyncHandle", 0);
|
||||
_memMap = _configuration.GetConfigurationValue("CommFpgaHssubCardTs", "MemMap", "");
|
||||
_cardHandle = 0;
|
||||
|
||||
// this gets set by the HssubChassis when a LB Read callback arrives
|
||||
_latestLbAddress = -1;
|
||||
_latestLbData = -1;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="cardAddress"></param>
|
||||
/// <param name="startingOffset"></param>
|
||||
/// <param name="firmware"></param>
|
||||
/// <param name="chassisHandle"></param>
|
||||
/// <param name="hssubAppHandle"></param>
|
||||
/// <param name="hssubAppSyncHandle"></param>
|
||||
public CommFpgaHssubCardTs(string name, string cardAddress, int startingOffset, string firmware, uint chassisHandle, int hssubAppHandle, int hssubAppSyncHandle, string memMap)
|
||||
{
|
||||
// hold onto args
|
||||
_name = name;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_cardAddress = cardAddress;
|
||||
_startingOffset = startingOffset;
|
||||
_firmware = firmware;
|
||||
_chassisHandle = chassisHandle;
|
||||
_hssubAppHandle = hssubAppHandle;
|
||||
_hssubAppSyncHandle = hssubAppSyncHandle;
|
||||
_memMap = memMap;
|
||||
|
||||
// this gets set by the HssubChassis in SetHandle()
|
||||
_cardHandle = 0;
|
||||
|
||||
// this gets set by the HssubChassis when a LB Read callback arrives
|
||||
_latestLbAddress = -1;
|
||||
_latestLbData = -1;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer.
|
||||
/// </summary>
|
||||
~CommFpgaHssubCardTs()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetMemMap()
|
||||
{
|
||||
return _memMap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
public uint Read(string fpgaName, uint address)
|
||||
{
|
||||
// populate the structure
|
||||
HssUtilTs.LocalBusParams lbParams;
|
||||
lbParams.cardHandle = _cardHandle;
|
||||
lbParams.address = (int)(_startingOffset + address);
|
||||
lbParams.data = 0;
|
||||
|
||||
// get the byte array
|
||||
byte[] dataToSend = HssUtilTs.LocalBusParmsToByteArray(lbParams);
|
||||
|
||||
// reset the callback data items
|
||||
_latestLbAddress = -1;
|
||||
_latestLbData = -1;
|
||||
|
||||
// send the message
|
||||
int ret = HssubNativeMethods.terHss_Application_SendMessage(_chassisHandle, _hssubAppHandle, HssubNativeMethods.MESSAGE_CONTEXT_LB_READ32, dataToSend.Length, dataToSend, HssubNativeMethods.TERHSS_TIMEOUT_10SEC);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_SendMessage() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
// wait for the callback event
|
||||
HssUtilTs.WaitForSync(_chassisHandle, _hssubAppSyncHandle, _name);
|
||||
|
||||
// confirm the address is what we requested (Set in SetLocalBusReadData())
|
||||
if (_latestLbAddress != lbParams.address)
|
||||
{
|
||||
throw new Exception("Received address: " + _latestLbAddress.ToString("X8") + " Expected: " + lbParams.address.ToString("X8"));
|
||||
}
|
||||
|
||||
return (uint)_latestLbData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
throw new Exception("Not Implemented");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="cardHandle"></param>
|
||||
public void SetHandle(int cardHandle)
|
||||
{
|
||||
// this gets set in
|
||||
_cardHandle = cardHandle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="data"></param>
|
||||
public void SetLocalBusRxData(int address, int data)
|
||||
{
|
||||
_latestLbAddress = address;
|
||||
_latestLbData = data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="value"></param>
|
||||
public void Write(string fpgaName, uint address, uint value)
|
||||
{
|
||||
|
||||
// populate the structure
|
||||
HssUtilTs.LocalBusParams lbParams;
|
||||
lbParams.cardHandle = _cardHandle;
|
||||
lbParams.address = (int)(_startingOffset + address);
|
||||
lbParams.data = (int)value;
|
||||
|
||||
// get the byte array
|
||||
byte[] dataToSend = HssUtilTs.LocalBusParmsToByteArray(lbParams);
|
||||
|
||||
// reset the callback data items
|
||||
_latestLbAddress = -1;
|
||||
_latestLbData = -1;
|
||||
|
||||
// send the message
|
||||
int ret = HssubNativeMethods.terHss_Application_SendMessage(_chassisHandle, _hssubAppHandle, HssubNativeMethods.MESSAGE_CONTEXT_LB_WRITE32, dataToSend.Length, dataToSend, HssubNativeMethods.TERHSS_TIMEOUT_10SEC);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(_chassisHandle, ret, _name);
|
||||
|
||||
throw new Exception("terHss_Application_SendMessage() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
|
||||
// wait for the callback event
|
||||
HssUtilTs.WaitForSync(_chassisHandle, _hssubAppSyncHandle, _name);
|
||||
|
||||
// confirm the address is what we requested (Set in SetLocalBusReadData())
|
||||
/*if (_latestLbAddress != lbParams.address)
|
||||
{
|
||||
throw new Exception("Received address: " + _latestLbAddress.ToString("X8") + " Expected: " + lbParams.address.ToString("X8"));
|
||||
}*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToWrite"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void Initialize(string fpgaName)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
LoadFirmware();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
return _selfTestResult;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaHssubCardTsFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaHssubCardTsFactory")]
|
||||
public class CommFpgaHssubCardTsFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaHssubCardTsFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaHssubCardTsFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaHssubCardTs(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
else
|
||||
return new CommFpgaHssubCardTs(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGA.HssubCardTs</AssemblyName>
|
||||
<Product>FPGA HssubCardTs implementation</Product>
|
||||
<Description>FPGA Hssub Card Ts implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FpgaSim\FpgaSim.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,576 @@
|
||||
// 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.IO.Ports;
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A class the provides an interface for read/write to registers on an FPGA that implement PC Node communication
|
||||
/// </summary>
|
||||
public class CommFpgaPcNode2x : IFpgaComm, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private SerialPort _serialPort;
|
||||
private readonly uint _pcNodeAddress;
|
||||
private byte[] _readBuf;
|
||||
private static object _syncObj = new Object();
|
||||
private uint _delayBeforeReadMs;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommFpgaPcNode2x()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a command in the PC node format
|
||||
/// </summary>
|
||||
/// <param name="address">The address to write to</param>
|
||||
/// <param name="data">The data to write</param>
|
||||
/// <param name="isForRead">True is the command is to perform a read, false to perform a write</param>
|
||||
/// <returns>The formatted command</returns>
|
||||
private byte[] BuildCommand(uint address, uint data, bool isForRead)
|
||||
{
|
||||
byte[] command = new byte[9];
|
||||
|
||||
byte type = 0;
|
||||
|
||||
// 2 bit shift per the spec, regardless of its a read or write
|
||||
address = address >> 2;
|
||||
|
||||
if (isForRead == true)
|
||||
{
|
||||
type = 0xf1;
|
||||
|
||||
// 2 bit shift per the spec for the read (this would be the PC node address)
|
||||
data = data >> 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = 0xf0;
|
||||
}
|
||||
|
||||
command[0] = type;
|
||||
byte[] addressBytes = BitConverter.GetBytes(address);
|
||||
Array.Copy(addressBytes, 0, command, 1, addressBytes.Length);
|
||||
|
||||
byte[] dataBytes = BitConverter.GetBytes(data);
|
||||
Array.Copy(dataBytes, 0, command, 5, dataBytes.Length);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the serial port until it is empty
|
||||
/// </summary>
|
||||
private void ClearBuffer()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
bool isClearComplete = false;
|
||||
|
||||
while (isClearComplete == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
int numBytesRead = _serialPort.Read(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
if (numBytesRead < _readBuf.Length)
|
||||
{
|
||||
isClearComplete = true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//expected if buffer is already cleared
|
||||
isClearComplete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_serialPort.Dispose();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommFpgaPcNode2x factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaPcNode2x(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_pcNodeAddress = _configuration.GetConfigurationValue<uint>("CommFpgaPcNode2x", "PCNodeAddress", 0);
|
||||
|
||||
string comPortName = _configuration.GetConfigurationValue("CommFpgaPcNode2x", "ComPortName", "COM1");
|
||||
int baudRate = _configuration.GetConfigurationValue("CommFpgaPcNode2x", "BaudRate", 115200);
|
||||
Parity parity = _configuration.GetConfigurationValue("CommFpgaPcNode2x", "Parity", Parity.None);
|
||||
int dataBits = _configuration.GetConfigurationValue("CommFpgaPcNode2x", "DataBits", 8);
|
||||
StopBits stopBits = _configuration.GetConfigurationValue("CommFpgaPcNode2x", "StopBits", StopBits.None);
|
||||
|
||||
_delayBeforeReadMs = _configuration.GetConfigurationValue<uint>("CommFpgaPcNode2x", "DelayBeforeReadMs", 0);
|
||||
_pcNodeAddress = _configuration.GetConfigurationValue<uint>("CommFpgaPcNode2x", "PcNodeAddress", 0);
|
||||
|
||||
const int READ_BUF_SIZE = 100;
|
||||
|
||||
try
|
||||
{
|
||||
_serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits)
|
||||
{
|
||||
ReadTimeout = 100
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex);
|
||||
|
||||
if (_serialPort.IsOpen == true)
|
||||
{
|
||||
_serialPort.Close();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
_readBuf = new byte[READ_BUF_SIZE];
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The constructor which opens up a serial port
|
||||
/// </summary>
|
||||
/// <param name="commFpgaPcNodeAddress">The address of the PC node</param>
|
||||
/// <param name="comPortName">The port name. "Com1' for example</param>
|
||||
/// <param name="delayBeforeReadMs">The num of ms to wait before a read</param>
|
||||
/// <param name="baudRate">The baud rate</param>
|
||||
/// <param name="parity">The parity</param>
|
||||
/// <param name="dataBits">Number of data bits</param>
|
||||
/// <param name="stopBits">Number of Stop Bits</param>
|
||||
public CommFpgaPcNode2x(string name, uint pcNodeAddress, string comPortName, uint delayBeforeReadMs, int baudRate = 115200, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
|
||||
{
|
||||
const int READ_BUF_SIZE = 100;
|
||||
|
||||
try
|
||||
{
|
||||
_name = name;
|
||||
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
_serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits);
|
||||
|
||||
_serialPort.ReadTimeout = 100;
|
||||
|
||||
_delayBeforeReadMs = delayBeforeReadMs;
|
||||
|
||||
_pcNodeAddress = pcNodeAddress;
|
||||
|
||||
_readBuf = new byte[READ_BUF_SIZE];
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_serialPort.IsOpen == true)
|
||||
{
|
||||
_serialPort.Close();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a FPGA PC Node called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
Initialize(string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
public void Initialize(string fpga)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
if (_serialPort.IsOpen == false)
|
||||
{
|
||||
_serialPort.Open();
|
||||
}
|
||||
|
||||
ClearBuffer();
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
return _selfTestResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <returns></returns>
|
||||
public uint Read(string fpga, uint address)
|
||||
{
|
||||
const int NUM_BYTES_EXPECTED_ON_READ = 9;
|
||||
|
||||
int numBytesRead = 0;
|
||||
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
byte[] command = BuildCommand(address, _pcNodeAddress, true);
|
||||
|
||||
for (uint numTries = 0; numTries < 2; numTries++)
|
||||
{
|
||||
_serialPort.Write(command, 0, command.Length);
|
||||
|
||||
Array.Clear(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
Thread.Sleep((int)_delayBeforeReadMs);
|
||||
|
||||
numBytesRead = _serialPort.Read(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
int numBytesExpectedToRead = NUM_BYTES_EXPECTED_ON_READ;
|
||||
|
||||
if (numBytesRead != numBytesExpectedToRead)
|
||||
{
|
||||
//put out diagnostic
|
||||
byte[] errorDiag = new byte[numBytesRead];
|
||||
|
||||
Array.Copy(_readBuf, errorDiag, numBytesRead);
|
||||
|
||||
string errMessage = Util.ByteArrayToHexString(errorDiag);
|
||||
|
||||
//ErrorLogger.Instance().Write("Read got wrong size. expected to read: " + numBytesExpectedToRead.ToString() + ", read: " + numBytesRead.ToString() + " The data received is: " + errMessage);
|
||||
|
||||
if (numTries != 0)
|
||||
{
|
||||
//second time - not a good read
|
||||
throw new Exception("expected to read: " + numBytesExpectedToRead.ToString() + ", read: " + numBytesRead.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;//continue processing
|
||||
}
|
||||
}
|
||||
|
||||
// Grab the last 4 bytes
|
||||
uint data = BitConverter.ToUInt32(_readBuf, numBytesRead - 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new Exception("Not Implemented");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
ClearBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_serialPort.Dispose();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="data"></param>
|
||||
public void Write(string fpga, uint address, uint data)
|
||||
{
|
||||
byte[] command = BuildCommand(address, data, false);
|
||||
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_serialPort.Write(command, 0, command.Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToWrite"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new Exception("Not Implemented");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads firmware
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
Initialize(fpgaName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaPcNode2xFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaPcNode2xFactory")]
|
||||
public class CommFpgaPcNode2xFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaPcNode2xFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaPcNode2xFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaPcNode2x(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
else
|
||||
return new CommFpgaPcNode2x(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGA.PcNode2x</AssemblyName>
|
||||
<Product>FPGA PcNode 2x implementation</Product>
|
||||
<Description>FPGA PcNode 2x implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FpgaSim\FpgaSim.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,653 @@
|
||||
// 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.IO.Ports;
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A class the provides an interface for read/write to registers on an FPGA that implement PC Node communication
|
||||
/// </summary>
|
||||
public class CommFpgaPcNode3x : IFpgaComm, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private string _name;
|
||||
private SerialPort _serialPort;
|
||||
private readonly uint _pcNodeAddress;
|
||||
private byte[] _readBuf;
|
||||
private static object _syncObj = new Object();
|
||||
private readonly bool _areUsingStartFrameDelim;
|
||||
private readonly ushort _startFrameDelim;
|
||||
private readonly uint _delayBeforeReadMs;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommFpgaPcNode3x()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a command in the PC node format
|
||||
/// </summary>
|
||||
/// <param name="address">The address to write to</param>
|
||||
/// <param name="data">The data to write</param>
|
||||
/// <param name="isForRead">True is the command is to perform a read, false to perform a write</param>
|
||||
/// <returns>The formatted command</returns>
|
||||
private byte[] BuildCommand(uint address, uint data, bool isForRead)
|
||||
{
|
||||
/*
|
||||
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Byte En | XGRID Data / Return Address | T | R | Upper 32 - Bit XGRID Address | R | R |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
Bit 35 T = TType(Transmission Type) 0 = Write 1 = Read
|
||||
R = Reserved
|
||||
*/
|
||||
const ulong READ_OP_CODE_MASK = 0x800000000;
|
||||
|
||||
// the data (PC NODE ADDRESS) is actually only 30 bits when reading
|
||||
if (isForRead == true)
|
||||
{
|
||||
data = data >> 2;
|
||||
}
|
||||
|
||||
// The address is always 30 bits
|
||||
address = address >> 2;
|
||||
|
||||
// shift the data into place
|
||||
ulong commandLow = data;
|
||||
commandLow = commandLow << 34;
|
||||
|
||||
// or in the address and put it in its place
|
||||
commandLow = commandLow | address;
|
||||
commandLow = commandLow << 2;
|
||||
|
||||
// set the op code bit
|
||||
if (isForRead == true)
|
||||
{
|
||||
commandLow = commandLow | READ_OP_CODE_MASK;
|
||||
}
|
||||
|
||||
// set the byte enables (All high by default)
|
||||
byte commandHigh = 0xF0;
|
||||
|
||||
// 4 high bits of data go to 4 low bits of commandHigh
|
||||
data = data >> 28;
|
||||
commandHigh = (byte)(commandHigh | data);
|
||||
|
||||
// place bytes in correct order and return
|
||||
byte[] commandLowBytes = BitConverter.GetBytes(commandLow);
|
||||
|
||||
if (_areUsingStartFrameDelim == true)
|
||||
{
|
||||
byte[] finalCommand = new byte[11];
|
||||
|
||||
byte[] frameDelimBytes = BitConverter.GetBytes(_startFrameDelim);
|
||||
|
||||
Array.Copy(frameDelimBytes, finalCommand, frameDelimBytes.Length);
|
||||
|
||||
Array.Copy(commandLowBytes, 0, finalCommand, frameDelimBytes.Length, commandLowBytes.Length);
|
||||
|
||||
finalCommand[10] = commandHigh;
|
||||
|
||||
return finalCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] finalCommand = new byte[9];
|
||||
|
||||
Array.Copy(commandLowBytes, finalCommand, commandLowBytes.Length);
|
||||
|
||||
finalCommand[8] = commandHigh;
|
||||
|
||||
return finalCommand;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads the serial port until it is empty
|
||||
/// </summary>
|
||||
private void ClearBuffer()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
bool isClearComplete = false;
|
||||
|
||||
while (isClearComplete == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
int numBytesRead = _serialPort.Read(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
if (numBytesRead < _readBuf.Length)
|
||||
{
|
||||
isClearComplete = true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//expected if buffer is already cleared
|
||||
isClearComplete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_serialPort.Dispose();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommFpgaPcNode2x factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommFpgaPcNode3x(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_pcNodeAddress = _configuration.GetConfigurationValue<uint>("CommFpgaPcNode3x", "PCNodeAddress", 0);
|
||||
|
||||
string comPortName = _configuration.GetConfigurationValue("CommFpgaPcNode3x", "ComPortName", "COM1");
|
||||
int baudRate = _configuration.GetConfigurationValue("CommFpgaPcNode3x", "BaudRate", 115200);
|
||||
Parity parity = _configuration.GetConfigurationValue("CommFpgaPcNode3x", "Parity", Parity.None);
|
||||
int dataBits = _configuration.GetConfigurationValue("CommFpgaPcNode3x", "DataBits", 8);
|
||||
StopBits stopBits = _configuration.GetConfigurationValue("CommFpgaPcNode3x", "StopBits", StopBits.None);
|
||||
|
||||
_delayBeforeReadMs = _configuration.GetConfigurationValue<uint>("CommFpgaPcNode3x", "DelayBeforeReadMs", 0);
|
||||
_pcNodeAddress = _configuration.GetConfigurationValue<uint>("CommFpgaPcNode3x", "PcNodeAddress", 0);
|
||||
_startFrameDelim = _configuration.GetConfigurationValue<ushort>("CommFpgaPcNode3x", "StartFrameDelim", 0);
|
||||
_areUsingStartFrameDelim = _configuration.GetConfigurationValue("CommFpgaPcNode3x", "AreUsingStartFrameDelim", false);
|
||||
|
||||
const int READ_BUF_SIZE = 100;
|
||||
|
||||
try
|
||||
{
|
||||
_serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits)
|
||||
{
|
||||
ReadTimeout = 100
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex);
|
||||
|
||||
if (_serialPort.IsOpen == true)
|
||||
{
|
||||
_serialPort.Close();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
_readBuf = new byte[READ_BUF_SIZE];
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor which opens up a serial port
|
||||
/// </summary>
|
||||
/// <param name="commFpgaPcNodeAddress">The address of the PC node</param>
|
||||
/// <param name="comPortName">The port name. "Com1' for example</param>
|
||||
/// <param name="delayBeforeReadMs">The num of ms to wait before a read</param>
|
||||
/// <param name="startFrameDelim">0 for no delim </param>
|
||||
/// <param name="baudRate">The baud rate</param>
|
||||
/// <param name="parity">The parity</param>
|
||||
/// <param name="dataBits">Number of data bits</param>
|
||||
/// <param name="stopBits">Number of Stop Bits</param>
|
||||
public CommFpgaPcNode3x(string name, uint pcNodeAddress, string comPortName, uint delayBeforeReadMs, ushort startFrameDelim, int baudRate = 115200, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
|
||||
{
|
||||
const int READ_BUF_SIZE = 100;
|
||||
|
||||
try
|
||||
{
|
||||
_name = name;
|
||||
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
_serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits);
|
||||
|
||||
_serialPort.ReadTimeout = 100;
|
||||
|
||||
_delayBeforeReadMs = delayBeforeReadMs;
|
||||
|
||||
_pcNodeAddress = pcNodeAddress;
|
||||
|
||||
_readBuf = new byte[READ_BUF_SIZE];
|
||||
|
||||
_startFrameDelim = startFrameDelim;
|
||||
|
||||
_areUsingStartFrameDelim = false;
|
||||
|
||||
if (startFrameDelim != 0)
|
||||
{
|
||||
_areUsingStartFrameDelim = true;
|
||||
}
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_serialPort != null && _serialPort.IsOpen == true)
|
||||
{
|
||||
_serialPort.Close();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a CommFpgaPcNode3x called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
public void Initialize(string fpga)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
if (_serialPort.IsOpen == false)
|
||||
{
|
||||
_serialPort.Open();
|
||||
}
|
||||
|
||||
ClearBuffer();
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on card " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
return _selfTestResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <returns></returns>
|
||||
public uint Read(string fpga, uint address)
|
||||
{
|
||||
const int NUM_BYTES_EXPECTED_ON_READ = 9;
|
||||
|
||||
/*
|
||||
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Byte En | XGRID Data / Return Address | T | R | Upper 32 - Bit XGRID Address | R | R |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
Bit 35 T = TType(Transmission Type) 0 = Write 1 = Read
|
||||
R = Reserved
|
||||
*/
|
||||
int numBytesRead = 0;
|
||||
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
byte[] command = BuildCommand(address, _pcNodeAddress, true);
|
||||
|
||||
for (uint numTries = 0; numTries < 2; numTries++)
|
||||
{
|
||||
_serialPort.Write(command, 0, command.Length);
|
||||
|
||||
Array.Clear(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
Thread.Sleep((int)_delayBeforeReadMs);
|
||||
|
||||
numBytesRead = _serialPort.Read(_readBuf, 0, _readBuf.Length);
|
||||
|
||||
int numBytesExpectedToRead = NUM_BYTES_EXPECTED_ON_READ;
|
||||
|
||||
if (_areUsingStartFrameDelim == true)
|
||||
{
|
||||
// plus 2 for the delim
|
||||
numBytesExpectedToRead += 2;
|
||||
}
|
||||
|
||||
if (numBytesRead != numBytesExpectedToRead)
|
||||
{
|
||||
//put out diagnostic
|
||||
byte[] errorDiag = new byte[numBytesRead];
|
||||
|
||||
Array.Copy(_readBuf, errorDiag, numBytesRead);
|
||||
|
||||
string errMessage = Util.ByteArrayToHexString(errorDiag);
|
||||
|
||||
//ErrorLogger.Instance().Write("Read got wrong size. expected to read: " + numBytesExpectedToRead.ToString() + ", read: " + numBytesRead.ToString() + " The data received is: " + errMessage);
|
||||
|
||||
if (numTries != 0)
|
||||
{
|
||||
//second time - not a good read
|
||||
throw new Exception("expected to read: " + numBytesExpectedToRead.ToString() + ", read: " + numBytesRead.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;//continue processing
|
||||
}
|
||||
}
|
||||
|
||||
// Grab the last 5 bytes
|
||||
ulong temp = BitConverter.ToUInt64(_readBuf, numBytesRead - 5);
|
||||
|
||||
// ditch the first 4 bits
|
||||
temp = temp >> 4;
|
||||
|
||||
// clear out everything but the 4 bytes we want
|
||||
temp = temp << 32;
|
||||
temp = temp >> 32;
|
||||
|
||||
// return the next 32 bits
|
||||
uint finalData = (uint)temp;
|
||||
|
||||
return finalData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToRead"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
/// <param name="dataRead"></param>
|
||||
public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new Exception("Not Implemented");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
ClearBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_serialPort.Dispose();
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpga"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="data"></param>
|
||||
public void Write(string fpga, uint address, uint data)
|
||||
{
|
||||
byte[] command = BuildCommand(address, data, false);
|
||||
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
_serialPort.Write(command, 0, command.Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="numberOfWordsToWrite"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="shallWeIncrementAddress"></param>
|
||||
public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress)
|
||||
{
|
||||
// lock up the FPGA resource
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new Exception("Not Implemented");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads firmware
|
||||
/// </summary>
|
||||
/// <param name="fpgaName"></param>
|
||||
public void LoadFirmware(string fpgaName)
|
||||
{
|
||||
Initialize(fpgaName);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// **********************************************************************************************************
|
||||
// CommFpgaPcNode3xFactory.cs
|
||||
// 2/20/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommFpgaPcNode3xFactory")]
|
||||
public class CommFpgaPcNode3xFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommFpgaPcNode3xFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommFpgaPcNode3xFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(IFpgaComm));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommFpgaPcNode3x(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommFpgaSim(name, _configurationManager, _logger);
|
||||
else
|
||||
return new CommFpgaPcNode3x(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.FPGA.PcNode3x</AssemblyName>
|
||||
<Product>FPGA PcNode 3x implementation</Product>
|
||||
<Description>FPGA PcNode 3x implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.FpgaComm.Contracts" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FpgaSim\FpgaSim.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user