MX Foundation 4
hdlc_flexsmp.c
/*****************************************************************************
//
// File:
// hdlc_flexSMP.c
//
// Copyright (c) MAX Technologies Inc. 1988-2023, All Rights Reserved.
// CONFIDENTIAL AND PROPRIETARY INFORMATION WHICH IS THE
// PROPERTY OF MAX TECHNOLOGIES INC.
//
// This example demonstrates the basic usage of HDLC channel class
// for transmission and reception on FlexSMP Module.
//
// Hardware requirements:
// - MAXT FlexMax Device with FlexSMP Module with HDLC channels
//
*****************************************************************************/
#include "example.h"
//#define LOCAL
//#define LOOPBACK
int main(void) {
uint32 rc = MAXT_SUCCESS;
HMXF_SERVER server = 0;
HMXF_CHANNEL rxChannel = 0;
HMXF_CHANNEL txChannel = 0;
size_t bufferSize = 0;
HMXF_BUFFER mxfRxBuffer = 0;
HMXF_BUFFER mxfTxBuffer = 0;
uint64 rxAcqStatus = 0;
uint64 msgCount = 0, byteCount = 0;
//Get Server Handle
#ifdef LOCAL
rc = mxfConnectPCIE(&server);
#else
rc = mxfConnectEthernet("192.168.0.1", "admin", "admin", FALSE, &server);
#endif
// Initialize MX Foundation library
if (!rc) {
printf("Initializing ...\n");
rc = mxfSystemInit(server);
}
//Get Receiver (Rx) Channel Handle
if (!rc) {
rc = mxfChannelGet(server, MXF_CLASS_HDLC, MXF_SCLASS_RX_CHANNEL, MXF_MODULE_FLEXSMP, 0, &rxChannel);
}
//Get Transmiter(Tx) Channel Handle
if (!rc) {
rc = mxfChannelGet(server, MXF_CLASS_HDLC, MXF_SCLASS_TX_CHANNEL, MXF_MODULE_FLEXSMP, 0, &txChannel);
}
//Set Data Encoding
if (!rc) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_HDLC_DATA_ENCODING, VMXF_HDLC_ENCODING_NRZ);
}
if (!rc) {
rc = mxfAttributeUint64Set(txChannel, KMXF_HDLC_DATA_ENCODING, VMXF_HDLC_ENCODING_NRZ);
}
//Set Clock Frequency to 1 Mbps
if (!rc) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_HDLC_INTERNAL_CLOCK_FREQ, 1000000);
}
if (!rc) {
rc = mxfAttributeUint64Set(txChannel, KMXF_HDLC_INTERNAL_CLOCK_FREQ, 1000000);
}
//Enable InterFrame Flags
if (!rc) {
rc = mxfAttributeUint64Set(txChannel, KMXF_HDLC_TX_INTERFRAME_TIME_FILL, VMXF_HDLC_TX_INTERFRAME_TIME_FILL_FLAGS);
}
//Disable Frame Size
if (!rc) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_HDLC_FRAME_SIZE_ENABLE, VMXF_DISABLE);
}
if (!rc) {
rc = mxfAttributeUint64Set(txChannel, KMXF_HDLC_FRAME_SIZE_ENABLE, VMXF_DISABLE);
}
//Set FCS Type
if (!rc) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_HDLC_FCS_TYPE, VMXF_HDLC_TX_RX_FCS_CCITT);
}
if (!rc) {
rc = mxfAttributeUint64Set(txChannel, KMXF_HDLC_FCS_TYPE, VMXF_HDLC_TX_RX_FCS_CCITT);
}
//Set Electrical interface
if (!rc) {
rc = mxfAttributeUint64Set(txChannel, KMXF_HDLC_ELECTRICAL_INTERFACE, VMXF_HDLC_ELECTRICAL_INTERFACE_RS485);
}
// Set Electrical Termination to 120 Ohm
if(!rc) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_HDLC_TERMINATION, VMXF_HDLC_TERMINATION_120OHM);
}
if(!rc) {
rc = mxfAttributeUint64Set(txChannel, KMXF_HDLC_TERMINATION, VMXF_HDLC_TERMINATION_120OHM);
}
#ifdef LOOPBACK
//Set Channel loopback
if (!rc) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_HDLC_TX_RX_TEST_LB, VMXF_ENABLE);
}
#endif
//Enable HDLC Channels and corresponding clock source
if (!rc) {
rc = mxfHDLCChannelEnable(rxChannel, VMXF_HDLC_CLOCK_SOURCE_EXTERNAL);
}
if (!rc) {
rc = mxfHDLCChannelEnable(txChannel, VMXF_HDLC_CLOCK_SOURCE_INTERNAL);
}
bufferSize = (uint64)sizeof(MXF_HDLC_DATAREC);
// Allocate acquisition static buffer
if (!rc) {
rc = mxfRxAcqBufferAlloc(rxChannel, bufferSize, &mxfRxBuffer, NULL);
}
//Start acquisition service
if (!rc) {
rc = mxfRxAcqStart(mxfRxBuffer, MXF_RXACQ_FLAG_DEFAULT, 0, 0);
}
// Allocate TX Aperiodic static buffer
if (!rc) {
rc = mxfTxAperiodicBufferAlloc(txChannel, MXF_TXAPERIODIC_PRIORITY_HIGH, bufferSize, &mxfTxBuffer, NULL);
}
// Transmit One Record of 4 words
if (!rc) {
char* data = "Hello, World!";
txRec.reserved = 0;
txRec.timeTag = 0;
txRec.control = 0;
txRec.repeatCount = 1;
txRec.dataSize = (uint32)strlen(data)+1+2; // data + FCS
memcpy(txRec.data, data, txRec.dataSize);
printf("Transmitting ...\n");
rc = mxfHDLCTxAperiodicWrite(mxfTxBuffer, MXF_TXAPERIODIC_FLAG_DEFAULT, 0, 1, &txRec);
}
//Wait
if (!rc) {
mxfSleep(1000);
}
// Read received record
if (!rc) {
printf("Receiving ...\n");
rc = mxfHDLCRxAcqRead(mxfRxBuffer, 1, bufferSize, &rxAcqStatus, &msgCount, &byteCount, &rxRec);
// Display received string
if(!rc && msgCount == 1) {
printf(" Timetag: %012"PRIu64", Size: %u\n", rxRec.timeTag, rxRec.dataSize);
printf(" String: %s\n", (char*)rxRec.data);
}
}
// Stop acquisition
if (!rc) {
rc = mxfRxAcqStop(mxfRxBuffer);
}
//Disable HDLC Channels and associated clock
if (!rc) {
rc = mxfHDLCChannelDisable(rxChannel);
}
if (!rc) {
rc = mxfHDLCChannelDisable(txChannel);
}
// Display Return Error Codes
if (rc) {
char errorString[200];
if (mxfSystemErrorStringGet(server, rc, sizeof(errorString), errorString)) {
sprintf(errorString, "ERROR # 0x%X", rc);
}
printf("%s\n\r", errorString);
}
printf("Terminating ...\n");
// Free mxf Buffers
if (mxfRxBuffer) {
mxfRxAcqBufferFree(mxfRxBuffer);
}
if (mxfTxBuffer) {
}
// Unload MX Foundation library
// Disconnect from MX Foundation library
printf("\nPress a key to exit\n");
getchar();
return 0;
}
Updated 10/23/2023