MX Foundation 4
Asynchronous Events

An application can register condition(s) to be monitored by the firmware.

When a callback handler is defined, the condition(s) is(are) reported to the application asynchronously from the firmware to the handler.

The way to define a handler is as follows:

After this registration, the application can transmit data as usual and/or received asynchronous events through the callback handler.

The transmit aperiodic buffer is normally updated from the callback handler.

List of conditions

The event conditions that can be monitored are as follows:

Condition Description
MXF_ASYNCEVENT_COND_TXAPERIODIC_BUFFER_THRESHOLD TX Aperiodic buffer almost empty threshold reached. Add enough records to the buffer to go over the almost full threshold to clear the event.
MXF_ASYNCEVENT_COND_TX_ERROR Transmission error detected. Only late transmit is supported, check the records time tag.

Example

ar717_buffer_threshold.c
In the example below an async event handler is defined to monitor the MXF_ASYNCEVENT_COND_TXAPERIODIC_BUFFER_THRESHOLD condition.

uint32 asyncEventHandler(HMXF_ASYNCEVENT asyncEvent, void* param)
{
uint64 maxCount=64, pendingCount;
uint64 i;
uint32 rc;
// Gets the list of pending events to process
rc = mxfAsyncEventPendingGet(asyncEvent, maxCount, &pendingCount, pendingList);
for (i=0; !rc && i<pendingCount; i++)
{
switch(pendingList[i].condID)
{
case MXF_ASYNCEVENT_COND_TXAPERIODIC_BUFFER_THRESHOLD:
// An almost empty condition was detected...
writeMsgs(pendingList[i].condition.txAperiodicBufferThreshold.buffer, (MXF_A717_DATAREC *)param);
break;
case MXF_ASYNCEVENT_COND_RXACQ_BUFFER_THRESHOLD:
// An almost full condition was detected...
readAcquisition(pendingList[i].condition.rxAcqBufferThreshold.buffer, (MXF_A717_DATAREC *)param);
break;
default:
printf("Unknown condID 0x%llx)", pendingList[i].condID);
break;
}
}
return rc;
}
// Aperiodic Transmission
uint32 writeMsgs(HMXF_BUFFER buffer, MXF_A717_DATAREC *hostBuffer)
{
uint32 rc=0;
uint32 i;
MXF_A717_DATAREC *recPtr=hostBuffer;
uint64 word;
static uint32 TXAsyncEvents=0;
// Refills the FIFO
for(i=0; !rc && i<TXALMOSTFULL; i++)
{
recPtr->timeTag=0;
recPtr->control=0;
recPtr->dataSize = 2 * (uint32)SUBFRAMESIZE; // 16 bits per word in subframe
recPtr->repeatCount=1;
recPtr->reserved=0;
for(word=0; word < SUBFRAMESIZE ; word++)
{
if (word == 0)
{
// 1st word of each subframe has to be a sync word
// sync words are:
// - 0x247 for subframe #0
// - 0x5B8 for subframe #1
// - 0xA47 for subframe #2
// - 0xDB8 for subframe #3
switch (i%4)
{
case 0:
recPtr->data[word] = 0x247;
break;
case 1:
recPtr->data[word] = 0x5B8;
break;
case 2:
recPtr->data[word] = 0xA47;
break;
case 3:
recPtr->data[word] = 0xDB8;
break;
default:
break;
}
}
else
recPtr->data[word] = (uint16)(0x11*word);
}
if(!rc)
rc = mxfA717NextDataRecordPtrGet(recPtr, &recPtr);
}
if(!rc)
{
printf("Transmitting ...\n");
// Transmits strings on relative record time
rc = mxfA717TxAperiodicWrite(buffer, MXF_TXAPERIODIC_FLAG_DEFAULT, 0, TXALMOSTFULL, hostBuffer);
}
if(rc)
printf("Periodic Update failed; rc=0x%08x\n", rc);
else
printf("\nAsync Event %d - Writing %d records\n", ++TXAsyncEvents, i);
return rc;
}



Asynchronous main logic for registering a condition handler and add conditions to be monitored.

#define TXALMOSTFULL 7
#define TXALMOSTEMPTY 3
uint32 rc;
HMXF_SERVER server;
HMXF_CHANNEL rxChannel;
HMXF_ASYNCEVENT asyncEvent;
HMXF_BUFFER txBuffer;
size_t bufferSize;
MXF_A717_DATAREC *hostBuffer;
MXF_ASYNCEVENT_CONDITION TXasyncEventInfo;
...
// Allocates host buffer
bufferSize = (TXALMOSTFULL*sizeof(MXF_A717_DATAREC));
if(!rc)
{
hostBuffer = (MXF_A717_DATAREC *)malloc(bufferSize);
if(!hostBuffer)
rc = MAXT_ERROR_MEM;
}
// Sets the event handler
if(!rc)
rc = mxfAsyncEventHandlerInit(server, &asyncEventHandler, hostBuffer, &asyncEvent);
// Allocates TX Periodic Update buffer
if(!rc)
rc = mxfTxAperiodicBufferAlloc(txChannel, MXF_TXAPERIODIC_PRIORITY_HIGH, bufferSize, &txBuffer, NULL);
// Sets the TX async event condition
if(!rc)
{
memset(&TXasyncEventInfo, 0, sizeof(TXasyncEventInfo));
TXasyncEventInfo.condID = MXF_ASYNCEVENT_COND_TXAPERIODIC_BUFFER_THRESHOLD;
TXasyncEventInfo.condition.txAperiodicBufferThreshold.buffer = txBuffer;
TXasyncEventInfo.condition.txAperiodicBufferThreshold.almostFull = TXALMOSTFULL;
TXasyncEventInfo.condition.txAperiodicBufferThreshold.almostEmpty = TXALMOSTEMPTY;
rc = mxfAsyncEventConditionsSet(asyncEvent, TRUE, 1, &TXasyncEventInfo);
}
...
// Terminates async event handler
if(!rc)
rc = mxfAsyncEventConditionsSet(asyncEvent, FALSE, 1, &TXasyncEventInfo);
if(!rc)
...
Updated 10/23/2023