MX Foundation 4
ar717_bridge_from_ar429.c
/*******************************************************************************
//
// File:
// ar717_bridge_from_ar429.c
//
// Copyright (c) MAX Technologies Inc. 1988-2015, 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.
//
*******************************************************************************/
#include "example.h"
#include <stdlib.h>
//#define LOOPBACK
//#define LOCAL
#define ar717_TX_SUBFRAMES_TO_TRANSMIT 8 //minimum 4 to have at least one full frame.
#define SUBFRAMESIZE 64
#define BNR 0
#define BCD 1
#define REAL 2
#define ar429_TX_RECORDS_TO_TRANSMIT 8
size_t BUFFER_SIZE = (ar717_TX_SUBFRAMES_TO_TRANSMIT*sizeof(MXF_A717_DATAREC));
typedef struct
{
uint32 encoding429;
uint32 encoding717;
double dataRange;
uint64 bitRange429;
uint64 bitRange717;
}
strucEncoding;
uint32 ARINC717DataDefinition (uint64 label, uint64 *NbOfSubframes, uint64 *subframes, uint64 *NbOfWords, uint64 *words, strucEncoding *encoding);
uint32 Ar429ToAr717Bridge(MXF_A429_DATAREC *rec429, uint64 msgsCount429, MXF_A717_DATAREC *rec717);
uint32 changeBitEncoding(uint32 originBitEncoding, uint32 destinationBitEncoding, double dataRange, uint64 originBitRange, uint64 destinationBitRange, uint32 originData, uint32 *destinationData);
uint32 writeEng (MXF_A429_DATAREC *rec429, uint64 msgsCount429, MXF_A717_DATAREC *rec717);
uint32 write717Msgs(HMXF_BUFFER buffer, MXF_A429_DATAREC *rec429, uint64 msgsCount429, MXF_A717_DATAREC *tx717HostBuffer);
uint32 write429Msgs(HMXF_BUFFER txBuffer, MXF_A429_DATAREC *rec429);
uint32 read717Acquisition(HMXF_BUFFER rxBuffer, MXF_A717_DATAREC *rx717HostBuffer);
uint32 read429Acquisition(HMXF_BUFFER rxBuffer, uint64 *msgsCount429, MXF_A429_DATAREC *rec429);
uint32 initHandler(HMXF_SERVER server, uint64 deviceIndex, uint64 moduleIndex, uint64 channelIndex, uint64 attrib, uint64* value);
/******************************************************************************/
// Main
/******************************************************************************/
int main(void)
{
uint32 rc;
HMXF_SERVER server;
HMXF_DEVICE device=0;
HMXF_MODULE module=0;
HMXF_CHANNEL tx717=0, rx717=0;
HMXF_CHANNEL tx429=0, rx429=0;
HMXF_BUFFER txBuffer717=0, rxBuffer717=0;
HMXF_BUFFER txBuffer429=0, rxBuffer429=0;
MXF_A717_DATAREC* tx717HostBuffer=0;
MXF_A717_DATAREC* rx717HostBuffer=0;
MXF_A429_DATAREC* tx429HostBuffer=0;
MXF_A429_DATAREC* rx429HostBuffer=0;
uint64 count=0, msgsCount429=0;
// Connects to services and initialize environment
#ifdef LOCAL
rc = mxfServerConnect("0.0.0.0", "", "", FALSE, &server);
#else
rc = mxfServerConnect("192.168.0.1", "admin", "admin", TRUE, &server);
#endif
if(rc!=MAXT_SUCCESS)
{
printf("Failed to connect; rc=0x%08x", rc);
printf("\nPress a key to terminate\n");
getchar();
return 0;
}
// Initializes init callback handler to set first TX and RX channel to A717
rc = mxfSystemInitAttributeUint64CallbackHandler(server, &initHandler);
// Initializes the server
printf("Starting\n");
rc = mxfSystemInit(server);
// Gets the device handle
if (!rc)
rc = mxfSystemDeviceAllGet(server, MXF_DEVICE_ALL, 1, &count, &device);
// Gets first module A717 Enhanced
if(!rc && count)
rc = mxfDeviceModuleAllGet(device, MXF_MODULE_MULTI_EH, 1, &count, &module);
// Gets the first ARINC 717 TX channel
if (!rc && count)
rc = mxfModuleChannelAllGet(module, MXF_CLASS_A717, MXF_SCLASS_TX_CHANNEL, 1, &count, &tx717);
// Gets the first ARINC 429 TX channel
if (!rc && count)
rc = mxfModuleChannelAllGet(module, MXF_CLASS_A429, MXF_SCLASS_TX_CHANNEL, 1, &count, &tx429);
// Gets the first ARINC 717 RX channel
if (!rc && count)
rc = mxfModuleChannelAllGet(module, MXF_CLASS_A717, MXF_SCLASS_RX_CHANNEL, 1, &count, &rx717);
// Gets the first ARINC 429 RX channel
if (!rc && count)
rc = mxfModuleChannelAllGet(module, MXF_CLASS_A429, MXF_SCLASS_RX_CHANNEL, 1, &count, &rx429);
// If channel not found, returns an error
if(!rc && !count)
rc = MAXT_ERROR_NOT_FOUND;
// Allocates 717 TX Aperiodic static buffer for HIGH priority queue
if (!rc)
rc=mxfTxAperiodicBufferAlloc(tx717, MXF_TXAPERIODIC_PRIORITY_HIGH, BUFFER_SIZE, &txBuffer717, NULL);
if(!rc)
{
tx717HostBuffer = (MXF_A717_DATAREC*) calloc(1, BUFFER_SIZE);
if(!tx717HostBuffer)
rc = MAXT_ERROR_MEM;
}
// Allocates 429 TX Aperiodic static buffer for HIGH priority queue
if (!rc)
rc=mxfTxAperiodicBufferAlloc(tx429, MXF_TXAPERIODIC_PRIORITY_HIGH, BUFFER_SIZE, &txBuffer429, NULL);
if(!rc)
{
tx429HostBuffer = (MXF_A429_DATAREC*) calloc(1, BUFFER_SIZE);
if(!tx429HostBuffer)
rc = MAXT_ERROR_MEM;
}
// Allocates 717 RX acquisition buffer
if (!rc)
{
rc = mxfRxAcqBufferAlloc(rx717, BUFFER_SIZE, &rxBuffer717, NULL);
// Host buffer allocation
if(!rc)
{
rx717HostBuffer = (MXF_A717_DATAREC*) calloc(1, BUFFER_SIZE);
if(!rx717HostBuffer)
rc = MAXT_ERROR_MEM;
}
}
// Allocates 429 RX acquisition buffer
if (!rc)
{
rc = mxfRxAcqBufferAlloc(rx429, BUFFER_SIZE, &rxBuffer429, NULL);
// Host buffer allocation
if(!rc)
{
rx429HostBuffer = (MXF_A429_DATAREC*) calloc(1, BUFFER_SIZE);
if(!rx429HostBuffer)
rc = MAXT_ERROR_MEM;
}
}
// Sets timebase to 64-bit microseconds
if(!rc)
rc = mxfSystemTimeBaseSet(server, MXF_TIMEBASE_DEVICE_USEC);
//Activates loopbacks before transmission and reception
#ifdef LOOPBACK
if (!rc)
rc = mxfAttributeUint64Set(rx717, KMXF_A717_TX_RX_TEST_LB, VMXF_ENABLE);
if (!rc)
rc = mxfAttributeUint64Set(rx429, KMXF_A429_TX_RX_TEST_LB, VMXF_ENABLE);
#endif
#if (ar717_TX_SUBFRAMES_TO_TRANSMIT < 4)
if(!rc)
printf("\nNumber of subframes to transmit less than 4: synchronization will not occur.\n\n");
#endif
// ************ SETS ATTRIBUTES FOR 717 CHANNELS ************
// Sets RX & TX channels subframe size
if(!rc)
rc=mxfAttributeUint64Set(rx717, KMXF_A717_SUBFRAME_SIZE, SUBFRAMESIZE);
if(!rc)
rc=mxfAttributeUint64Set(tx717, KMXF_A717_SUBFRAME_SIZE, SUBFRAMESIZE);
// Sets RX & TX channels bit encoding to harvard
if(!rc)
rc=mxfAttributeUint64Set(rx717, KMXF_A717_BIT_ENCODING, VMXF_A717_BIT_ENCODING_HARVARDBIPHASE);
if(!rc)
rc=mxfAttributeUint64Set(tx717, KMXF_A717_BIT_ENCODING, VMXF_A717_BIT_ENCODING_HARVARDBIPHASE);
// Sets RX & TX channels electrical selection to default
if(!rc)
rc=mxfAttributeUint64Set(rx717, KMXF_A717_ELECTRICAL_SELECTION, VMXF_A717_ELECTRICAL_SELECT_DEFAULT);
if(!rc)
rc=mxfAttributeUint64Set(tx717, KMXF_A717_ELECTRICAL_SELECTION, VMXF_A717_ELECTRICAL_SELECT_DEFAULT);
// Starts 429 and 717 acquisitions
if (!rc)
{
rc = mxfRxAcqStart(rxBuffer429, MXF_RXACQ_FLAG_DEFAULT, 0, 0);
if (!rc)
printf("\nA429 Acquisition started\n\r");
}
if (!rc)
{
rc = mxfRxAcqStart(rxBuffer717, MXF_RXACQ_FLAG_DEFAULT, 0, 0);
if (!rc)
printf("\nA717 Acquisition started\n\r");
}
// Transmits
if(!rc)
rc = write429Msgs(txBuffer429, tx429HostBuffer);
// Reads
if (!rc)
rc = read429Acquisition(rxBuffer429, &msgsCount429, rx429HostBuffer);
if (!msgsCount429)
{
rc = MAXT_ERROR_COUNT;
}
// Transmits
if(!rc)
rc = write717Msgs(txBuffer717, rx429HostBuffer, msgsCount429, tx717HostBuffer);
// Reads
if (!rc)
rc = read717Acquisition(rxBuffer717, rx717HostBuffer);
// Displays data in engineering writing
if (!rc)
rc = writeEng(rx429HostBuffer, msgsCount429, rx717HostBuffer);
// Catches any previous failing function
if(rc)
{
char buffer[256];
if(mxfSystemErrorStringGet(server, rc, sizeof(buffer), buffer))
sprintf (buffer,"ERROR # 0x%08X", rc);
printf("%s\n\r", buffer);
}
//Frees all buffers
if (rxBuffer429)
mxfRxAcqBufferFree(rxBuffer429);
if (rxBuffer717)
mxfRxAcqBufferFree(rxBuffer717);
if(txBuffer429)
if(txBuffer717)
// Terminates
printf("\nPress enter to terminate\n");
getchar();
return rc;
}
//****************************************************************************************************************
// changeBitEncoding - changes how the data is encoded (BNR, real, BCD) and on how many bits
//****************************************************************************************************************
uint32 changeBitEncoding(uint32 originBitEncoding, uint32 destinationBitEncoding, double dataRange, uint64 originBitRange, uint64 destinationBitRange, uint32 originData, 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, &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, &realData, 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
//****************************************************************************************************************
uint32 Ar429ToAr717Bridge(MXF_A429_DATAREC *rec429, uint64 msgsCount429, MXF_A717_DATAREC *rec717)
{
MXF_A717_DATAREC *recPtr717;
MXF_A429_DATAREC *recPtr429 = rec429;
uint64 label=0, sdi, data=0, ssm, parity;
uint32 rc = MAXT_SUCCESS, dataTemp=0;
uint64 iSubframe, iMsgs429, i, iWord;
uint64 NbOfSubframes=0, subframes[4] = {0}, NbOfWords=0, words[10] = {0};
strucEncoding encoding;
// Refills the FIFO
for (iMsgs429 = 0; iMsgs429 < msgsCount429 && !rc; iMsgs429++)
{
recPtr717 = rec717;
// Decomposes the data received in A429 and stored in the MXF_A717_DATAREC
if (!rc)
rc = mxfA429ArwDecompose(recPtr429->data, &label, &sdi, &data, &ssm, &parity);
if (!rc)
{
// Finds in the data definition the locations (subframes and words) where the data correspondin to the A429 label is to be stored
ARINC717DataDefinition (label, &NbOfSubframes, subframes, &NbOfWords, words, &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, &dataTemp);
data = dataTemp;
}
data >>= 7; // because encoded on 19 bits whereas A717 words are 12-bit long
}
for(iSubframe=0; !rc && iSubframe<ar717_TX_SUBFRAMES_TO_TRANSMIT; iSubframe++)
{
recPtr717->timeTag=0;
recPtr717->control=0;
recPtr717->dataSize = 2 * (uint32)SUBFRAMESIZE; // 16 bits per word in subframe
recPtr717->repeatCount=1;
recPtr717->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++)
{
recPtr717->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:
recPtr717->data[0] = 0x247;
break;
case 1:
recPtr717->data[0] = 0x5B8;
break;
case 2:
recPtr717->data[0] = 0xA47;
break;
case 3:
recPtr717->data[0] = 0xDB8;
break;
default:
break;
}
if(!rc)
rc = mxfA717NextDataRecordPtrGet(recPtr717, &recPtr717);
}
rc = mxfA429NextDataRecordPtrGet(recPtr429, &recPtr429);
}
return rc;
}
//****************************************************************************************************************
// ARINC717DataDefinition
//****************************************************************************************************************
uint32 ARINC717DataDefinition (uint64 label, uint64 *NbOfSubframes, uint64 *subframes, uint64 *NbOfWords, uint64 *words, 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 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 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 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 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 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 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 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 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
//****************************************************************************************************************
uint32 write717Msgs(HMXF_BUFFER buffer, MXF_A429_DATAREC *rec429, uint64 msgsCount429, MXF_A717_DATAREC *tx717HostBuffer)
{
uint32 rc=0;
printf("\nA717 Aperiodic transmission\n");
// Builds tx717HostBuffer (A717) from a A429 record
rc = Ar429ToAr717Bridge(rec429 , msgsCount429 , tx717HostBuffer);
// Transmits strings on relative record time
if(!rc)
rc = mxfA717TxAperiodicWrite(buffer, MXF_TXAPERIODIC_FLAG_DEFAULT, 0, ar717_TX_SUBFRAMES_TO_TRANSMIT, tx717HostBuffer);
// Waits for transmit to be over
if (!rc)
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)
printf("A717 transmit failed; rc=0x%08x\n", rc);
else
printf("\nWriting A717-records\n");
return rc;
}
//****************************************************************************************************************
// ARINC429 Aperiodic Transmission
//****************************************************************************************************************
uint32 write429Msgs(HMXF_BUFFER txBuffer, MXF_A429_DATAREC *rec429)
{
uint32 label, sdi, data, ssm, parity;
double value;
uint32 record;
uint64 delay100ms = 100000;
uint32 rc;
uint64 msgCount, usedBytes, freeBytes;
// In the example below the record are sent back-to-back 100 ms in the future.
printf("\nA429 Aperiodic transmission\n");
// Sets the records
rec = rec429;
for (record=0; record<ar429_TX_RECORDS_TO_TRANSMIT; record++)
{
// Sets each record
rec->timeTag = 0;
rec->control = 0;
rec->repeatCount = 1;
rec->reserved = 0;
data = 0;
sdi = 1;
ssm = 0;
parity = VMXF_A429_PARITY_ODD;
switch (record)
{
case 0:
label = 0331; // Longitudinal acceleration
value = 0.6501; // mach
mxfA429ArwRealToBnr(2, 12, &value, &data);
data >>= 10;
break;
case 1:
label = 0332; // Lateral acceleration
value = -0.0141; // mach
mxfA429ArwRealToBnr(2, 12, &value, &data);
data >>= 10;
break;
case 2:
label = 0320; // Magnetic heading
value = 45.342; // deg/180
mxfA429ArwRealToBnr(180, 15, &value, &data);
data >>= 10;
break;
case 3:
label = 0104; // Selected vertical speed
value = 231; // Ft/min
mxfA429ArwRealToBnr(16384, 10, &value, &data);
data >>= 10;
break;
case 4:
label = 0325; // Roll angle
value = 3.67; // deg/180
mxfA429ArwRealToBnr(180, 14, &value, &data);
data >>= 10;
break;
case 5:
label = 0102; // Selected altitude
value = 13400; // feet
mxfA429ArwRealToBnr(65536, 16, &value, &data);
data >>= 10;
break;
case 6:
label = 0101; // Selected heading
value = 48; // deg/180
mxfA429ArwRealToBnr(180, 12, &value, &data);
data >>= 10;
break;
case 7:
label = 0103; // Selected speed
value = 435.54; // knots
mxfA429ArwRealToBnr(512, 11, &value, &data);
data >>= 10;
break;
default:
label = 0001;
data = 0;
break;
}
rc= mxfA429ArwCompose(label, sdi, data, ssm, parity, &rec->data);
}
// 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, &msgCount, &usedBytes, &freeBytes);
if (rc)
return rc;
}while (msgCount!=0);
// Makse sure they are received
mxfSleep(100);
return rc;
}
/***************************************************************************************************************/
// read717Acquisition
/***************************************************************************************************************/
uint32 read717Acquisition(HMXF_BUFFER rxBuffer, MXF_A717_DATAREC *rx717HostBuffer)
{
uint64 status, msgsCount, bytesCount;
uint64 word, data;
uint32 rc;
printf("\nA717 reading\n");
// Reads and display records
rc = mxfA717RxAcqRead(rxBuffer, 0, BUFFER_SIZE, &status, &msgsCount, &bytesCount, rx717HostBuffer);
if(!rc)
printf("String received count = %llu \n", msgsCount);
if(!rc)
{
// Displays received strings
recPtr = rx717HostBuffer;
for(data=0; data<msgsCount && !rc; data++)
{
printf("\n%02llu: Timetag=%012llu, Size=%u words\n", data, recPtr->timeTag, (recPtr->dataSize)/2);
for(word=0; word < SUBFRAMESIZE ; word++)
{
if (recPtr->data[word])
printf("%03X ", recPtr->data[word]);
else
printf("--- ");
}
printf("\n");
mxfA717NextDataRecordPtrGet(recPtr, &recPtr);
}
}
if(rc)
printf("A717 acquisition read failed; rc=0x%08x\n", rc);
return rc;
}
/***************************************************************************************************************/
// read429Acquisition
/***************************************************************************************************************/
uint32 read429Acquisition(HMXF_BUFFER rxBuffer, uint64 *msgsCount429, MXF_A429_DATAREC *rec429)
{
MXF_A429_DATAREC* recPtr=rec429;
uint64 status, bytesCount;
uint64 label, sdi, data, ssm, parity;
uint64 j;
uint32 rc;
printf("\nA429 reading\n");
// Reads and displays records
rc = mxfA429RxAcqRead(rxBuffer, 0, BUFFER_SIZE, &status, msgsCount429, &bytesCount, rec429);
for (j=0; j < (*msgsCount429) && !rc; j++)
{
rc = mxfA429ArwDecompose(recPtr->data, &label, &sdi, &data, &ssm, &parity);
if(!rc)
{
printf("%02llu: Timetag %llu - ARINC429 word=[%03llo,%lld,%05llX,%lld,%s]\n",
j, recPtr->timeTag, label, sdi, data, ssm, (parity==VMXF_A429_PARITY_ODD)?"ODD":"EVEN");
if(!rc)
rc = mxfA429NextDataRecordPtrGet(recPtr, &recPtr);
}
}
if(rc)
printf("A429 acquisition read failed; rc=0x%08x\n", rc);
return rc;
}
/***************************************************************************************************************/
// Decodes the data in 429 and 717 to display them in engineering writing
/***************************************************************************************************************/
uint32 writeEng (MXF_A429_DATAREC *rec429, uint64 msgsCount429, MXF_A717_DATAREC* rec717)
{
uint32 rc=MAXT_SUCCESS;
MXF_A429_DATAREC* recPtr429 = rec429;
MXF_A717_DATAREC* recPtr717;
uint64 label, sdi, data429, ssm, parity;
uint64 iMsgCount, iSubframe;
uint64 data717, NbOfSubframes=0, subframes[4] = {0}, NbOfWords=0, words[10] = {0};
strucEncoding encoding;
double real429, real717;
int digits;
memset(&encoding, 0, sizeof(encoding));
printf("\n\n"
"---------------------------------------------------------------------\n"
"| Label | Value received in A429 | Value received in A717 |\n"
"---------------------------------------------------------------------\n");
for (iMsgCount = 0; iMsgCount < msgsCount429; iMsgCount++)
{
real429 = 0;
real717 = 0;
recPtr717 = rec717;
// A429
rc = mxfA429ArwDecompose(recPtr429->data, &label, &sdi, &data429, &ssm, &parity);
if (!rc)
ARINC717DataDefinition(label, &NbOfSubframes, subframes, &NbOfWords, words, &encoding);
if (!rc)
{
data429 <<= 10;
rc = mxfA429ArwBnrToReal((uint32)data429, encoding.dataRange, encoding.bitRange429, &real429);
}
// A717
if (!rc)
{
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 = recPtr717->data[words[0]-1];
data717 <<= 17;
if (!rc)
rc = mxfA429ArwBnrToReal((uint32)data717, encoding.dataRange, encoding.bitRange717, &real717);
}
else
{
rc = mxfA717NextDataRecordPtrGet(recPtr717, &recPtr717);
}
}
}
if (!rc)
rc = mxfA429NextDataRecordPtrGet(recPtr429, &recPtr429);
//prints according to the number of digits
if(fabs(real429)>=100000)
digits = 0;
else if(fabs(real429)>=10000)
digits = 1;
else if(fabs(real429)>=100)
digits = 2;
else
digits = 3;
printf("| %03llo | % 8.*f | % 8.*f |\n", label, digits, real429, digits, real717);
}
printf("---------------------------------------------------------------------\n");
return rc;
}
uint32 initHandler(HMXF_SERVER server, uint64 deviceIndex, uint64 moduleIndex, uint64 channelIndex, uint64 attrib, uint64* value)
{
HMXF_DEVICE device;
MXF_DEVICE_INFO deviceInfo;
uint32 rc;
server=server;
deviceIndex=deviceIndex;
if(attrib == KMXF_CHANNEL_CLASS)
{
rc = mxfSystemDeviceGet(server, deviceIndex, &device);
if (!rc)
rc = mxfDeviceInfoGet(device, &deviceInfo);
if(!rc && (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 TRUE;
}
}
}
return FALSE;
}
Updated 10/23/2023