AR429 Interrupt
Edit this on GitLab
AR429 Interrupt Sample Application (SSK 2.x)
Overview
The AR429 Interrupt sample application demonstrates how to configure and handle hardware interrupts on ARINC 429 transmit modules using the NAI Software Support Kit (SSK 2.x). It covers configuring an ARINC 429 channel for triggered FIFO transmission, setting up an interrupt on the Tx FIFO Full status, connecting an ISR callback, configuring interrupt steering and vector, loading data into the transmit FIFO, and handling the interrupt when the FIFO reaches its threshold. The sample provides an interactive loop where the user loads words into the Tx FIFO until the full threshold is reached and the interrupt fires.
This sample supports the following ARINC 429 module types: AR1 and AR2. The Tx FIFO threshold is set to 32 messages, and the interrupt fires when the FIFO contains at least 32 entries. The sample uses triggered transmission mode (NAIBRD_AR_TX_SENDMODE_TRGF) so that data accumulates in the FIFO rather than being sent immediately, allowing the threshold to be reached.
For the SSK 1.x version, see AR Interrupt Basic (SSK 1.x).
|
Note
|
This sample is not available on DEOS. The interrupt callback mechanism requires POSIX thread support, which DEOS does not provide. Consult the SSK 2.x Software Development Guide for platform-specific build configuration. |
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with an ARINC 429 module installed (AR1, AR2).
-
SSK 2.x installed on your development host.
-
The sample applications built. Refer to the SSK 2.x Software Development Guide for platform-specific build instructions.
-
A platform that supports hardware interrupts (Petalinux or VxWorks).
How to Run
Launch the ar429_interrupt executable from your build output directory. On startup the application looks for a configuration file (default_ARXmit.txt). On the first run, this file will not exist — the application will present an interactive board menu. After connecting, select a card, module, channel, and data rate. The application configures the ARINC 429 channel for triggered FIFO transmission with interrupt-on-full, then enters an interactive loop where you load data words into the Tx FIFO. When the FIFO reaches the 32-word threshold, the interrupt fires and the status is displayed.
Board Connection and Module Selection
|
Note
|
This startup sequence is common to all NAI sample applications. The board connection and module selection code shown here is not specific to ARINC 429. |
The main() function follows a standard SSK 2.x startup flow:
-
Call
naiapp_RunBoardMenu()to load a saved configuration file (if one exists) or present the interactive board menu. -
Enter a loop that calls
AR_Interrupt_run()for each iteration.
#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t ar429_interrupt(void)
#else
int32_t main(void)
#endif
{
bool_t bQuit = NAI_FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == (bool_t)NAI_TRUE)
{
while (!bQuit)
{
bQuit = AR_Interrupt_run();
}
}
naiapp_access_CloseAllOpenCards();
return 0;
}
Note the SSK 2.x differences from SSK 1.x in this startup sequence:
-
The VxWorks preprocessor guard uses
NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS(SSK 1.x uses__VXWORKS__). -
The module identifier is retrieved with
naibrd_GetModuleName()(SSK 1.x usesnaibrd_GetModuleID()). -
Boolean constants are
NAI_TRUE/NAI_FALSE(SSK 1.x usesTRUE/FALSE). -
Console output uses
naiif_printf()from the platform abstraction layer (SSK 1.x usesprintf()directly).
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Entry Point
On standard platforms (Petalinux) the entry point is main(). On VxWorks the entry point is ar429_interrupt(). The main function handles board connection, then enters a loop calling AR_Interrupt_run() which performs channel selection, configuration, interrupt setup, and the interactive FIFO loading loop.
Channel Configuration
The ARINC 429 channel is configured with the following parameters:
/* Reset the channel */
check_status(naibrd_AR_ChannelReset(cardIndex, module, archan));
/* Set the transmission speed */
check_status(naibrd_AR_SetBaudRate(cardIndex, module, archan, datarate));
/* Set the Tx FIFO Threshold to 32 */
check_status(naibrd_AR_SetTxFifoThreshold(cardIndex, module, archan, 32));
/* Set parity to odd parity checking */
check_status(naibrd_AR_SetParityBitUsage(cardIndex, module, archan,
NAIBRD_AR_PAR_ODD));
/* Set inter-message gap time */
check_status(naibrd_AR_SetTxGapTime(cardIndex, module, archan, 6));
-
Tx FIFO Threshold — set to 32. When the number of messages in the Tx FIFO reaches 32, the Tx FIFO Full status is set and the interrupt fires.
-
Transmission mode — set to
NAIBRD_AR_TX_SENDMODE_TRGF(triggered mode) inAR_TxFIFO(), so data accumulates in the FIFO until explicitly triggered.
Interrupt Configuration
The interrupt is configured using the "EventMapped" interrupt pattern for ARINC 429 modules:
/* Set Interrupt Trigger Type to edge */
check_status(naibrd_AR_SetEventMappedInterruptTriggerType(cardIndex, module,
archan, NAIBRD_AR_EVENT_STATUS_GENERAL_TX_FIFO_FULL_LATCHED,
NAIBRD_INT_TRIGGER_TYPE_EDGE));
/* Set Interrupt Vector */
check_status(naibrd_AR_SetEventMappedInterruptVector(cardIndex, module,
archan, NAIBRD_AR_EVENT_MAP_GENERAL, INTERRUPT_VECTOR));
/* Set Interrupt Steering to PCIe */
check_status(naibrd_AR_SetEventMappedInterruptSteering(cardIndex, module,
archan, NAIBRD_AR_EVENT_MAP_GENERAL, NAIBRD_INT_STEERING_PCIE));
/* Install the ISR */
check_status(naibrd_ConnectISR(cardIndex, myIsr));
-
naibrd_AR_SetEventMappedInterruptTriggerType()— configures edge triggering on the Tx FIFO Full latched status. -
naibrd_AR_SetEventMappedInterruptVector()— assigns vector0xF5to the general event map for this channel. -
naibrd_AR_SetEventMappedInterruptSteering()— routes the interrupt to the PCIe bus. Change toNAIBRD_INT_STEERING_ONBOARD_ARMfor ARM-based processing. -
naibrd_ConnectISR()— registers the ISR callback once per card.
FIFO Loading and Interrupt Handling
Enabling the Interrupt
After channel configuration, the interrupt is enabled and all latched statuses are cleared:
/* Enable Interrupt for Tx FIFO Full events */
check_status(naibrd_AR_SetEventMappedInterruptEnable(cardIndex, module, channel,
NAIBRD_AR_EVENT_STATUS_GENERAL_TX_FIFO_FULL_LATCHED, NAI_TRUE));
/* Clear All Latched Status Bits */
check_status(naibrd_AR_ClearEventMappedStatusRaw(cardIndex, module, channel,
NAIBRD_AR_EVENT_MAP_GENERAL, 0xFFFFFFFF));
Interactive Data Loading
The AR_TxFIFO() function enters a loop where the user specifies how many words to load. Data is loaded with naibrd_AR_LoadTxFifo(). After each load, the code checks irqFlag to see if the threshold interrupt fired:
if (irqFlag)
{
irqFlag = 0;
naiif_printf("\r\nReceived Vector: 0x%08X", receivedVector);
switch (receivedVector)
{
case INTERRUPT_VECTOR:
/* Read channel status */
check_status(naibrd_AR_GetEventMappedStatusRaw(cardIndex, module,
channel, NAI_STATUS_LATCHED, NAIBRD_AR_EVENT_MAP_GENERAL,
&outStatusWord));
/* Optionally clear the Tx FIFO */
/* Clear Latched Status Bits */
check_status(naibrd_AR_ClearEventMappedStatusRaw(cardIndex, module,
channel, NAIBRD_AR_EVENT_MAP_GENERAL, outStatusWord));
break;
default:
naiif_printf("\r\nReceived Vector is not mine.\r\n");
}
}
ISR Callback
The ISR is minimal — it stores the received vector, sets a global flag, and increments a counter:
static void myIsr(uint32_t vector)
{
receivedVector = vector;
irqFlag = 1;
irqCount++;
}
Troubleshooting Reference
This table summarizes common errors and symptoms. Consult the AR1 Manual for hardware-specific diagnostic procedures.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
No board found or connection timeout |
Board not powered, incorrect configuration file, network issue |
Verify hardware is powered and connected. Check that |
Module not recognized as ARINC 429 |
Selected slot contains a non-AR module |
Verify the slot contains an AR1 or AR2 module |
|
Platform does not support hardware interrupts |
Verify you are running on Petalinux or VxWorks with interrupt support compiled in |
Interrupt never fires |
FIFO threshold not reached, wrong steering, or interrupt not enabled |
Load at least 32 words into the Tx FIFO. Verify steering matches your platform (PCIe vs. ARM). |
|
Tx FIFO is full |
Clear the Tx FIFO with |
Interrupt fires but vector does not match |
Multiple interrupt sources active |
Verify the vector assigned with |
Data not transmitted after loading |
Triggered mode requires explicit trigger signal |
The sample uses triggered mode to accumulate data. Send a trigger or switch to immediate mode if you want data sent immediately. |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — ar429_interrupt.c (SSK 2.x)
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"
/* naibrd include files */
#include "nai_libs/naibrd/include/naibrd.h"
/* naiif include files */
#include "nai_libs/naiif/include/naiif_stdio.h"
/* Common Sample Program include files */
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_menu.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_query.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_access.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_display.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_utils.h"
/* AD Sample App include files */
#include "nai_sample_apps/naiapp_src/board_modules/ar429/ar429_common_utils/ar429_common_utils.h"
static const int8_t *CONFIG_FILE = (int8_t *)"default_ARXmit.txt";
/* Function prototypes */
static bool_t AR_Interrupt_run();
static void myIsr(uint32_t vector);
static bool_t AR_TxFIFO( int32_t cardIndex, int32_t module, int32_t channel, naibrd_ar_tx_mode_t txmode );
/* Default channel selection */
#define DEF_AR_CARD_INDEX 0
#define DEF_AR_MODULE 1
#define DEF_AR_XMIT_CHANNEL 1
/* Default channel configuration settings */
#define DEF_AR_DATA_RATE NAIBRD_AR_SPEED_LOW
#define DEF_AR_TX_MODE NAIBRD_AR_TX_SENDMODE_IMMED
#define DEF_AR_XMIT_DATA_COUNT 1
/* Interrupt Configuration */
#define INTERRUPT_VECTOR 0xF5
/* Global Variables */
static volatile int32_t irqFlag;
static int32_t irqCount;
static uint32_t receivedVector;
/**************************************************************************************************************/
/**
* <summary>
* The purpose of the ar429_interrupt is to illustrate the methods to call in the naibrd library to configure
* the ARINC channel to run in Tx mode and generate an interrupt when the Tx FIFO is full.
* </summary>
*/
/**************************************************************************************************************/
#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t ar429_interrupt(void)
#else
int32_t main(void)
#endif
{
bool_t bQuit = NAI_FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == (bool_t)NAI_TRUE)
{
while (!bQuit)
{
bQuit = AR_Interrupt_run();
}
naiif_printf("Type the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
naiapp_access_CloseAllOpenCards();
return 0;
}
/**************************************************************************************************************/
/**
<summary>
AR_Interrupt_run queries the user for the card, module and channel to configure as the ARINC transmitter
as well as the data rate (high (100KHz) or low (12.5KHz)). Methods in the naibrd library are invoked to configure
the ARINC channel. The user-specified ARINC channel is configured with the Tx FIFO Threshold set to 32 messages,
which means that the Tx FIFO Full status bit will be set and, if enabled, an interrupt will be generated when the
Tx FIFO reaches 32 messages at any point in time. In order to be able to accumulate messages in the Tx FIFO, the
Tx FIFO send mode is set to Triggered Mode, which requires the user to send a Trigger signal in order for the
contents of the Tx FIFO to get sent out. This code demonstrates how to program the ARINC module to generate an
interrupt when the Tx FIFO Full event occurs.
</summary>
*/
/**************************************************************************************************************/
static bool_t AR_Interrupt_run()
{
int32_t archan;
naibrd_ar_datarate_t datarate;
bool_t bQuit = NAI_FALSE;
int32_t cardIndex, module;
bQuit = GetARCfg( DEF_AR_CARD_INDEX, DEF_AR_MODULE, DEF_AR_XMIT_CHANNEL, &cardIndex, &module, &archan );
if (!bQuit)
{
/* Get Data Rate */
bQuit = GetARINCDataRate( DEF_AR_DATA_RATE, &datarate );
if (!bQuit)
{
/* Reset the channel */
check_status( naibrd_AR_ChannelReset( cardIndex, module, archan ) );
/* Set the transmission speed */
check_status( naibrd_AR_SetBaudRate( cardIndex, module, archan, datarate ) );
/* Set the Tx Fifo Threshold to 32 (max is 255). If the number of messages in the Tx FIFO falls under 32, the Tx FIFO Almost Empty Status will be set */
check_status( naibrd_AR_SetTxFifoThreshold( cardIndex, module, archan, 32 ) );
/* Set the Parity Bit Usage to treat ARINC bit 32 as an odd parity bit and perform parity checking */
check_status( naibrd_AR_SetParityBitUsage( cardIndex, module, archan, NAIBRD_AR_PAR_ODD ) );
/* Set the inter-message transmission gap time (interval rate) */
check_status( naibrd_AR_SetTxGapTime( cardIndex, module, archan, 6 ) ); /* 6 bit-times */
/* Set Interrupt Trigger Type (NAIBRD_INT_TRIGGER_TYPE_EDGE or NAIBRD_INT_TRIGGER_TYPE_LEVEL) */
check_status( naibrd_AR_SetEventMappedInterruptTriggerType( cardIndex, module, archan, NAIBRD_AR_EVENT_STATUS_GENERAL_TX_FIFO_FULL_LATCHED, NAIBRD_INT_TRIGGER_TYPE_EDGE ) );
/* Set Interrupt Vector for this channel */
check_status( naibrd_AR_SetEventMappedInterruptVector( cardIndex, module, archan, NAIBRD_AR_EVENT_MAP_GENERAL, INTERRUPT_VECTOR ) );
/* Select Interrupt Steering from the following enums */
/* Direct interrupt to VME Bus = NAIBRD_INT_STEERING_VME */
/* Interrupt to the Custom App on ARM / NAI Ethernet Listener App = NAIBRD_INT_STEERING_ONBOARD_ARM */
/* Interrupt to PCIe Bus = NAIBRD_INT_STEERING_PCIE */
/* Interrupt to CPCI Bus = NAIBRD_INT_STEERING_CPCI */
check_status( naibrd_AR_SetEventMappedInterruptSteering( cardIndex, module, archan, NAIBRD_AR_EVENT_MAP_GENERAL, NAIBRD_INT_STEERING_PCIE ) );
/* Install the ISR */
check_status( naibrd_ConnectISR( cardIndex, myIsr ) );
/* Set transmit mode and start transmission */
bQuit = AR_TxFIFO( cardIndex, module, archan, NAIBRD_AR_TX_SENDMODE_TRGF );
}
}
return bQuit;
}
static void myIsr(uint32_t vector)
{
receivedVector = vector;
/* Set the global interrupt flag */
irqFlag = 1;
irqCount++;
}
static bool_t AR_TxFIFO( int32_t cardIndex, int32_t module, int32_t channel, naibrd_ar_tx_mode_t txmode )
{
bool_t bQuit = NAI_FALSE;
int32_t nNumWordsToLoad = 1;
int32_t nNumWordsLoaded;
int32_t i;
int32_t increment = 0x33333333;
uint32_t SendData[255];
nai_status_t status;
bool_t outenable;
uint32_t outStatusWord;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
/* Set FIFO Transmission mode */
check_status( naibrd_AR_SetTransmitSendMode( cardIndex, module, channel, txmode ) );
/* Enable transmitter */
check_status( naibrd_AR_SetTxEnable( cardIndex, module, channel, NAI_TRUE ) );
/* Enable Interrupt for Tx FIFO Full events */
check_status( naibrd_AR_SetEventMappedInterruptEnable( cardIndex, module, channel, NAIBRD_AR_EVENT_STATUS_GENERAL_TX_FIFO_FULL_LATCHED, NAI_TRUE ) );
/* Clear All Latched Status Bits */
check_status( naibrd_AR_ClearEventMappedStatusRaw( cardIndex, module, channel, NAIBRD_AR_EVENT_MAP_GENERAL, 0xFFFFFFFF ) );
while (!bQuit)
{
/* Query for the number of data words to load into Tx Buffer */
bQuit = GetARTransmitDataCount( DEF_AR_XMIT_DATA_COUNT, &nNumWordsToLoad );
if (!bQuit)
{
if (nNumWordsToLoad > 255)
{
nNumWordsToLoad = 255;
}
naiif_printf( "\r\nLoading %d words ...\r\n", nNumWordsToLoad );
for (i = 0; i < nNumWordsToLoad; i++)
{
SendData[i] = (uint32_t)increment++;
naiif_printf( "0x%08X\r\n", SendData[i] );
}
status = naibrd_AR_LoadTxFifo( cardIndex, module, channel, nNumWordsToLoad, SendData, &nNumWordsLoaded );
if (status == NAI_SUCCESS)
{
naiif_printf( "Load success - %d words loaded.\r\n", nNumWordsLoaded );
check_status( naibrd_AR_GetTxFifoCnt( cardIndex, module, channel, &nNumWordsLoaded ) );
naiif_printf( "Tx FIFO count: %d\r\n", nNumWordsLoaded );
if (irqFlag)
{
irqFlag = 0;
/* Display the Interrupt Vector */
naiif_printf("\r\nReceived Vector: 0x%08X", receivedVector);
switch (receivedVector)
{
case INTERRUPT_VECTOR: /* mine */
/* Read off channel status */
check_status( naibrd_AR_GetEventMappedStatusRaw( cardIndex, module, channel, NAI_STATUS_LATCHED, NAIBRD_AR_EVENT_MAP_GENERAL, &outStatusWord ) );
naiif_printf("\r\nStatus Word: 0x%08X\r\n");
/* Query user to clear Tx FIFO */
bQuit = naiapp_query_ForBinaryResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt, (int8_t *)"Clear Tx FIFO? ", (int8_t *)"Invalid response. Please enter y or n. ", NAI_TRUE, &outenable);
if (bQuit == NAI_TRUE)
{
break;
}
else
{
if (outenable == NAI_TRUE)
{
/* Clear Tx Buffer */
check_status( naibrd_AR_ClearTxFifo( cardIndex, module, channel ) );
}
}
/* Clear Latched Status Bits */
check_status( naibrd_AR_ClearEventMappedStatusRaw( cardIndex, module, channel, NAIBRD_AR_EVENT_MAP_GENERAL, outStatusWord ) );
break;
default: /* not mine */
naiif_printf("\r\nReceived Vector is not mine.\r\n");
}
}
}
else if (status == NAI_ERROR_FULL)
{
naiif_printf( "Load fail - Not enough space in Tx Buffer. Space available: %d words.\r\n", nNumWordsLoaded );
}
else
{
naiif_printf( "Load fail - Error status: %d.\r\n", status );
}
}
}
/* Disable transmitter */
check_status( naibrd_AR_SetTxEnable( cardIndex, module, channel, NAI_FALSE ) );
return bQuit;
}