// 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.Text; using FpgaMeasurementInstrumentsLib; using NLog; using Raytheon.Common; namespace Raytheon.Instruments { /// /// A class that implements the Teradyne HSS Test Station Card /// 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; private readonly ILogger _logger; 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 /// /// /// /// protected virtual void Dispose(bool disposing) { if (disposing) { HssubNativeMethods.terHss_close(_chassisHandle); } } /// /// /// 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(); } /// /// /// 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 /// /// CommFpgaHssubCardTs factory constructor /// /// /// public CommFpgaHssubCardTs(string deviceName, IConfigurationManager configurationManager) { Name = deviceName; _logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}"); _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("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(); } /// /// /// /// /// /// /// /// /// /// public CommFpgaHssubCardTs(string deviceName, string cardAddress, int startingOffset, string firmware, uint chassisHandle, int hssubAppHandle, int hssubAppSyncHandle, string memMap) { // hold onto args _name = deviceName; _logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}"); _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(); } /// /// The finalizer. /// ~CommFpgaHssubCardTs() { Dispose(false); } /// /// /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// /// /// public string GetMemMap() { return _memMap; } /// /// /// /// 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; } /// /// /// /// /// /// /// public void ReadBlock(string fpgaName, uint address, uint numberOfWordsToRead, bool shallWeIncrementAddress, ref uint[] dataRead) { throw new Exception("Not Implemented"); } /// /// /// /// public void SetHandle(int cardHandle) { // this gets set in _cardHandle = cardHandle; } /// /// /// /// /// public void SetLocalBusRxData(int address, int data) { _latestLbAddress = address; _latestLbData = data; } /// /// /// /// /// /// 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")); }*/ } /// /// /// /// /// /// /// /// public void WriteBlock(string fpgaName, uint address, uint numberOfWordsToWrite, uint[] data, bool shallWeIncrementAddress) { throw new NotImplementedException(); } /// /// /// /// public void Initialize(string fpgaName) { Initialize(); } /// /// /// /// public void LoadFirmware(string fpgaName) { LoadFirmware(); } /// /// /// /// public bool ClearErrors() { return false; } /// /// /// /// /// public SelfTestResult PerformSelfTest() { _selfTestResult = SelfTestResult.Unknown; return _selfTestResult; } /// /// /// public void Reset() { Shutdown(); Initialize(); } /// /// /// public void Shutdown() { Dispose(); } #endregion } }