MX Foundation 4
mil1553_embedded_update_host.c
/*****************************************************************************
//
// File:
// mil1553_embedded_update_host.c
//
// Copyright (c) MAX Technologies Inc. 1988-2016, All Rights Reserved.
// CONFIDENTIAL AND PROPRIETARY INFORMATION WHICH IS THE
// PROPERTY OF MAX TECHNOLOGIES INC.
//
// This example demonstrates how to transmit information from host to
// embedded application. The communication queues are used to communicate
// between host and embedded application part. Data from communication
// queue is used to update BC message. Asynchronous event is used for
// data communication queue threshold.
//
// This file is used to generate the host part of the application.
// mil1553_embedded_update_embedded.c file is used for the embedded part
// of the application.
//
// Hardware requirements:
// - MAXT Flex1553-PCIe or FlexMulti.
//
*****************************************************************************/
#include "example.h"
#define MAX_TX_RECORDS_TO_TRANSMIT 8
#define EX_USER_COMMAND_ID_START 0x80000001
#define EX_USER_COMMAND_ID_STOP 0x80000002
#define EX_USER_COMMAND_ID_READ 0x80000003
#define EX_USER_COMMAND_ID_TERMINATE 0x80000005
#define EX_USER_COMMAND_ACK 0xA5A5A5A5
#define DWORD_SWAP(dword) ((dword & 0x0000ffff) << 16 | (dword & 0xffff0000) >> 16)
#define LOOPBACK
typedef struct
{
HMXF_SERVER server;
HMXF_DEVICE device;
HMXF_MODULE module1553;
HMXF_CHANNEL bcChannel;
HMXF_CHANNEL bmChannel;
HMXF_BUFFER commTxBuffer;
HMXF_BUFFER commRxBuffer;
HMXF_BUFFER commTxUpdateDataBuffer;
}
TEST_INFO;
typedef struct
{
uint32 command;
uint32 paramNum;
uint32 param[32];
}
EX_COMMAND;
uint32 initHandler(HMXF_SERVER server, uint64 deviceIndex, uint64 moduleIndex, uint64 channelIndex, uint64 attrib, uint64* value);
uint32 commandSend(HMXF_BUFFER txBuffer, HMXF_BUFFER rxBuffer, EX_COMMAND* cmd);
uint32 commandRead(HMXF_BUFFER rxBuffer, uint64* readCnt, EX_COMMAND* cmd);
uint32 hostPart(TEST_INFO info);
int
main(void)
{
TEST_INFO info;
uint32 rc;
uint64 moduleCount=0;
uint64 channelCount=0;
char temp[10];
// Connect to MX Foundation library
rc = mxfServerConnect("0.0.0.0", "", "", FALSE, &info.server);
// Set initialisation handler
if(!rc)
rc = mxfSystemInitAttributeUint64CallbackHandler(info.server, &initHandler);
// Initialize MX Foundation library
if(!rc)
{
printf("Starting ...\n\r");
rc = mxfSystemInit(info.server);
}
// Get the device handle
if (!rc)
rc = mxfSystemDeviceGet(info.server, 0, &info.device);
// Get handle of first 1553-EH module
if(!rc)
rc = mxfDeviceModuleAllGet(info.device, MXF_MODULE_MIL1553MRT_EH, 1, &moduleCount, &info.module1553);
// Get handle of first MIL1553 BC channel
if(!rc && moduleCount)
rc = mxfModuleChannelAllGet(info.module1553, MXF_CLASS_MIL1553, MXF_SCLASS_BC_CHANNEL, 1, &channelCount, &info.bcChannel);
// Get handle of first MIL1553 BM channel
if(!rc && channelCount)
rc = mxfModuleChannelAllGet(info.module1553, MXF_CLASS_MIL1553, MXF_SCLASS_BM_CHANNEL, 1, &channelCount, &info.bmChannel);
if(!rc && !channelCount)
rc = MAXT_ERROR_NOT_FOUND;
if(!rc)
rc = hostPart(info);
if(rc)
{
char errorString[200];
if(mxfSystemErrorStringGet(info.server, rc, sizeof(errorString), errorString))
sprintf (errorString,"ERROR # 0x%X", rc);
printf("%s\n\r", errorString);
}
printf("Terminating ...\n\r");
// Unload MX Foundation library
mxfSystemResourcesRelease(info.server, 0);
// Disconnect from MX Foundation library
mxfServerDisconnect(info.server);
printf("Press enter to terminate\n\r");
fgets(temp, 10, stdin);
return rc;
}
uint32
initHandler(HMXF_SERVER server, uint64 deviceIndex, uint64 moduleIndex, uint64 channelIndex, uint64 attrib, uint64* value)
{
server=server;
deviceIndex=deviceIndex;
moduleIndex=moduleIndex;
channelIndex=channelIndex;
if(attrib == KMXF_DEVICE_COMM_QUEUE_NUM)
{
// Set the communication queue number attribute
*value = 3;
return TRUE;
}
return FALSE;
}
uint32
commandSend(HMXF_BUFFER txBuffer, HMXF_BUFFER rxBuffer, EX_COMMAND* cmd)
{
uint64 readCnt=0;
uint64 byteCnt;
uint32 rc=0;
memset(&msg, 0, sizeof(msg));
msg.dataSize = (2+cmd->paramNum)*4;
memcpy(msg.data, cmd, msg.dataSize);
// Write command in the communication queue
rc=mxfDeviceCommBufferWrite(txBuffer, 1, &msg);
if(!rc && rxBuffer)
{
while(!rc)
{
// Wait acknowledge of embedded application
rc=mxfDeviceCommBufferRead(rxBuffer, 1, sizeof(msg), &readCnt, &byteCnt, &msg);
if(!rc && readCnt)
{
if((msg.dataSize >= 8) && (msg.data[0]==EX_USER_COMMAND_ACK))
{
if(msg.dataSize >= 12)
rc = msg.data[2];
break;
}
}
}
}
return rc;
}
uint32
commandRead(HMXF_BUFFER rxBuffer, uint64* readCnt, EX_COMMAND* cmd)
{
uint64 byteCnt;
uint32 rc;
memset(cmd, 0, sizeof(*cmd));
// Read command from the communication queue
rc=mxfDeviceCommBufferRead(rxBuffer, 1, sizeof(*cmd), readCnt, &byteCnt, &msg);
if(!rc && *readCnt)
{
cmd->command = msg.data[0];
cmd->paramNum = msg.data[1];
memcpy(cmd->param, &msg.data[2], cmd->paramNum*4);
}
return rc;
}
uint32
hostPart(TEST_INFO info)
{
EX_COMMAND cmd;
MXF_EMBEDDED_DATAREC* commRec=NULL;
uint32 rc=0;
MXF_EMBEDDED_DATAREC* txHostBuffer=0;
size_t txBufferSize=0;
uint64 data;
uint64 word;
uint64 byte;
uint32* dw;
MXF_EMBEDDED_DATAREC* rxHostBuffer=0;
size_t rxBufferSize=0;
#ifdef LOOPBACK
// Set internal loopback Mil1553 channel
rc=mxfAttributeUint64Set(info.bmChannel, KMXF_MIL1553_TX_RX_TEST_LB, VMXF_ENABLE);
#endif
if(!rc)
{
// Allocate 10 KB buffer for TX communication queue
txBufferSize = 10*1024;
// Allocate buffer for comm queue #0
rc=mxfDeviceCommBufferAlloc(info.device, 0, txBufferSize, &info.commTxBuffer, NULL);
}
// Allocate 10 KB buffer for RX communication queue
if(!rc)
{
rxBufferSize = 10*1024;
// Allocate buffer for comm queue #1
rc=mxfDeviceCommBufferAlloc(info.device, 1, rxBufferSize, &info.commRxBuffer, NULL);
// Host buffer allocation
if(!rc)
{
rxHostBuffer = (MXF_EMBEDDED_DATAREC*)calloc(1, rxBufferSize);
if(!rxHostBuffer)
rc = MAXT_ERROR_MEM;
}
}
// Allocate 1 KB buffer for TX communication update data queue
if(!rc)
{
txBufferSize = 1*1024;
// Allocate buffer for comm queue #2
rc=mxfDeviceCommBufferAlloc(info.device, 2, txBufferSize, &info.commTxUpdateDataBuffer, NULL);
// Host buffer allocation
if(!rc)
{
txHostBuffer = (MXF_EMBEDDED_DATAREC*)calloc(1, txBufferSize);
if(!txHostBuffer)
rc = MAXT_ERROR_MEM;
}
}
// Upload and start embedded part
if(!rc)
{
rc=mxfDeviceFileUpload(info.device, MXF_DEVICE_FILETYPE_APPLICATION, "mil1553_embedded_update_embedded-flex.mxf");
}
// Send START command to embedded part
if(!rc)
{
cmd.command=EX_USER_COMMAND_ID_START;
cmd.paramNum=0;
rc=commandSend(info.commTxBuffer, info.commRxBuffer, &cmd);
}
// Send update data to embedded part
if(!rc)
{
// TX data simulation
commRec = txHostBuffer;
for(data=0; data<MAX_TX_RECORDS_TO_TRANSMIT; data++)
{
commRec->timeTag = 0;
commRec->control = 0;
commRec->repeatCount = 1;
commRec->dataSize = 18;
commRec->data[0] = 0;
for(word=1; word <= (commRec->dataSize-2)/2; word++)
((uint16*)commRec->data)[word] = (uint16)data;
for(byte=0, dw=(uint32*)commRec->data; byte<commRec->dataSize; byte+=4, dw++)
*dw=DWORD_SWAP(*dw);
mxfNextRecordPtrGet(MXF_CLASS_EMBEDDED, MXF_RECTYPE_DATAREC, commRec, (void**)&commRec);
}
printf("Transmitting simulation data...\n\r");
rc=mxfDeviceCommBufferWrite(info.commTxUpdateDataBuffer, MAX_TX_RECORDS_TO_TRANSMIT, txHostBuffer);
}
// Wait 2 seconds
if(!rc)
mxfSleep(2000);
// Send STOP command to embedded part
if(!rc)
{
cmd.command=EX_USER_COMMAND_ID_STOP;
cmd.paramNum=0;
rc=commandSend(info.commTxBuffer, info.commRxBuffer, &cmd);
}
// Send READ command to embedded part
if(!rc)
{
cmd.command=EX_USER_COMMAND_ID_READ;
cmd.paramNum=0;
rc=commandSend(info.commTxBuffer, info.commRxBuffer, &cmd);
// Give time to read before terminating
if(!rc)
mxfSleep(100);
}
// Send TERMINATE command to embedded part
if(!rc)
{
cmd.command=EX_USER_COMMAND_ID_TERMINATE;
cmd.paramNum=0;
rc=commandSend(info.commTxBuffer, info.commRxBuffer, &cmd);
}
// Free host buffers
if(txHostBuffer)
free(txHostBuffer);
if(rxHostBuffer)
free(rxHostBuffer);
return rc;
}
Updated 10/23/2023