MX Foundation 4
ar717_bridge_from_ar429.cs
/*******************************************************************************
//
// File:
// ar717_bridge_from_ar429.cs
//
// Copyright (c) MAX Technologies Inc. 1988-2019, All Rights Reserved.
// CONFIDENTIAL AND PROPRIETARY INFORMATION WHICH IS THE
// PROPERTY OF MAX TECHNOLOGIES INC.
//
// In this example we show how to make a data bridge betweem 429 and 717. This
// example first transmits and receives in 429, then the data received in 429
// are placed at the right places in the 717 frame and are encoded how they have
// to be. Finally, the frame is transmited in 717, and received. The 717 display
// shows the subframes individually with the words that have been received. The
// engineering display is a table with for each 429-label, the data in engineering
// writing that have been received in 429 and in 717 (not necessarily equal).
//
// The function ARINC717DataDefinition() holds the information that can be found
// in a specification.
//
//
// Hardware Requirements:
// - MAXT FlexMulti with loopback between (if internal loopback is not used):
// > first TX and RX ARINC 717 Enhanced channel;
// > first TX and RX ARINC 429 dedicated channel.
//
*******************************************************************************/
#define LOOPBACK
//#define LOCAL
using System;
using static MAXT.MXFoundation.mxf;
using System.Runtime.InteropServices;
using System.Text;
namespace ar717_example
{
class ar717_bridge_from_ar429
{
const int ar717_TX_SUBFRAMES_TO_TRANSMIT = 8;//minimum 4 to have at least one full frame.
const int SUBFRAMESIZE = 64;
const int BNR = 0;
const int BCD = 1;
const int REAL = 2;
const int ar429_TX_RECORDS_TO_TRANSMIT = 8;
public struct strucEncoding
{
public UInt32 encoding429;
public UInt32 encoding717;
public double dataRange;
public UInt64 bitRange429;
public UInt64 bitRange717;
}
static uint BUFFER_SIZE = (uint)ar717_TX_SUBFRAMES_TO_TRANSMIT * (uint)Marshal.SizeOf(typeof(MXF_A717_DATAREC));
public static void Main(string[] args)
{
UInt32 rc;
UInt64 server;
var device = new UInt64[1];
var module = new UInt64[1];
var tx717 = new UInt64[1];
var rx717 = new UInt64[1];
var tx429 = new UInt64[1];
var rx429 = new UInt64[1];
UInt64 txBuffer717 = 0, rxBuffer717 = 0;
UInt64 txBuffer429 = 0, rxBuffer429 = 0;
IntPtr tx717HostBuffer = IntPtr.Zero;
IntPtr rx717HostBuffer = IntPtr.Zero;
IntPtr tx429HostBuffer = IntPtr.Zero;
IntPtr rx429HostBuffer = IntPtr.Zero;
UInt64 count = 0, msgsCount429 = 0;
int nbFrames = ar717_TX_SUBFRAMES_TO_TRANSMIT;
MXF_SYSTEM_INIT_ATTRIBUTE_UINT64_HANDLER _initHandler = initHandler;
{
data = new UInt16[8192]
};
// 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
if (rc != MAXT_SUCCESS)
{
Console.Write("Failed to connect; rc=0x{0:x8}", rc);
Console.WriteLine();
Console.WriteLine("Press a key to terminate");
Console.Read();
return;
}
// Initializes init callback handler to set first TX and RX channel to A717
// Initializes the server
Console.WriteLine("Starting");
rc = mxfSystemInit(server);
// Gets the device handle
if (rc == MAXT_SUCCESS)
rc = mxfSystemDeviceAllGet(server, MXF_DEVICE_ALL, 1, out count, device);
// Gets first module A717 Enhanced
if ((rc == MAXT_SUCCESS) && (count != 0))
rc = mxfDeviceModuleAllGet(device[0], MXF_MODULE_MULTI_EH, 1, out count, module);
// Gets the first ARINC 717 TX channel
if ((rc == MAXT_SUCCESS) && (count != 0))
rc = mxfModuleChannelAllGet(module[0], MXF_CLASS_A717, MXF_SCLASS_TX_CHANNEL, 1, out count, tx717);
// Gets the first ARINC 429 TX channel
if ((rc == MAXT_SUCCESS) && (count != 0))
rc = mxfModuleChannelAllGet(module[0], MXF_CLASS_A429, MXF_SCLASS_TX_CHANNEL, 1, out count, tx429);
// Gets the first ARINC 717 RX channel
if ((rc == MAXT_SUCCESS) && (count != 0))
rc = mxfModuleChannelAllGet(module[0], MXF_CLASS_A717, MXF_SCLASS_RX_CHANNEL, 1, out count, rx717);
// Gets the first ARINC 429 RX channel
if ((rc == MAXT_SUCCESS) && (count != 0))
rc = mxfModuleChannelAllGet(module[0], MXF_CLASS_A429, MXF_SCLASS_RX_CHANNEL, 1, out count, rx429);
// If channel not found, returns an error
if ((rc == MAXT_SUCCESS) && (count == 0))
rc = MAXT_ERROR_NOT_FOUND;
// Allocates 717 TX Aperiodic static buffer for HIGH priority queue
if (rc == MAXT_SUCCESS)
rc = mxfTxAperiodicBufferAlloc(tx717[0], MXF_TXAPERIODIC_PRIORITY_HIGH, BUFFER_SIZE, out txBuffer717, IntPtr.Zero);
if (rc == MAXT_SUCCESS)
{
try
{
tx717HostBuffer = Marshal.AllocHGlobal((int)BUFFER_SIZE);
}
catch (OutOfMemoryException)
{
rc = MAXT_ERROR_MEM;
}
}
// Allocates 429 TX Aperiodic static buffer for HIGH priority queue
if (rc == MAXT_SUCCESS)
rc = mxfTxAperiodicBufferAlloc(tx429[0], MXF_TXAPERIODIC_PRIORITY_HIGH, BUFFER_SIZE, out txBuffer429, IntPtr.Zero);
if (rc == MAXT_SUCCESS)
{
try
{
tx429HostBuffer = Marshal.AllocHGlobal((int)BUFFER_SIZE);
}
catch (OutOfMemoryException)
{
rc = MAXT_ERROR_MEM;
}
}
// Allocates 717 RX acquisition buffer
if (rc == MAXT_SUCCESS)
{
rc = mxfRxAcqBufferAlloc(rx717[0], BUFFER_SIZE, out rxBuffer717, IntPtr.Zero);
// Host buffer allocation
if (rc == MAXT_SUCCESS)
{
try
{
rx717HostBuffer = Marshal.AllocHGlobal((int)BUFFER_SIZE);
}
catch (OutOfMemoryException)
{
rc = MAXT_ERROR_MEM;
}
}
}
// Allocates 429 RX acquisition buffer
if (rc == MAXT_SUCCESS)
{
rc = mxfRxAcqBufferAlloc(rx429[0], BUFFER_SIZE, out rxBuffer429, IntPtr.Zero);
// Host buffer allocation
if (rc == MAXT_SUCCESS)
{
try
{
rx429HostBuffer = Marshal.AllocHGlobal((int)BUFFER_SIZE);
}
catch (OutOfMemoryException)
{
rc = MAXT_ERROR_MEM;
}
}
}
// Sets timebase to 64-bit microseconds
if (rc == MAXT_SUCCESS)
rc = mxfSystemTimeBaseSet(server, MXF_TIMEBASE_DEVICE_USEC);
//Activates loopbacks before transmission and reception
#if LOOPBACK
if (rc == MAXT_SUCCESS)
rc = mxfAttributeUint64Set(rx717[0], KMXF_A717_TX_RX_TEST_LB, VMXF_ENABLE);
if (rc == MAXT_SUCCESS)
rc = mxfAttributeUint64Set(rx429[0], KMXF_A429_TX_RX_TEST_LB, VMXF_ENABLE);
#endif
if (nbFrames < 4)
{
if (rc == MAXT_SUCCESS)
Console.Write("\nNumber of subframes to transmit less than 4: synchronization will not occur.\n\n");
}
// ************ SETS ATTRIBUTES FOR 717 CHANNELS ************
// Sets RX & TX channels subframe size
if (rc == MAXT_SUCCESS)
rc = mxfAttributeUint64Set(rx717[0], KMXF_A717_SUBFRAME_SIZE, SUBFRAMESIZE);
if (rc == MAXT_SUCCESS)
rc = mxfAttributeUint64Set(tx717[0], KMXF_A717_SUBFRAME_SIZE, SUBFRAMESIZE);
// Sets RX & TX channels bit encoding to harvard
if (rc == MAXT_SUCCESS)
rc = mxfAttributeUint64Set(rx717[0], KMXF_A717_BIT_ENCODING, VMXF_A717_BIT_ENCODING_HARVARDBIPHASE);
if (rc == MAXT_SUCCESS)
rc = mxfAttributeUint64Set(tx717[0], KMXF_A717_BIT_ENCODING, VMXF_A717_BIT_ENCODING_HARVARDBIPHASE);
// Sets RX & TX channels electrical selection to default
if (rc == MAXT_SUCCESS)
rc = mxfAttributeUint64Set(rx717[0], KMXF_A717_ELECTRICAL_SELECTION, VMXF_A717_ELECTRICAL_SELECT_DEFAULT);
if (rc == MAXT_SUCCESS)
rc = mxfAttributeUint64Set(tx717[0], KMXF_A717_ELECTRICAL_SELECTION, VMXF_A717_ELECTRICAL_SELECT_DEFAULT);
// Starts 429 and 717 acquisitions
if (rc == MAXT_SUCCESS)
{
rc = mxfRxAcqStart(rxBuffer429, MXF_RXACQ_FLAG_DEFAULT, 0, 0);
if (rc == MAXT_SUCCESS)
Console.Write("\nA429 Acquisition started\n\r");
}
if (rc == MAXT_SUCCESS)
{
rc = mxfRxAcqStart(rxBuffer717, MXF_RXACQ_FLAG_DEFAULT, 0, 0);
if (rc == MAXT_SUCCESS)
Console.Write("\nA717 Acquisition started\n\r");
}
// Transmits
if (rc == MAXT_SUCCESS)
rc = write429Msgs(txBuffer429, tx429HostBuffer);
// Reads
if (rc == MAXT_SUCCESS)
rc = read429Acquisition(rxBuffer429, ref msgsCount429, rx429HostBuffer);
if (msgsCount429 == 0)
{
rc = MAXT_ERROR_COUNT;
}
// Transmits
if (rc == MAXT_SUCCESS)
rc = write717Msgs(txBuffer717, rx429HostBuffer, msgsCount429, tx717HostBuffer);
// Reads
if (rc == MAXT_SUCCESS)
rc = read717Acquisition(rxBuffer717, rx717HostBuffer);
// Displays data in engineering writing
if (rc == MAXT_SUCCESS)
rc = writeEng(rx429HostBuffer, msgsCount429, rx717HostBuffer);
// Catches any previous failing function
if (rc != MAXT_SUCCESS)
{
StringBuilder buffer = new StringBuilder(256);
if (mxfSystemErrorStringGet(server, rc, 256, buffer) != MAXT_SUCCESS)
buffer.Append(string.Format("ERROR # 0x{0:x8}", rc));
Console.WriteLine(buffer);
}
//Frees all buffers
if (rxBuffer429 != 0)
mxfRxAcqBufferFree(rxBuffer429);
if (rxBuffer717 != 0)
mxfRxAcqBufferFree(rxBuffer717);
if (txBuffer429 != 0)
if (txBuffer717 != 0)
if (tx429HostBuffer != IntPtr.Zero)
Marshal.FreeHGlobal(tx429HostBuffer);
if (tx717HostBuffer != IntPtr.Zero)
Marshal.FreeHGlobal(tx717HostBuffer);
if (rx429HostBuffer != IntPtr.Zero)
Marshal.FreeHGlobal(rx429HostBuffer);
if (rx717HostBuffer != IntPtr.Zero)
Marshal.FreeHGlobal(rx717HostBuffer);
// Terminates
Console.WriteLine();
Console.WriteLine("Press enter to terminate");
Console.Read();
return;
}
//****************************************************************************************************************
// changeBitEncoding - changes how the data is encoded (BNR, real, BCD) and on how many bits
//****************************************************************************************************************
private static UInt32 changeBitEncoding(UInt32 originBitEncoding, UInt32 destinationBitEncoding, double dataRange, UInt64 originBitRange, UInt64 destinationBitRange, UInt32 originData, ref UInt32 destinationData)
{
double realData = 0;
UInt32 rc = MAXT_SUCCESS;
switch (originBitEncoding)
{
case BNR:
originData <<= 10; //mxfA429ArwBnrToReal expects a data placed like in a A429 word, i.e. originData have to be shifted of 10 to the left to have the useful data at the right place.
mxfA429ArwBnrToReal(originData, dataRange, originBitRange, out realData);
break;
case BCD:
rc = MAXT_ERROR_NOT_SUPPORTED; // not implemented in this example
break;
case REAL:
realData = (double)originData;
break;
default:
rc = MAXT_ERROR_PARAM;
break;
}
switch (destinationBitEncoding)
{
case BNR:
mxfA429ArwRealToBnr(dataRange, destinationBitRange, ref realData, out destinationData);
destinationData >>= 10; //mxfA429ArwRealToBnr returns the data placed like in a A429 word. Therefore, by shifting of 10 to the right, we get the useful data right.
break;
case BCD:
rc = MAXT_ERROR_NOT_SUPPORTED; // not implemented in this example
break;
case REAL:
destinationData = (UInt32)realData;
break;
default:
rc = MAXT_ERROR_PARAM;
break;
}
return rc;
}
//****************************************************************************************************************
// ARINC429 to ARINC717 bridge
//****************************************************************************************************************
private static UInt32 Ar429ToAr717Bridge(IntPtr Ptr429, UInt64 msgsCount429, IntPtr Ptr717)
{
IntPtr recPtr717 = IntPtr.Zero;
IntPtr recPtr429 = Ptr429;
UInt64 label = 0, sdi, data = 0, ssm, parity;
UInt32 rc = MAXT_SUCCESS, dataTemp = 0;
UInt64 iSubframe, iMsgs429, i, iWord;
UInt64 NbOfSubframes = 0, NbOfWords = 0;
var subframes = new UInt64[4];
var words = new UInt64[10];
strucEncoding encoding = new strucEncoding();
{
data = new UInt16[8192]
};
// Refills the FIFO
for (iMsgs429 = 0; (iMsgs429 < msgsCount429) && (rc == MAXT_SUCCESS); iMsgs429++)
{
recPtr717 = Ptr717;
rec429 = (MXF_A429_DATAREC)Marshal.PtrToStructure(recPtr429, typeof(MXF_A429_DATAREC));
// Decomposes the data received in A429 and stored in the MXF_A717_DATAREC
if (rc == MAXT_SUCCESS)
rc = mxfA429ArwDecompose(rec429.data, out label, out sdi, out data, out ssm, out parity);
if (rc == MAXT_SUCCESS)
{
// Finds in the data definition the locations (subframes and words) where the data correspondin to the A429 label is to be stored
ARINC717DataDefinition(label, ref NbOfSubframes, ref subframes, ref NbOfWords, ref words, ref encoding);
// if the data is not endoded the same way (BNR/BCD and/or number of bit) in A717 and in A429 according to the definition, then changes the way the data is encoded
if (encoding.bitRange429 != encoding.bitRange717 || encoding.encoding429 != encoding.encoding717)
{
changeBitEncoding(encoding.encoding429, encoding.encoding717, encoding.dataRange, encoding.bitRange429, encoding.bitRange717, (UInt32)data, ref dataTemp);
data = dataTemp;
}
data >>= 7; // because encoded on 19 bits whereas A717 words are 12-bit long
}
for (iSubframe = 0; (rc == MAXT_SUCCESS) && (iSubframe < ar717_TX_SUBFRAMES_TO_TRANSMIT); iSubframe++)
{
rec717.timeTag = 0;
rec717.control = 0;
rec717.dataSize = 2 * (UInt32)SUBFRAMESIZE; // 16 bits per word in subframe
rec717.repeatCount = 1;
rec717.reserved = 0;
// Use of 429 data to fill in other words
for (i = 0; i < NbOfSubframes; i++)
{
if (iSubframe % 4 == subframes[i] - 1)
{
for (iWord = 0; iWord < NbOfWords; iWord++)
{
rec717.data[words[iWord] - 1] = (UInt16)data;
}
}
}
// 1st word of each subframe has to be a sync word
// sync words are:
// - 0x247 for subframe #0
// - 0x5B8 for subframe #1
// - 0xA47 for subframe #2
// - 0xDB8 for subframe #3
switch (iSubframe % 4)
{
case 0:
rec717.data[0] = 0x247;
break;
case 1:
rec717.data[0] = 0x5B8;
break;
case 2:
rec717.data[0] = 0xA47;
break;
case 3:
rec717.data[0] = 0xDB8;
break;
default:
break;
}
if (rc == MAXT_SUCCESS)
{
Marshal.StructureToPtr(rec717, recPtr717, false);
rc = mxfA717NextDataRecordPtrGet(recPtr717, out recPtr717);
}
}
rc = mxfA429NextDataRecordPtrGet(recPtr429, out recPtr429);
}
return rc;
}
//****************************************************************************************************************
// ARINC717DataDefinition
//****************************************************************************************************************
private static UInt32 ARINC717DataDefinition(UInt64 label, ref UInt64 NbOfSubframes, ref UInt64[] subframes, ref UInt64 NbOfWords, ref UInt64[] words, ref strucEncoding encoding)
{
// Build your own data definition
// For each A429 label that can be received, the definition gives the subframes and the words in which the data corresponding to this label has to be written
switch (label)
{
case 65: //0101
{
subframes[0] = 1;
subframes[1] = 2;
subframes[2] = 3;
subframes[3] = 4;
words[0] = 19;
NbOfSubframes = 4;
NbOfWords = 1;
encoding.encoding429 = BNR; //in A429
encoding.encoding717 = BNR; //in A717
encoding.dataRange = 180;
encoding.bitRange429 = 12;
encoding.bitRange717 = 12;
}
break;
case 66: //0102
{
subframes[0] = 1;
subframes[1] = 2;
subframes[2] = 3;
subframes[3] = 4;
words[0] = 17;
NbOfSubframes = 4;
NbOfWords = 1;
encoding.encoding429 = BNR;
encoding.encoding717 = BNR;
encoding.dataRange = 65536;
encoding.bitRange429 = 16;
encoding.bitRange717 = 12;
}
break;
case 67: //0103
{
subframes[0] = 1;
subframes[1] = 2;
subframes[2] = 3;
subframes[3] = 4;
words[0] = 32;
NbOfSubframes = 4;
NbOfWords = 1;
encoding.encoding429 = BNR;
encoding.encoding717 = BNR;
encoding.dataRange = 512;
encoding.bitRange429 = 11;
encoding.bitRange717 = 12;
}
break;
case 68: //0104
{
subframes[0] = 1;
subframes[1] = 2;
subframes[2] = 3;
subframes[3] = 4;
words[0] = 11;
NbOfSubframes = 4;
NbOfWords = 1;
encoding.encoding429 = BNR;
encoding.encoding717 = BNR;
encoding.dataRange = 16384;
encoding.bitRange429 = 10;
encoding.bitRange717 = 12;
}
break;
case 208: //0320
{
subframes[0] = 1;
subframes[1] = 2;
subframes[2] = 3;
subframes[3] = 4;
words[0] = 9;
NbOfSubframes = 4;
NbOfWords = 1;
encoding.encoding429 = BNR;
encoding.encoding717 = BNR;
encoding.dataRange = 180;
encoding.bitRange429 = 15;
encoding.bitRange717 = 12;
}
break;
case 213: //0325
{
subframes[0] = 1;
subframes[1] = 2;
subframes[2] = 3;
subframes[3] = 4;
words[0] = 14;
words[1] = 46;
NbOfSubframes = 4;
NbOfWords = 2;
encoding.encoding429 = BNR;
encoding.encoding717 = BNR;
encoding.dataRange = 180;
encoding.bitRange429 = 14;
encoding.bitRange717 = 12;
}
break;
case 217: //0331
{
subframes[0] = 1;
subframes[1] = 2;
subframes[2] = 3;
subframes[3] = 4;
words[0] = 5;
words[1] = 21;
words[2] = 37;
words[3] = 53;
NbOfSubframes = 4;
NbOfWords = 4;
encoding.encoding429 = BNR;
encoding.encoding717 = BNR;
encoding.dataRange = 2;
encoding.bitRange429 = 12;
encoding.bitRange717 = 12;
}
break;
case 218: //0332
{
subframes[0] = 1;
subframes[1] = 2;
subframes[2] = 3;
subframes[3] = 4;
words[0] = 6;
words[1] = 22;
words[2] = 38;
words[3] = 54;
NbOfSubframes = 4;
NbOfWords = 4;
encoding.encoding429 = BNR;
encoding.encoding717 = BNR;
encoding.dataRange = 2;
encoding.bitRange429 = 12;
encoding.bitRange717 = 12;
}
break;
default:
break;
}
return MAXT_SUCCESS;
}
//****************************************************************************************************************
// ARINC717 Aperiodic Transmission
//****************************************************************************************************************
private static UInt32 write717Msgs(UInt64 buffer, IntPtr rec429, UInt64 msgsCount429, IntPtr tx717HostBuffer)
{
UInt32 rc = 0;
Console.Write("\nA717 Aperiodic transmission\n");
// Builds tx717HostBuffer (A717) from a A429 record
rc = Ar429ToAr717Bridge(rec429, msgsCount429, tx717HostBuffer);
// Transmits strings on relative record time
if (rc == MAXT_SUCCESS)
rc = mxfA717TxAperiodicWrite(buffer, MXF_TXAPERIODIC_FLAG_DEFAULT, 0, ar717_TX_SUBFRAMES_TO_TRANSMIT, tx717HostBuffer);
// Waits for transmit to be over
if (rc == MAXT_SUCCESS)
mxfSleep((ar717_TX_SUBFRAMES_TO_TRANSMIT + 1) * 1000); // 1 second per subframe + 1 seconds to be sure to exceed the minimum duration to wait.
if (rc != MAXT_SUCCESS)
Console.Write("A717 transmit failed; rc=0x{0:x8}\n", rc);
else
Console.Write("\nWriting A717-records\n");
return rc;
}
//****************************************************************************************************************
// ARINC429 Aperiodic Transmission
//****************************************************************************************************************
private static UInt32 write429Msgs(UInt64 txBuffer, IntPtr rec429)
{
IntPtr recPtr = rec429;
UInt32 label, sdi, data, ssm, parity;
double value;
UInt32 record;
UInt64 delay100ms = 100000;
UInt32 rc =0;
UInt64 msgCount, usedBytes, freeBytes;
// In the example below the record are sent back-to-back 100 ms in the future.
Console.Write("\nA429 Aperiodic transmission\n");
// Sets the records
for (record = 0; (record < ar429_TX_RECORDS_TO_TRANSMIT) && (rc == MAXT_SUCCESS); record++)
{
// Sets each record
rec.timeTag = 0;
rec.control = 0;
rec.repeatCount = 1;
rec.reserved = 0;
data = 0;
sdi = 1;
ssm = 0;
parity = (UInt32)VMXF_A429_PARITY_ODD;
switch (record)
{
case 0:
label = Convert.ToUInt32("331", 8); ; // Longitudinal acceleration
value = 0.6501; // mach
mxfA429ArwRealToBnr(2, 12, ref value, out data);
data >>= 10;
break;
case 1:
label = Convert.ToUInt32("332", 8); // Lateral acceleration
value = -0.0141; // mach
mxfA429ArwRealToBnr(2, 12, ref value, out data);
data >>= 10;
break;
case 2:
label = Convert.ToUInt32("320", 8); // Magnetic heading
value = 45.342; // deg/180
mxfA429ArwRealToBnr(180, 15, ref value, out data);
data >>= 10;
break;
case 3:
label = Convert.ToUInt32("104", 8); // Selected vertical speed
value = 231; // Ft/min
mxfA429ArwRealToBnr(16384, 10, ref value, out data);
data >>= 10;
break;
case 4:
label = Convert.ToUInt32("325", 8); // Roll angle
value = 3.67; // deg/180
mxfA429ArwRealToBnr(180, 14, ref value, out data);
data >>= 10;
break;
case 5:
label = Convert.ToUInt32("102", 8); // Selected altitude
value = 13400; // feet
mxfA429ArwRealToBnr(65536, 16, ref value, out data);
data >>= 10;
break;
case 6:
label = Convert.ToUInt32("101", 8); // Selected heading
value = 48; // deg/180
mxfA429ArwRealToBnr(180, 12, ref value, out data);
data >>= 10;
break;
case 7:
label = Convert.ToUInt32("103", 8); // Selected speed
value = 435.54; // knots
mxfA429ArwRealToBnr(512, 11, ref value, out data);
data >>= 10;
break;
default:
label = Convert.ToUInt32("001", 8);
data = 0;
break;
}
rc = mxfA429ArwCompose(label, sdi, data, ssm, parity, out rec.data);
if (rc == MAXT_SUCCESS)
{
Marshal.StructureToPtr(rec, recPtr, false);
rc = mxfA429NextDataRecordPtrGet(recPtr, out recPtr);
}
}
// Transmits the array of records
rc = mxfA429TxAperiodicWrite(txBuffer, MXF_TXAPERIODIC_FLAG_DEFAULT, delay100ms, ar429_TX_RECORDS_TO_TRANSMIT, rec429);
// Waits TX completion
// Waits till all records are sent on the interface
do
{
rc = mxfTxAperiodicBufferStatusGet(txBuffer, out msgCount, out usedBytes, out freeBytes);
if (rc != MAXT_SUCCESS)
return rc;
} while (msgCount != 0);
// Makse sure they are received
mxfSleep(100);
return rc;
}
/***************************************************************************************************************/
// read717Acquisition
/***************************************************************************************************************/
private static UInt32 read717Acquisition(UInt64 rxBuffer, IntPtr rx717HostBuffer)
{
IntPtr recPtr = rx717HostBuffer;
UInt64 status, msgsCount, bytesCount;
UInt64 word, data;
UInt32 rc;
{
data = new UInt16[8192]
};
Console.Write("\nA717 reading\n");
// Reads and display records
rc = mxfA717RxAcqRead(rxBuffer, 0, (UInt64)BUFFER_SIZE, out status, out msgsCount, out bytesCount, rx717HostBuffer);
if (rc == MAXT_SUCCESS)
Console.Write("String received count = {0} \n", msgsCount);
if (rc == MAXT_SUCCESS)
{
// Displays received strings
for (data = 0; (data < msgsCount) && (rc == MAXT_SUCCESS); data++)
{
rec = (MXF_A717_DATAREC)Marshal.PtrToStructure(recPtr, typeof(MXF_A717_DATAREC));
Console.Write("\n{0:D2}: Timetag={1:D12}, Size={2} words\n", data, rec.timeTag, (rec.dataSize) / 2);
for (word = 0; word < SUBFRAMESIZE; word++)
{
if (rec.data[word] != 0)
Console.Write("{0:X3} ", rec.data[word]);
else
Console.Write("--- ");
}
Console.Write("\n");
rc = mxfA717NextDataRecordPtrGet(recPtr, out recPtr);
}
}
if (rc != MAXT_SUCCESS)
Console.Write("A717 acquisition read failed; rc=0x{0:x8}\n", rc);
return rc;
}
/***************************************************************************************************************/
// read429Acquisition
/***************************************************************************************************************/
private static UInt32 read429Acquisition(UInt64 rxBuffer, ref UInt64 msgsCount429, IntPtr rec429)
{
IntPtr recPtr = rec429;
UInt64 status, bytesCount;
UInt64 label, sdi, data, ssm, parity;
UInt64 j;
UInt32 rc;
Console.Write("\nA429 reading\n");
// Reads and displays records
rc = mxfA429RxAcqRead(rxBuffer, 0, BUFFER_SIZE, out status, out msgsCount429, out bytesCount, rec429);
for (j = 0; (j < msgsCount429) && (rc == MAXT_SUCCESS); j++)
{
rec = (MXF_A429_DATAREC)Marshal.PtrToStructure(recPtr, typeof(MXF_A429_DATAREC));
rc = mxfA429ArwDecompose(rec.data, out label, out sdi, out data, out ssm, out parity);
if (rc == MAXT_SUCCESS)
{
Console.Write("{0:D2}: Timetag {1} - ARINC429 word=[{2},{3},{4:X5},{5},{6}]\n",
j, rec.timeTag, Convert.ToString((int)label, 8).PadLeft(3, '0'), sdi, data, ssm, (parity == VMXF_A429_PARITY_ODD) ? "ODD" : "EVEN");
if (rc == MAXT_SUCCESS)
rc = mxfA429NextDataRecordPtrGet(recPtr, out recPtr);
}
}
if (rc != MAXT_SUCCESS)
Console.Write("A429 acquisition read failed; rc=0x{0:x8}\n", rc);
return rc;
}
/***************************************************************************************************************/
// Decodes the data in 429 and 717 to display them in engineering writing
/***************************************************************************************************************/
private static UInt32 writeEng(IntPtr Ptr429, UInt64 msgsCount429, IntPtr Ptr717)
{
UInt32 rc = MAXT_SUCCESS;
IntPtr recPtr429 = Ptr429;
IntPtr recPtr717 = IntPtr.Zero;
UInt64 label, sdi, data429, ssm, parity;
UInt64 iMsgCount, iSubframe;
UInt64 data717, NbOfSubframes = 0, NbOfWords = 0;
var subframes = new UInt64[4];
var words = new UInt64[10];
strucEncoding encoding = new strucEncoding();
double real429, real717;
{
data = new UInt16[8192]
};
Console.Write("\n\n");
Console.Write("---------------------------------------------------------------------\n");
Console.Write("| Label | Value received in A429 | Value received in A717 |\n");
Console.Write("---------------------------------------------------------------------\n");
for (iMsgCount = 0; (iMsgCount < msgsCount429) && (rc == MAXT_SUCCESS); iMsgCount++)
{
real429 = 0;
real717 = 0;
recPtr717 = Ptr717;
rec717 = (MXF_A717_DATAREC)Marshal.PtrToStructure(recPtr717, typeof(MXF_A717_DATAREC));
// A429
rec429 = (MXF_A429_DATAREC)Marshal.PtrToStructure(recPtr429, typeof(MXF_A429_DATAREC));
rc = mxfA429ArwDecompose(rec429.data, out label, out sdi, out data429, out ssm, out parity);
if (rc == MAXT_SUCCESS)
ARINC717DataDefinition(label, ref NbOfSubframes, ref subframes, ref NbOfWords, ref words, ref encoding);
if (rc == MAXT_SUCCESS)
{
data429 <<= 10;
rc = mxfA429ArwBnrToReal((UInt32)data429, encoding.dataRange, encoding.bitRange429, out real429);
}
// A717
if (rc == MAXT_SUCCESS)
{
for (iSubframe = 0; iSubframe < 4; iSubframe++)
{
if (iSubframe == subframes[0]) //if true, recPtr717 is on the first subframe containing the data corresponding to the label 'label' in A429
{
data717 = rec717.data[words[0] - 1];
data717 <<= 17;
if (rc == MAXT_SUCCESS)
rc = mxfA429ArwBnrToReal((UInt32)data717, encoding.dataRange, encoding.bitRange717, out real717);
}
else
{
rc = mxfA717NextDataRecordPtrGet(recPtr717, out recPtr717);
}
}
}
if (rc == MAXT_SUCCESS)
rc = mxfA429NextDataRecordPtrGet(recPtr429, out recPtr429);
//prints according to the number of digits
if (real429 < -10000)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.0}", real429), String.Format("{0:0.0}", real717));
else if (real429 < -1000)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.00}", real429), String.Format("{0:0.00}", real717));
else if (real429 < -100)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.00}", real429), String.Format("{0:0.00}", real717));
else if (real429 < -10)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.000}", real429), String.Format("{0:0.000}", real717));
else if (real429 < 0)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.000}", real429), String.Format("{0:0.000}", real717));
else if (real429 < 10)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.000}", real429), String.Format("{0:0.000}", real717));
else if (real429 < 100)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.000}", real429), String.Format("{0:0.000}", real717));
else if (real429 < 1000)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.00}", real429), String.Format("{0:0.00}", real717));
else if (real429 < 10000)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.00}", real429), String.Format("{0:0.00}", real717));
else if (real429 < 100000)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.0}", real429), String.Format("{0:0.0}", real717));
else if (real429 >= 100000)
Console.Write("| {0} | {1} | {2} |\n", Convert.ToString((int)label, 8).PadLeft(3, '0'), String.Format("{0:0.0}", real429), String.Format("{0:0.0}", real717));
}
Console.Write("---------------------------------------------------------------------\n");
return rc;
}
private static UInt32 initHandler(UInt64 server, UInt64 deviceIndex, UInt64 moduleIndex, UInt64 channelIndex, UInt64 attrib, ref UInt64 value)
{
UInt64 device;
MXF_DEVICE_INFO deviceInfo = new MXF_DEVICE_INFO();
UInt32 rc;
server = server;
deviceIndex = deviceIndex;
if (attrib == KMXF_CHANNEL_CLASS)
{
rc = mxfSystemDeviceGet(server, deviceIndex, out device);
if (rc == MAXT_SUCCESS)
rc = mxfDeviceInfoGet(device, out deviceInfo);
if ((rc == MAXT_SUCCESS) && (deviceInfo.modules[moduleIndex].type == MXF_MODULE_MULTI_EH))
{
// Sets MXF_MODULE_MULTI_EH first TX and RX channels to A717
if ((channelIndex == 0) || (channelIndex == deviceInfo.modules[moduleIndex].txCount))
{
value = MXF_CLASS_A717;
return Convert.ToUInt32(true);
}
}
}
return Convert.ToUInt32(false);
}
}
}
Updated 10/23/2023