Big changes

This commit is contained in:
Duc
2025-03-13 12:04:22 -07:00
parent c689fcb7f9
commit ffa9905494
748 changed files with 199255 additions and 3743 deletions

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View 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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>