MX Foundation 4
irigb_1pps.c
/*****************************************************************************
//
// File:
// irigb_1pps.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 generate the 1PPS signal, to be used
// with IRIG-B generator, with a discrete output pin.
//
// Hardware requirements:
// - MAXT Flex.
//
*****************************************************************************/
#include "example.h"
#include <time.h>
//#define LOCAL
int main(void)
{
uint32 rc;
HMXF_SERVER server = 0;
HMXF_DEVICE device = 0;
HMXF_MODULE module = 0;
HMXF_CHANNEL txChannel = 0;
HMXF_BUFFER txBuffer = 0;
uint64 moduleCount = 0;
uint64 channelCount = 0;
size_t txBufferSize = 0;
MXF_DISCRETE_DATAREC* txHostBuffer = 0;
uint64 irigbStatus = 0;
uint64 timer = 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);
getchar();
return 0;
}
// Initializes MX Foundation library
if (!rc)
{
printf("Starting ...\n");
rc = mxfSystemInit(server);
}
// Gets the device handle
if (!rc)
rc = mxfSystemDeviceGet(server, 0, &device);
// Gets handle of first discrete module
if (!rc)
rc = mxfDeviceModuleAllGet(device, MXF_MODULE_DIOFIFO_EH, 1, &moduleCount, &module);
// Gets handle of first discrete output channel
if (!rc)
rc = mxfModuleChannelAllGet(module, MXF_CLASS_DISCRETE, MXF_SCLASS_TX_CHANNEL, 1, &channelCount, &txChannel);
// If channel not found, return an error
if (!rc && !channelCount)
rc = MAXT_ERROR_NOT_FOUND;
// Allocate buffer for tx data
if (!rc)
{
txBufferSize = sizeof(MXF_DISCRETE_DATAREC);
// Allocates TX Aperiodic static buffer for HIGH priority queue
rc = mxfTxAperiodicBufferAlloc(txChannel, MXF_TXAPERIODIC_PRIORITY_HIGH, txBufferSize, &txBuffer, NULL);
// Host buffer allocation
if (!rc)
{
txHostBuffer = (MXF_DISCRETE_DATAREC*)calloc(1, txBufferSize);
if (!txHostBuffer)
rc = MAXT_ERROR_MEM;
}
}
// Configure IRIG-B
// Set IRIG-B time to current time
if (!rc)
{
time_t currentTime = time(NULL);
struct tm * ptm = gmtime(&currentTime);
uint64 bcd;
//Time ellapsed since 1 jan 1970 (UTC)
rc = mxfDeviceIrigbBcdCompose(ptm->tm_year - 70, ptm->tm_yday + 1, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, &bcd);
if (!rc)
rc = mxfAttributeUint64Set(device, KMXF_DEVICE_IRIGB_GEN_BCD_TIME, bcd);
}
// Enable IRIG-B generator
if (!rc)
{
printf("Configuring IRIG-B\n");
rc = mxfAttributeUint64Set(device, KMXF_DEVICE_IRIGB_GEN_ENABLE, TRUE);
}
// Enable IRIG-B internal loopback
if (!rc)
rc = mxfAttributeUint64Set(device, KMXF_DEVICE_IRIGB_GEN_LOOPBACK_ENABLE, TRUE);
// Set IRIG-B input to device input
if (!rc)
rc = mxfAttributeUint64Set(device, KMXF_DEVICE_IRIGB_INPUT, VMXF_DEVICE_IRIGB_INPUT_DEVICE);
// Set IRIG-B signal to digital
if (!rc)
rc = mxfAttributeUint64Set(device, KMXF_DEVICE_IRIGB_INPUT_SIGNAL, VMXF_DEVICE_IRIGB_INPUT_SIGNAL_DIGITAL);
// Wait IRIG-B signal locked
if (!rc)
{
do
{
rc = mxfDeviceIrigbStatusGet(device, &irigbStatus);
} while (!rc && (irigbStatus != MXF_IRIGB_STATUS_NO_SIGNAL) && (irigbStatus != MXF_IRIGB_STATUS_LOCKED));
}
// Set timebase to IRIG-B nsec
if (!rc)
{
if (irigbStatus == MXF_IRIGB_STATUS_LOCKED)
rc = mxfSystemTimeBaseSet(server, MXF_TIMEBASE_IRIGB_NSEC);
else
{
printf("No IRIG-B signal found\n\r");
rc = MAXT_ERROR_IRIGB_NO_SIGNAL;
}
}
if (!rc)
{
// Prepares 1PPS
rec = txHostBuffer;
rec->timeTag = 0;
rec->control = MXF_DISCRETE_TX_REC_CTRL_PULSE_START;
rec->repeatCount = 0;
rec->data = 0x0001; // 1PPS will be on pin #0 High
rec->edge = 0x0001;
rec->highDuration = (uint32)(500000); // 5 msec Hi
rec->lowDuration = (uint32)(99500000); // 995 msec Low
rc = mxfDeviceTimerGet(device, &timer);
}
if (!rc)
{
// Prepare start time
timer /= 1*1000*1000*1000; // Round time to second
timer *= 1*1000*1000*1000;
timer += 2*1000*1000*1000; // Add 2 seconds to be in the future
printf("Starting 1PPS ...\n");
rc = mxfDiscreteTxAperiodicWrite(txBuffer, MXF_TXAPERIODIC_FLAG_ABSOLUTE_START_TIME, timer, 1, txHostBuffer);
}
// Run for 10 seconds
if (!rc)
{
mxfSleep(10000);
}
// Stop 1PPS
if (!rc)
{
// Prepares record
rec = txHostBuffer;
rec->timeTag = 0;
rec->control = 0;
rec->repeatCount = 1;
rec->data = 0x0000;
rec->edge = 0x0001;
rec->highDuration = 0;
rec->lowDuration = 0;
rc = mxfDiscreteTxAperiodicWrite(txBuffer, MXF_TXAPERIODIC_FLAG_DEFAULT, 0, 1, txHostBuffer);
}
// Frees device and host buffers
if (txBuffer)
if (txHostBuffer)
free(txHostBuffer);
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");
// Unloads MX Foundation library
// Disconnects from MX Foundation library
printf("\nPress a key to terminate\n");
getchar();
return rc;
}
Updated 10/23/2023