MX Foundation 4
mil1553_rt_rt.cs
/*****************************************************************************
//
## File:
## mil1553_rt_rt.cs
//
// Copyright (c) MAX Technologies Inc. 1988-2019, All Rights Reserved.
// CONFIDENTIAL AND PROPRIETARY INFORMATION WHICH IS THE
// PROPERTY OF MAX TECHNOLOGIES INC.
//
// This example demonstrates the usage of simple aperiodic transmission
// to transmit a command of type RT-RT and record using BC.
// First RT is RT #5 and second RT is RT #7 for example. (RT5 SA1 -> RT7 SA1)
// Then we do an acquisition to be able to read the status of each RT and also
// the timetags between records.
// We enabled the RT for test purposes but if you have your RTs connected, you
// obviously don't need to.
//
// Hardware requirements:
// - MAXT Flex1553-PCIe or FlexMulti or 500 series carrier with IPM-1553-MRT
//
*****************************************************************************/
#define LOOPBACK
#define LOCAL
using System;
using System.Text;
using System.Runtime.InteropServices;
using static MAXT.MXFoundation.mxf;
namespace mil1553_example
{
public class mil1553_rt_rt
{
const UInt32 NUM_REC_TX = 10; //bit count error of +2 bits
static void Main(string[] args)
{
UInt32 rc;
UInt64 server;
UInt64 bc = 0, rt5 = 0, rt7 = 0, bm = 0;
UInt64 bcBufferTx = 0;
UInt64 bmBufferRx = 0;
UInt64 rt5Buffer = 0, rt7Buffer = 0;
IntPtr recPtr = IntPtr.Zero;
UInt32 txBufferSize;
IntPtr txBuffer = IntPtr.Zero;
var txRec1553 = new MXF_MIL1553_DATAREC();
var msgInfo = new MXF_MIL1553_MSGINFO[1];
UInt32 rxBufferSize = 0;
IntPtr rxBuffer = IntPtr.Zero;
var rxRec1553 = new MXF_MIL1553_DATAREC[1];
UInt64 cmd;
UInt64 rxAcqStatus;
UInt64 msgCount;
UInt64 byteCount;
UInt64 rxRec;
UInt64 address1 = 0, subAddress1 = 0, dir1 = 0, wordCount1 = 0;
UInt64 address2 = 0, subAddress2 = 0, dir2 = 0, wordCount2 = 0;
var errorString = new StringBuilder(200);
// Connects to services and initialize environment
#if (LOCAL)
rc = mxfServerConnect("0.0.0.0", "", "", Convert.ToUInt64(false), out server);
#else
rc = mxfServerConnect("192.168.0.1", "admin", "admin", Convert.ToUInt64(false), out server);
#endif
// Initializes MX Foundation library
if (rc == MAXT_SUCCESS)
{
Console.Write("Starting ...\n");
rc = mxfSystemInit(server);
}
//Gets handle of the first BM
if (rc == MAXT_SUCCESS)
rc = mxfChannelGet(server, MXF_CLASS_MIL1553, MXF_SCLASS_BM_CHANNEL, MXF_MODULE_ALL, 0, out bm);
//Gets handle of the first BC
if (rc == MAXT_SUCCESS)
rc = mxfChannelGet(server, MXF_CLASS_MIL1553, MXF_SCLASS_BC_CHANNEL, MXF_MODULE_ALL, 0, out bc);
// Gets handle of MIL1553 remote terminal 5 channel
if (rc == MAXT_SUCCESS)
rc = mxfChannelGet(server, MXF_CLASS_MIL1553, MXF_SCLASS_RT_CHANNEL, MXF_MODULE_ALL, 5, out rt5);
// Gets handle of MIL1553 remote terminal 7 channel
if (rc == MAXT_SUCCESS)
rc = mxfChannelGet(server, MXF_CLASS_MIL1553, MXF_SCLASS_RT_CHANNEL, MXF_MODULE_ALL, 7, out rt7);
#if LOOPBACK
if (rc == MAXT_SUCCESS)
rc = mxfAttributeUint64Set(bc, KMXF_MIL1553_TX_RX_TEST_LB, VMXF_ENABLE);
#endif
// Allocate enough buffer for at least NUM_REC_TX tx data
if (rc == MAXT_SUCCESS)
{
txBufferSize = (UInt32)(NUM_REC_TX * Marshal.SizeOf(typeof(MXF_MIL1553_DATAREC)));
// Device allocation
rc = mxfTxAperiodicBufferAlloc(bc, MXF_TXAPERIODIC_PRIORITY_LOW, txBufferSize, out bcBufferTx, IntPtr.Zero);
// Host allocation
if (rc == MAXT_SUCCESS)
{
try
{
txBuffer = Marshal.AllocHGlobal((int)txBufferSize);
}
catch (OutOfMemoryException)
{
rc = MAXT_ERROR_MEM;
}
}
// Necessary to enable the RTs
if (rc == MAXT_SUCCESS)
rc = mxfTxPeriodicUpdateMsgBufferAlloc(rt5, 0, txBufferSize, out rt5Buffer, IntPtr.Zero); // RT buffer for RT5 SA1 TX
if (rc == MAXT_SUCCESS)
rc = mxfTxPeriodicUpdateMsgBufferAlloc(rt7, 0, 0, out rt7Buffer, IntPtr.Zero); // RT buffer for RT7 SA1 RX
}
// Enables the different RTs
if (rc == MAXT_SUCCESS)
rc = mxfMIL1553RtSubsystemEnableSet(rt5, MXF_MIL1553_MSGTYPE_TX, 1, MXF_MIL1553_BUS_A | MXF_MIL1553_BUS_B, rt5Buffer);
if (rc == MAXT_SUCCESS)
rc = mxfMIL1553RtEnableSet(rt5, VMXF_ENABLE);
if (rc == MAXT_SUCCESS)
rc = mxfMIL1553RtSubsystemEnableSet(rt7, MXF_MIL1553_MSGTYPE_RX, 1, MXF_MIL1553_BUS_A | MXF_MIL1553_BUS_B, rt7Buffer);
if (rc == MAXT_SUCCESS)
rc = mxfMIL1553RtEnableSet(rt7, VMXF_ENABLE);
// Allocates 10KB buffer for rx data
if (rc == MAXT_SUCCESS)
{
rxBufferSize = 10 * 1024;
// Device allocation
rc = mxfRxAcqBufferAlloc(bm, rxBufferSize, out bmBufferRx, IntPtr.Zero);
// Host allocation
if (rc == MAXT_SUCCESS)
{
try
{
rxBuffer = Marshal.AllocHGlobal((int)rxBufferSize);
}
catch (OutOfMemoryException)
{
rc = MAXT_ERROR_MEM;
}
}
}
// Sets timebase to RTC nsec
if (rc == MAXT_SUCCESS)
rc = mxfSystemTimeBaseSet(server, MXF_TIMEBASE_DEVICE_NSEC);
// Starts BM acquisition
if (rc == MAXT_SUCCESS)
rc = mxfRxAcqStart(bmBufferRx, MXF_RXACQ_FLAG_DEFAULT, 0, 0);
// Sends NUM_REC_TX commands
recPtr = txBuffer;
for (cmd = 0; cmd < NUM_REC_TX && rc == MAXT_SUCCESS; cmd++) //we send 10 times the same command
{
txRec1553 = new MXF_MIL1553_DATAREC();
txRec1553.data = new UInt16[36];
//Command #0
txRec1553.timeTag = 0;
txRec1553.repeatCount = 1;
txRec1553.control = MXF_MIL1553_TXAPERIODIC_REC_CTRL_RT_RT;
txRec1553.dataSize = 4; //4 bytes (2 commands)
rc = mxfMIL1553CommandCompose(7, 1, MXF_MIL1553_MSGTYPE_RX, 0, out txRec1553.data[0]); //RT7 SA1
//Command #1
if (rc == MAXT_SUCCESS)
rc = mxfMIL1553CommandCompose(5, 1, MXF_MIL1553_MSGTYPE_TX, 0, out txRec1553.data[1]); //RT5 SA1
Marshal.StructureToPtr(txRec1553, recPtr, true);
if (rc == MAXT_SUCCESS)
rc = mxfMIL1553NextDataRecordPtrGet(recPtr, out recPtr);
}
// Sends commands
Console.Write("Transmitting...\n");
rc = mxfMIL1553TxAperiodicWrite(bcBufferTx, MXF_TXAPERIODIC_FLAG_DEFAULT, 0, cmd, txBuffer);
// Reads and displays received messages for 5 seconds
if (rc == MAXT_SUCCESS)
{
// Waits a little for commands to be transmitted
mxfSleep(1000);
Console.Write("Reading...\n");
rc = mxfMIL1553RxAcqRead(bmBufferRx, 0, rxBufferSize, out rxAcqStatus, out msgCount, out byteCount, rxBuffer);
recPtr = rxBuffer;
for (rxRec = 0; rxRec < msgCount && rc == MAXT_SUCCESS; rxRec++)
{
rxRec1553[0] = (MXF_MIL1553_DATAREC)Marshal.PtrToStructure(recPtr, typeof(MXF_MIL1553_DATAREC));
rc = mxfMIL1553DataRecordDecompose(bm, 1, rxRec1553, msgInfo);
if (rc == MAXT_SUCCESS)
{
rc = mxfMIL1553CommandDecompose(rxRec1553[0].data[1], out address1, out subAddress1, out dir1, out wordCount1);
if (rc == MAXT_SUCCESS)
rc = mxfMIL1553CommandDecompose(rxRec1553[0].data[0], out address2, out subAddress2, out dir2, out wordCount2);
if (rc == MAXT_SUCCESS)
{
Console.Write("\n\r{0}:\t", rxRec1553[0].timeTag);
switch (msgInfo[0].msgType)
{
case MXF_MIL1553_MSGINFO_TYPE_RTRT:
Console.Write("RT{0} SA{1} to RT{2} SA{3} WC{4} (0x{5:x4})\n\r", address1, subAddress1, address2, subAddress2, wordCount1, rxRec1553[0].data[0]);
if (msgInfo[0].statusIndex[0] != 0xffff)
Console.Write("\t\tRT{0} SA{1} status: 0x{2:x4}\n\r", address1, subAddress1, rxRec1553[0].data[msgInfo[0].statusIndex[0]]);
if (msgInfo[0].statusIndex[1] != 0xffff)
Console.Write("\t\tRT{0} SA{1} status: 0x{2:x4}\n\r", address2, subAddress2, rxRec1553[0].data[msgInfo[0].statusIndex[1]]);
break;
}
}
}
// Gets next msg
rc = mxfMIL1553NextDataRecordPtrGet(recPtr, out recPtr);
}
}
// Clears aperiodic buffer
if (rc == MAXT_SUCCESS)
rc = mxfTxAperiodicClear(bcBufferTx, 0);
// Stops RTs
if (rc == MAXT_SUCCESS)
rc = mxfMIL1553RtEnableSet(rt5, VMXF_DISABLE);
if (rc == MAXT_SUCCESS)
rc = mxfMIL1553RtEnableSet(rt7, VMXF_DISABLE);
// Stops acquisition
if (rc == MAXT_SUCCESS)
rc = mxfRxAcqStop(bmBufferRx);
// Clears acquisition
if (rc == MAXT_SUCCESS)
rc = mxfRxAcqClear(bmBufferRx);
// Frees buffers
if (txBuffer != IntPtr.Zero)
Marshal.FreeHGlobal(txBuffer);
if (rxBuffer != IntPtr.Zero)
Marshal.FreeHGlobal(rxBuffer);
if (rc != MAXT_SUCCESS)
{
if (mxfSystemErrorStringGet(server, rc, (UInt32)errorString.Capacity, errorString) != MAXT_SUCCESS)
{
errorString.Clear();
errorString.Append(string.Format("ERROR # 0x{0:x8}", rc));
}
Console.Write(errorString + "\n\r");
}
// Frees all buffers and terminate
if (bcBufferTx > 0)
if (bmBufferRx > 0)
mxfRxAcqBufferFree(bmBufferRx);
if (rt5Buffer > 0)
if (rt7Buffer > 0)
// Unloads MX Foundation library
Console.Write("\n\rPress enter to terminate\n\r");
Console.ReadKey();
return;
}
}
}
Updated 10/23/2023