MX Foundation 4
pulse.c
/*****************************************************************************
//
// File:
// pulse.c
//
// Copyright (c) MAX Technologies Inc. 1988-2020, All Rights Reserved.
// CONFIDENTIAL AND PROPRIETARY INFORMATION WHICH IS THE
// PROPERTY OF MAX TECHNOLOGIES INC.
//
// This example demonstrates the basic usage of aperiodic transmit service with PULSE
// channel class.
//
// Hardware requirements:
// - MAXT 500 series carrier board with IPM-MULTI.
//
*****************************************************************************/
#include <mxfapi.h>
uint32 initHandler(HMXF_SERVER server, uint64 deviceIndex, uint64 moduleIndex, uint64 channelIndex, uint64 attrib, uint64* value);
int main(void)
{
HMXF_SERVER server;
HMXF_DEVICE device=0;
HMXF_CHANNEL txChannel=0;
HMXF_BUFFER txBuffer=0;
uint32 rc;
char szTemp[32];
uint64 timer=0, time=0;
rc = mxfServerConnect("0.0.0.0", "", "", FALSE, &server);
// Configuration of the Multi port in PULSE
if (!rc)
if(!rc)
rc = mxfSystemInit(server);
// Get the first detected Pulse channel.
if (!rc)
rc = mxfChannelGet(server, MXF_CLASS_PULSE, MXF_SCLASS_TX_CHANNEL, MXF_MODULE_MULTI, 0, &txChannel);
if(!rc)
rc = mxfChannelInfoGet(txChannel, &device, NULL);
// Set electrical settings
if(!rc)
{
rc = mxfAttributeUint64Set(txChannel, KMXF_PULSE_ELECTRICAL_SELECTION, VMXF_PULSE_ELECTRICAL_SELECT_CUSTOM);
if(!rc)
rc = mxfAttributeDoubleSet(txChannel, KMXF_PULSE_TX_DIFF_VOLTAGE_HIGH, 5.0);
if (!rc)
rc = mxfAttributeDoubleSet(txChannel, KMXF_PULSE_TX_DIFF_VOLTAGE_LOW, -5.0);
if (!rc)
rc = mxfAttributeDoubleSet(txChannel, KMXF_PULSE_TX_VOLTAGE_OFFSET, 0.0);
}
// Set time base
if (!rc)
rc = mxfSystemTimeBaseSet(server, MXF_TIMEBASE_DEVICE_USEC);
// Allocates TX Aperiodic static buffer for HIGH priority queue
if(!rc)
rc = mxfTxAperiodicBufferAlloc(txChannel, MXF_TXAPERIODIC_PRIORITY_HIGH, sizeof(Rec), &txBuffer, NULL);
// Set line to low state now
if (!rc)
{
printf("Set line to 0\n\r");
memset(&Rec, 0, sizeof(Rec));
Rec.control = 0;
Rec.mode = MXF_PULSE_DATAREC_MODE_LOW;
rc = mxfPulseTxAperiodicWrite(txBuffer, 0, 0, 1, &Rec);
}
mxfSleep(100);
// Set line to high state now
if (!rc)
{
printf("Set line to 1\n\r");
Rec.control = 0;
Rec.mode = MXF_PULSE_DATAREC_MODE_HIGH;
rc = mxfPulseTxAperiodicWrite(txBuffer, 0, 0, 1, &Rec);
}
mxfSleep(100);
// Set line to low state in 500 msec
if (!rc)
{
printf("Set line to 0 in 500 msec\n\r");
Rec.control = 0;
Rec.mode = MXF_PULSE_DATAREC_MODE_LOW;
rc = mxfDeviceTimerGet(device, &timer);
if (!rc)
{
timer += 500000;
rc = mxfPulseTxAperiodicWrite(txBuffer, MXF_TXAPERIODIC_FLAG_ABSOLUTE_START_TIME, timer, 1, &Rec);
}
}
// Start a pulse schedule 50 usec after low state (50 usec low, 80 usec high, 50 pulses)
if (!rc)
{
printf("Start a pulse schedule 50 usec after low state\n\r");
Rec.timeTag = 0;
Rec.control = 0;
Rec.mode = MXF_PULSE_DATAREC_MODE_SCHED_START;
Rec.repeatCount = 50;
Rec.lowDuration = 400; //400*125 nsec = 50 usec
Rec.highDuration = 640; //640*125 nsec = 80 usec
timer += 50;
rc = mxfPulseTxAperiodicWrite(txBuffer, MXF_TXAPERIODIC_FLAG_ABSOLUTE_START_TIME, timer, 1, &Rec);
}
// Re-Start a pulse schedule in 1 sec (50 usec low, 80 usec high, forever)
if (!rc)
{
printf("Re-Start a pulse schedule in 1 sec\n\r");
Rec.timeTag = 0;
Rec.control = 0;
Rec.mode = MXF_PULSE_DATAREC_MODE_SCHED_START;
Rec.repeatCount = 0; //forever
Rec.lowDuration = 400; //400*125 nsec = 50 usec
Rec.highDuration = 640; //640*125 nsec = 80 usec
rc = mxfDeviceTimerGet(device, &timer);
if(!rc)
{
timer += 1000000;
rc = mxfPulseTxAperiodicWrite(txBuffer, MXF_TXAPERIODIC_FLAG_ABSOLUTE_START_TIME, timer, 1, &Rec);
}
}
// Change the current duty cycle to 25 usec high, 25 usec low after 500 msec.
// This change will occur at the end of the pulse. The repeat count is fixed
// to 50 pulses.
if (!rc)
{
printf("Change the current duty cycle to 25 usec high, 25 usec low after 500 msec\n\r");
Rec.timeTag = 0;
Rec.control = 0;
Rec.mode = MXF_PULSE_DATAREC_MODE_SCHED_START_EOP;
Rec.repeatCount = 50;
Rec.lowDuration = 200; //200*125 nsec = 25 usec
Rec.highDuration = 200; //200*125 nsec = 25 usec
timer += 500000;
rc = mxfPulseTxAperiodicWrite(txBuffer, MXF_TXAPERIODIC_FLAG_ABSOLUTE_START_TIME, timer, 1, &Rec);
}
// Change the current duty cycle to 100 usec high, 100 usec low at the end of
// the current pulse repeat count.
if (!rc)
{
printf("Change the current duty cycle to 100 usec high, 100 usec low at the end of the current pulse repeat count\n\r");
Rec.timeTag = 0;
Rec.control = 0;
Rec.mode = MXF_PULSE_DATAREC_MODE_SCHED_START_EOR;
Rec.repeatCount = 0; //forever
Rec.lowDuration = 800; //800*125 nsec = 100 usec
Rec.highDuration = 800; //800*125 nsec = 100 usec
rc = mxfPulseTxAperiodicWrite(txBuffer, MXF_TXAPERIODIC_FLAG_ABSOLUTE_START_TIME, timer, 1, &Rec);
}
// Stop the shedule after 2 seconds (Set the line to low state). This
// change will occur at the end of the pulse.
if (!rc)
{
printf("Stop the shedule after 2 seconds (set the line to low state)\n\r");
Rec.timeTag = 0;
Rec.control = 0;
Rec.mode = MXF_PULSE_DATAREC_MODE_LOW_EOP;
timer += 2000000;
rc = mxfPulseTxAperiodicWrite(txBuffer, MXF_TXAPERIODIC_FLAG_ABSOLUTE_START_TIME, timer, 1, &Rec);
}
// Wait until last transmit occured
do
{
if (!rc)
rc = mxfSleep(100);
if (!rc)
rc = mxfDeviceTimerGet(device, &time);
} while (time < timer && !rc);
if (rc)
printf("ERROR, rc=%08lx\n\r", rc);
printf("Press enter to terminate ...");
fgets(szTemp, sizeof(szTemp), stdin);
if(txBuffer)
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))
{
// Sets MULTI fifth TX channel to PULSE
if (channelIndex == 4)
{
*value = MXF_CLASS_PULSE;
return TRUE;
}
}
}
return FALSE;
}
Updated 10/23/2023