MX Foundation 4
csdb_flexsmp.cs
/*****************************************************************************
//
// File:
// csdb_flexsmp.cs
//
// 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 CSDB channel class
// for transmission and reception on FlexSMP Module.
//
// Hardware requirements:
// - MAXT FlexMax Device with FlexSMP Module with CSDB channels
//
*****************************************************************************/
//#define LOCAL
//#define LOOPBACK
using System;
using static MAXT.MXFoundation.mxf;
using System.Runtime.InteropServices;
using System.Text;
using System.ComponentModel;
namespace csdb_flexsmp_example {
class csdb_flexsmp {
private const int BLOCK_COUNT = 8;
static void Main(string[] args) {
UInt32 rc = MAXT_SUCCESS;
UInt64 server = 0;
UInt64 rxChannel = 0;
UInt64 txChannel = 0;
UInt64 bufferSize = 0;
UInt64 mxfRxBuffer = 0;
UInt64 mxfTxBuffer = 0;
var txRec = new MXF_CSDB_DATAREC[2]{
new MXF_CSDB_DATAREC() { data = new byte[12] },
new MXF_CSDB_DATAREC() { data = new byte[12] }
};
var rxRec = new MXF_CSDB_DATAREC[2]{
new MXF_CSDB_DATAREC() { data = new byte[12] },
new MXF_CSDB_DATAREC() { data = new byte[12] }
};
IntPtr recPtr = IntPtr.Zero;
UInt64 rxAcqStatus = 0;
UInt64 msgCount = 0, byteCount = 0;
UInt64 iData = 0;
//Get Server Handle
#if (LOCAL)
rc = mxfConnectPCIE(out server);
#else
rc = mxfConnectEthernet("192.168.0.1", "admin", "admin", Convert.ToUInt64(false), out server);
#endif
// Initialize MX Foundation library
if (rc == MAXT_SUCCESS) {
Console.WriteLine("Initializing ...");
rc = mxfSystemInit(server);
}
//Get Receiver (Rx) Channel Handle
if (rc == MAXT_SUCCESS) {
rc = mxfChannelGet(server, MXF_CLASS_ALL, MXF_SCLASS_RX_CHANNEL, MXF_MODULE_FLEXSMP, 0, out rxChannel);
}
//Get Transmiter(Tx) Channel Handle
if (rc == MAXT_SUCCESS) {
rc = mxfChannelGet(server, MXF_CLASS_ALL, MXF_SCLASS_TX_CHANNEL, MXF_MODULE_FLEXSMP, 0, out txChannel);
}
//Set Channel Class
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_CHANNEL_CLASS, MXF_CLASS_CSDB);
}
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(txChannel, KMXF_CHANNEL_CLASS, MXF_CLASS_CSDB);
}
//Set speed to 50 Kbps
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_CSDB_SPEED, 50000);
}
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(txChannel, KMXF_CSDB_SPEED, 50000);
}
//Set Parity to odd
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_CSDB_PARITY, VMXF_CSDB_PARITY_ODD);
}
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(txChannel, KMXF_CSDB_PARITY, VMXF_CSDB_PARITY_ODD);
}
//Set Stop bit size to 1
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_CSDB_STOPBITSIZE, 1);
}
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(txChannel, KMXF_CSDB_STOPBITSIZE, 1);
}
//Set BLock Count
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_CSDB_BLOCKCOUNT, BLOCK_COUNT);
}
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(txChannel, KMXF_CSDB_BLOCKCOUNT, BLOCK_COUNT);
}
//Set Termination to 120 Ohm
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_CSDB_TERMINATION, VMXF_CSDB_TERMINATION_120OHM);
}
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(txChannel, KMXF_CSDB_TERMINATION, VMXF_CSDB_TERMINATION_120OHM);
}
# if LOOPBACK
//Set Channel loopback
if (rc == MAXT_SUCCESS) {
rc = mxfAttributeUint64Set(rxChannel, KMXF_CSDB_TX_RX_TEST_LB, VMXF_ENABLE);
}
#endif
bufferSize = 2 * (UInt64)Marshal.SizeOf(typeof(MXF_CSDB_DATAREC));
// Allocate acquisition static buffer
if (rc == MAXT_SUCCESS) {
rc = mxfRxAcqBufferAlloc(rxChannel, bufferSize, out mxfRxBuffer, IntPtr.Zero);
}
//Start acquisition service
if (rc == MAXT_SUCCESS) {
rc = mxfRxAcqStart(mxfRxBuffer, MXF_RXACQ_FLAG_DEFAULT, 0, 0);
}
// Allocate TX Aperiodic static buffer
if (rc == MAXT_SUCCESS) {
rc = mxfTxAperiodicBufferAlloc(txChannel, MXF_TXAPERIODIC_PRIORITY_HIGH, bufferSize, out mxfTxBuffer, IntPtr.Zero);
}
// Transmit one Label
if (rc == MAXT_SUCCESS) {
//Sync Block
txRec[0].reserved = 0;
txRec[0].timeTag = 0;
txRec[0].control = 0;
txRec[0].repeatCount = 1;
for (int iByte = 0; iByte < BLOCK_COUNT; iByte++) {
txRec[0].data[iByte] = 0xA5;
}
// Label = 6, SI = 2
txRec[1].reserved = 0;
txRec[1].timeTag = 0;
txRec[1].control = 0;
txRec[1].repeatCount = 1;
txRec[1].data[0] = 6;
txRec[1].data[1] = 2;
for (int iByte = 2; iByte < BLOCK_COUNT; iByte++) {
txRec[1].data[iByte] = (byte)(0x11 * iByte);
}
IntPtr txRecBufferPtr = IntPtr.Zero;
try {
txRecBufferPtr = Marshal.AllocHGlobal((int)bufferSize);
}
catch (OutOfMemoryException) {
rc = MAXT_ERROR_MEM;
}
if (rc == MAXT_SUCCESS) {
recPtr = txRecBufferPtr;
Marshal.StructureToPtr(txRec[0], recPtr, false);
rc = mxfCSDBNextDataRecordPtrGet(recPtr, out recPtr);
if (rc == MAXT_SUCCESS) {
Marshal.StructureToPtr(txRec[1], recPtr, false);
Console.WriteLine("Transmitting ...");
rc = mxfCSDBTxAperiodicWrite(mxfTxBuffer, MXF_TXAPERIODIC_FLAG_DEFAULT, 0, 2, txRecBufferPtr);
}
}
if (txRecBufferPtr != IntPtr.Zero) {
Marshal.FreeHGlobal(txRecBufferPtr);
}
}
//Wait
if (rc == MAXT_SUCCESS) {
mxfSleep(1000);
}
if (rc == MAXT_SUCCESS) {
IntPtr rxRecBufferPtr = IntPtr.Zero;
try {
rxRecBufferPtr = Marshal.AllocHGlobal((int)bufferSize);
}
catch (OutOfMemoryException) {
rc = MAXT_ERROR_MEM;
}
// Read received record
if (rc == MAXT_SUCCESS) {
Console.WriteLine("Receiving ...");
rc = mxfHDLCRxAcqRead(mxfRxBuffer, 2, bufferSize, out rxAcqStatus, out msgCount, out byteCount, rxRecBufferPtr);
if (rc == MAXT_SUCCESS && msgCount == 2) {
Console.WriteLine("Frame received count = {0:D}", msgCount);
recPtr = rxRecBufferPtr;
for (UInt64 i = 0; i < msgCount && rc == MAXT_SUCCESS; i++) {
if (rc == MAXT_SUCCESS) {
rxRec[i] = Marshal.PtrToStructure<MXF_CSDB_DATAREC>(recPtr);
}
rc = mxfCSDBNextDataRecordPtrGet(recPtr, out recPtr);
}
}
}
// Display received Records
for (UInt64 i = 0; i < msgCount && rc == MAXT_SUCCESS; i++) {
Console.WriteLine();
Console.WriteLine(" Record #{0}, Timetag: {0} Size: {1}", i, rxRec[i].timeTag, BLOCK_COUNT);
Console.Write(" Data:");
for (iData = 0; iData < BLOCK_COUNT; iData++) {
Console.Write(" {0:X2}", rxRec[i].data[iData]);
}
Console.WriteLine();
}
if (rxRecBufferPtr != IntPtr.Zero) {
Marshal.FreeHGlobal(rxRecBufferPtr);
}
}
// Stop acquisition
if (rc == MAXT_SUCCESS) {
rc = mxfRxAcqStop(mxfRxBuffer);
}
// Display Return Error Codes
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);
}
Console.WriteLine();
Console.WriteLine("Terminating...");
// Free mxf buffers
if (mxfRxBuffer != 0) {
mxfRxAcqBufferFree(mxfRxBuffer);
}
if (mxfTxBuffer != 0) {
}
// Unload MX Foundation library
// Disconnect from MX Foundation library
Console.WriteLine();
Console.WriteLine("Press enter to exit");
Console.Read();
return;
}
}
}
Updated 10/23/2023