Integrator Resources

The official home for NAI Support

Not sure where to start? Try Quick Start Guide or ask a question below!

Toggle Components with Visual Button
JavaScript Form Processing

AR Interrupt Basic

AR Interrupt Basic Sample Application (SSK 1.x)

Overview

The AR Interrupt Basic sample application demonstrates how to configure ARINC 429 module interrupts to detect BIT (Built-In Test) failures and new message availability using the NAI Software Support Kit (SSK 1.x). ARINC 429 is an avionics data bus standard used for point-to-point communication between aircraft systems. Unlike discrete module interrupts — which monitor voltage levels on individual I/O pins — ARINC 429 interrupts operate at the communication protocol level. They notify your application when the receive FIFO has captured a new ARINC word from the bus or when the hardware’s continuous self-test detects a data path fault.

This distinction is important: a DT interrupt fires because a voltage crossed a threshold or an edge was detected on a wire. An AR interrupt fires because a complete ARINC message arrived in the receive buffer, or because the internal loopback verification detected a mismatch between transmitted and received data. The interrupt sources are fundamentally different — protocol events vs. electrical events — and this affects how you configure, handle, and troubleshoot them.

This sample supports the following AR module types: AR1 (up to 12 channels) and AR2 (2 channels). It also works with combination modules that include ARINC 429 functionality: CM2 (8 AR channels) and CM5 (8 AR channels).

For background on interrupt concepts — including edge vs. level triggering, interrupt vector numbering, steering architecture, and latency measurement — see the Interrupts API Guide. This guide focuses on how those concepts apply specifically to ARINC 429 modules and walks through the practical implementation using the SSK 1.x API. Consult your AR module’s manual (AR-01 or equivalent) for BIT timing specifications and FIFO depth details.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with an ARINC 429 module installed (AR1, AR2, or a combination module such as CM2 or CM5).

  • SSK 1.x installed on your development host.

  • The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.

  • For testing RX Available interrupts: an ARINC 429 transmitter connected to the receive channel’s bus (either an external device or another channel on the same module configured for Tx).

How to Run

Launch the AR_Interrupt_Basic executable from your build output directory. On startup the application looks for a configuration file (default_AR_Interrupt_Basic.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, the application prompts you for a receive channel, trigger mode, steering, and timestamp preferences, then waits for interrupt events.

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. For details on board connection configuration, see the First Time Setup Guide.

The main() function (or AR_Interrupt_Basic() on VxWorks) follows a standard SSK 1.x startup flow:

  1. Initialize default AR and interrupt configuration structures with initializeARConfigurations() and initializeInterruptConfigurations().

  2. Call naiapp_RunBoardMenu() to load a saved configuration file or present the interactive board menu. The configuration file (default_AR_Interrupt_Basic.txt) is not included with the SSK — it is created when you save your connection settings from the board menu. On the first run, the menu will always appear.

  3. Query the user for card index and module number.

  4. Retrieve the module ID with naibrd_GetModuleID() and, if valid, proceed to interrupt configuration.

#if defined (__VXWORKS__)
int32_t AR_Interrupt_Basic(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   initializeARConfigurations(0,0,0,0,0,0,MAX_FIFO_COUNT, DEF_AR_TIMESTAMP,FALSE);
   initializeInterruptConfigurations(FALSE,FALSE,FALSE,0,0,0,0);

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         inputARConfig.cardIndex = cardIndex;
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            inputARConfig.module = module;
            if (stop != TRUE)
            {
               inputARConfig.modid = naibrd_GetModuleID(cardIndex, module);
               if ((inputARConfig.modid != 0))
               {
                  Run_AR_Interrupt_Basic();
               }
            }
         }
         printf("\nType Q to quit or Enter key to restart application:\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   printf("\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();

   return 0;
}
Important

Common connection errors you may encounter at this stage:

  • No board found — verify that the board is powered on and physically connected. Check that the configuration file lists the correct interface and address.

  • Connection timeout — confirm network settings (for Ethernet connections) or bus configuration (for PCI/PCIe). Firewalls and IP mismatches are frequent causes.

  • Invalid card or module index — indices are zero-based for cards and one-based for modules. Ensure the values you pass match your hardware setup.

  • Module not present at selected slot — the slot you selected does not contain an AR module. Use the board menu to verify which slots are populated.

Program Structure

The AR Interrupt Basic sample is split across two source files:

  • AR_Interrupt_Basic.c — entry point. Handles board connection, user queries, and orchestrates the interrupt lifecycle (install ISR, configure, wait, clean up).

  • nai_ar_int.c — shared ARINC interrupt utilities. Contains the ISR (basic_ISR_AR()), the interrupt configuration function (configureARToInterruptOnRx()), the interrupt enable function (enableARInterrupts()), the polling/check function (checkForARInterrupt()), and user query helpers.

Entry Point

Run_AR_Interrupt_Basic() is the core function called after board connection succeeds. It collects four pieces of information from the user, then executes the interrupt lifecycle:

  1. Receive channel — which ARINC channel to monitor for incoming messages.

  2. Latch trigger mode — edge-triggered (0) or level-triggered (1, default). This determines whether the interrupt fires once on detection (edge) or continuously while the condition persists (level). For ARINC receive interrupts, level triggering is the default because new messages may accumulate in the FIFO — level mode ensures the interrupt re-fires as long as unread data remains.

  3. Interrupt steering — where the interrupt signal is delivered (onboard, offboard PCI/PCIe, etc.).

  4. Timestamp enable — whether to include hardware timestamps with received ARINC messages (default: Yes).

After collecting these values, the function follows a linear flow: install ISR, configure interrupt registers, enable Rx on the channel, wait for interrupts, then clean up.

/* Query user for RX channel */
printf( "\nWhich channel would you like to Receive on? \n" );
bQuit = naiapp_query_ChannelNumber( inputARConfig.maxChannel, inputARConfig.minChannel, &inputARConfig.channel );

/* Query user for Trigger Status of interrupts */
bQuit = GetARLatchStatusTriggerMode( &inputInterruptConfig.interrupt_Edge_Trigger );

/* Query user for location interrupt will be sent out to */
bQuit = GetIntSteeringTypeFromUser( &inputInterruptConfig.steering );

/* Query user for timestamp enable */
bQuit = QueryUserForTimeStampEnable( &inputARConfig.timeStampEnable );

The menu system is a sample convenience — in your own code, call these API functions directly with your desired values.

Interrupt Status Types

ARINC 429 interrupts are fundamentally different from discrete (DT) interrupts. A DT module monitors voltage levels on physical I/O pins and generates interrupts when those voltages cross configured thresholds (low-to-high transition, high-to-low transition) or when hardware faults are detected (overcurrent, BIT failure). An AR module monitors communication protocol events on the ARINC 429 bus and generates interrupts when protocol-level conditions occur — a new message has been received, or the internal data path verification has failed.

This means your interrupt handler logic is different. With DT interrupts, you typically read which channels triggered and take action based on the signal state. With AR interrupts, you read the FIFO to retrieve the actual ARINC message data, or you investigate a BIT failure to determine if the communication path is compromised.

The AR module exposes two primary interrupt status types that this sample demonstrates:

BIT (Built-In Test)

AR_BIT_ERROR (status bit 0x0200)

The module’s Built-In Test circuitry continuously verifies the ARINC data path using an internal loopback mechanism. The BIT system uses an "add-2, subtract-1" filtering scheme for Continuous BIT (CBIT): it transmits known test patterns through the internal loopback path and compares the received data against the expected values. Each successful comparison decrements an internal error counter; each failure increments it by two. This asymmetric weighting means a single transient glitch will not immediately trigger a BIT fault, but a persistent mismatch — where failures outnumber successes — will eventually cause the counter to exceed its threshold and latch the BIT error status.

When the BIT error bit latches, the corresponding interrupt fires (if enabled). A BIT fault indicates that the transmit-to-receive data path on the channel is not functioning correctly. This could be caused by a hardware failure, a configuration error that disrupts the internal loopback, or an FPGA issue.

Enable BIT interrupts for health monitoring, safety-critical applications, or continuous hardware validation. In systems where a compromised ARINC communication path must be flagged immediately rather than discovered during a periodic status poll, BIT interrupts provide the fastest notification.

Consult the AR-01 module manual for BIT timing specifications, error counter thresholds, and the relationship between CBIT test rate and fault detection latency.

Summary RX Available

AR_RX_DATA_AVAIL (status bit 0x0001)

A new ARINC 429 message has been received and is available in the channel’s receive FIFO buffer. This is the primary data-availability interrupt — it fires when the hardware has captured a complete ARINC word from the bus and placed it in the FIFO. Your application responds by reading the FIFO to retrieve the message data, status, and (if enabled) timestamp.

This interrupt is the ARINC equivalent of a "data ready" notification. Unlike a DT low-to-high transition interrupt — which tells you a voltage level changed — the RX Available interrupt tells you a complete 32-bit ARINC word has arrived through the protocol decoder, passed parity checking (if enabled), and been stored in the receive buffer.

Enable RX Available interrupts when your application needs to process incoming ARINC messages as they arrive rather than polling the FIFO. This is the most common AR interrupt type and the primary one demonstrated by this sample.

How AR Interrupts Differ from Discrete Interrupts

To summarize the key differences:

Characteristic DT (Discrete) Interrupts AR (ARINC 429) Interrupts

What is monitored

Voltage levels on I/O pins

ARINC 429 protocol events on the bus

BIT meaning

Channel hardware health (open input, stuck output)

Data path integrity (Tx-to-Rx loopback verification)

Data event

Voltage transition (low-to-high, high-to-low)

Message received (FIFO has new ARINC word)

Handler action

Read which channels triggered, check signal state

Read FIFO to retrieve ARINC message data

Prerequisite

Physical signal present at input pin

ARINC transmitter active on the bus, Rx enabled on channel

Interrupt Configuration

The configureARToInterruptOnRx() function in nai_ar_int.c configures the module’s interrupt registers for a single channel. The configuration follows a specific sequence: disable existing interrupts, clear stale status, set the vector, configure the trigger mode, and set interrupt steering. After this, the main application enables interrupts and configures the channel for reception.

Step 1: Disable Interrupts and Clear Status

Always disable interrupts and clear stale status before reconfiguring. Stale latched status from a previous run will trigger an immediate interrupt if not cleared first.

/* clear interruptConfigs of previous channels */
check_status( naibrd_AR_SetInterruptEnable( cardIndex, module, channel, 0 ) );
check_status( naibrd_AR_ClearStatus( cardIndex, module, channel, 0xFFFF ) );

The 0xFFFF mask clears all status bits — BIT, RX Available, FIFO status, parity errors, and all other latched conditions. This ensures a clean starting state.

Step 2: Set Interrupt Vector

The vector identifies which interrupt source generated the event when your ISR is called. The sample assigns NAI_AR_INTERRUPT_VECTOR to the channel. If you need to distinguish multiple AR channels in a single ISR, you can assign a different vector to each channel.

check_status( naibrd_AR_SetInterruptVector( cardIndex, module, channel, vector ) );

Step 3: Set Trigger Mode (Edge/Level)

The trigger mode determines how the latched status register generates interrupts. Edge-triggered mode fires once when the status transitions from clear to set. Level-triggered mode fires continuously as long as the status remains set.

check_status( naibrd_AR_SetInterruptEdgeLevel( cardIndex, module, channel, interrupt_Edge_Trigger ) );

For ARINC receive interrupts, the default is level-triggered (1). This is appropriate because multiple ARINC messages may arrive in rapid succession — level mode ensures the interrupt continues to fire as long as unread messages remain in the FIFO. If you switch to edge-triggered mode, you must ensure your handler reads all available messages before clearing the status, or you may miss messages that arrived while you were processing.

Step 4: Set Interrupt Steering

Steering determines how the interrupt signal is delivered from the module to your application. The user’s selection is passed directly to the steering configuration call.

check_status( naibrd_AR_SetInterruptSteering( cardIndex, module, channel, steering ) );

The steering options are the same as for other module types: onboard (NAIBRD_INT_STEERING_ON_BOARD_0), cPCI offboard (NAIBRD_INT_STEERING_CPCI_APP), PCIe offboard (NAIBRD_INT_STEERING_PCIE_APP), and Ethernet (NAIBRD_INT_STEERING_ON_BOARD_1). Ensure the steering mode matches your physical bus configuration and the IRQ ID used in naibrd_InstallISR().

Step 5: Enable Interrupts on the Channel

After configuration, the enableARInterrupts() function enables interrupt generation on the selected channel:

check_status( naibrd_AR_SetInterruptEnable( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, enable ) );

Step 6: Enable Rx and Configure the Channel

This step is AR-specific and has no equivalent in discrete module interrupt setup. ARINC channels must be explicitly enabled for reception before any messages can arrive. Without this step, the channel’s receiver is inactive and no RX Available interrupt will ever fire, regardless of how correctly the interrupt registers are configured.

The Cfg_Rx_AR() function handles this:

Cfg_Rx_AR( inputARConfig );

This function sets the ARINC data rate (high speed at 100 kbps for ARINC 429, or the appropriate rate for the module variant), configures timestamp mode if the user requested it, and calls naibrd_AR_SetRxEnable() to activate the receiver on the selected channel. The Rx enable step is the most commonly missed step when ARINC interrupts fail to fire.

Full Configuration Sequence

The complete configuration flow in Run_AR_Interrupt_Basic() ties all steps together:

/**** 2. Implement Bus Interrupt Handling ****/
setIRQ( inputInterruptConfig.steering, &inputInterruptConfig.irq );
check_status( naibrd_InstallISR( inputARConfig.cardIndex, inputInterruptConfig.irq, basic_ISR_AR, NULL ) );

/**** 3. configure Module to perform interrupts ****/
configureARToInterruptOnRx( inputInterruptConfig, inputARConfig );
enableARInterrupts( inputARConfig, TRUE );

/**** 4. Configure Module to cause Interrupts ****/
Cfg_Rx_AR( inputARConfig );
Important

Common interrupt configuration errors:

  • RX Available never fires — the most common ARINC interrupt issue. The channel’s Rx is not enabled (naibrd_AR_SetRxEnable() was not called), or no ARINC transmitter is active on the bus. Both conditions must be true for RX Available to fire.

  • Stale status triggers immediate interrupt — if you enable interrupts without clearing the status registers first, any latched status from a previous run will fire immediately. Always call naibrd_AR_ClearStatus() with 0xFFFF before enabling.

  • Steering mismatch — selecting onboard steering when the ISR is installed as offboard (or vice versa) results in interrupts being routed to a path with no handler. Ensure the steering mode passed to naibrd_AR_SetInterruptSteering() matches the IRQ ID used in naibrd_InstallISR().

Interrupt Handler

The sample uses a simple ISR (basic_ISR_AR()) that sets a flag and records the interrupt vector. The actual status reading and FIFO retrieval happen in the polling function checkForARInterrupt(), which runs in the main thread.

ISR: basic_ISR_AR()

The ISR is intentionally minimal. It sets the interruptOccured flag to TRUE and captures the interrupt vector. On VxWorks, it also reads and clears the onboard interrupt vector directly.

#if defined (__VXWORKS__)
 void basic_ISR_AR( uint32_t param )
#else
void basic_ISR_AR( void *param, uint32_t vector )
#endif
{
   interruptOccured = TRUE;

#if defined (WIN32)
   UNREFERENCED_PARAMETER( param );
#endif

   #if defined (__VXWORKS__)
      interruptVector = nai_Onboard_GetInterruptVector();
      nai_Onboard_ClearInterrupt();
   #else
      interruptVector = vector;
   #endif
}

In your own application, keep the ISR as short as possible. Set a flag or post a message, then do the heavy work (FIFO reads, data processing) outside the ISR context.

Polling and FIFO Read: checkForARInterrupt()

The checkForARInterrupt() function runs in a loop, prompting the user to check for interrupts. When interruptOccured is TRUE, it reads the channel’s latched status, retrieves the FIFO contents, and displays the received ARINC message data.

if (interruptOccured)
{
   naibrd_Wait( 1000000 );
   check_status( naibrd_AR_GetStatus( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, NAI_AR_STATUS_LATCHED, &status ) );
   check_status( naibrd_AR_GetRxBufferCnt( cardIndex, module, channel, &count ) );
   check_status( naibrd_AR_ReadFifo( cardIndex, module, channel, inputARConfig.timeStampEnable, count, statArr, dataArr, tstampArr, &outnummsgs ) );
   printf( "\nVector = %#x \n", interruptVector );
   printf( "Status = %#x \n\n", status );
   /* ... display message data, status, and timestamps ... */
   interruptOccured = FALSE;
}

The key API sequence when an RX Available interrupt fires:

  1. naibrd_AR_GetStatus() — read the latched status register to confirm which status bits are set. The status word contains AR_RX_DATA_AVAIL (bit 0), AR_BIT_ERROR (bit 9), and other condition flags.

  2. naibrd_AR_GetRxBufferCnt() — get the number of messages currently in the receive FIFO.

  3. naibrd_AR_ReadFifo() — read all available messages from the FIFO. Each message includes a status word, the 32-bit ARINC data word, and (if timestamps are enabled) a hardware timestamp.

After displaying the results, the function offers to clear the status register:

printf( "\n\nWould you like to clear the status register? (default:Y):" );
/* ... */
if ( inputBuffer[0] == 'y' || inputBuffer[0] =='Y' || inputResponseCnt == 0 )
{
   check_status( naibrd_AR_ClearStatus( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, 0xFFFF ) );
}

Clearing the status register re-arms the interrupt for the next event. If you are using edge-triggered mode and do not clear the status, no new edge will be generated and the interrupt will never fire again. In level-triggered mode, the interrupt will continue to assert as long as unread data remains in the FIFO, but clearing the status after reading all messages is still good practice.

Cleanup

After the user quits the polling loop, the application disables Rx on the channel, clears all status, and uninstalls the ISR:

/***** 7. Clear Module Configurations *****/
check_status( naibrd_AR_SetRxEnable( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, FALSE ) );
check_status( naibrd_AR_ClearStatus( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, 0xFFFF ) );

/***** 8. Clear Board Configurations *****/
check_status( naibrd_UninstallISR( inputARConfig.cardIndex ) );

Always disable Rx and clear status before uninstalling the ISR. This prevents any final interrupt from firing after the handler has been removed.

Important

Common interrupt handling errors:

  • FIFO read returns zero messages — the interrupt fired but naibrd_AR_GetRxBufferCnt() returns 0. This can happen if the status was cleared between the interrupt and the FIFO read, or if the interrupt was triggered by a non-RX-Available condition (such as BIT). Always check the status word to determine which condition actually fired.

  • Interrupts stop after first event (edge-triggered) — the handler did not clear the latched status register. With edge triggering, the interrupt fires on the transition into the latched state. If the status is never cleared, no new edge occurs and the interrupt will not fire again.

  • Missing timestamps — timestamps appear as zero even though timeStampEnable is TRUE. Verify that Cfg_Rx_AR() was called with the timestamp flag set before enabling Rx. Timestamp configuration must be set before the first message arrives.

Troubleshooting Reference

This table summarizes common errors and symptoms covered in the sections above. For detailed context, refer to the relevant section. Consult your module’s manual for hardware-specific diagnostic procedures.

Debugging ARINC Interrupts That Are Not Firing

For ARINC interrupts, the most common issue is RX Available never firing. This usually means the channel’s Rx is not enabled, or no ARINC transmitter is present on the bus. Use this approach to isolate the problem:

  1. Check whether the status registers are changing. Call naibrd_AR_GetStatus() with NAI_AR_STATUS_LATCHED to read the latched status for your channel. If the AR_RX_DATA_AVAIL bit is setting when you know a transmitter is active, the module is detecting messages — the issue is in your interrupt delivery path (steering, ISR installation, or enable).

  2. If the status registers are NOT changing, verify that Rx is enabled on the channel (naibrd_AR_SetRxEnable() was called with TRUE), that an ARINC transmitter is actually sending data on the bus, and that the data rate configuration matches between transmitter and receiver. You can also try reading the FIFO directly with naibrd_AR_ReadFifo() to bypass the interrupt path entirely and confirm whether messages are arriving.

Error / Symptom Possible Causes Suggested Resolution

No board found or connection timeout

Board not powered, incorrect or missing configuration file, network issue

Verify hardware is powered and connected. If the configuration file exists, check that it lists the correct interface and address. If it does not exist, the board menu will appear — configure and save your connection settings.

Module not detected or not recognized as AR

No AR module installed at the selected slot, incorrect module number, or a non-AR module is present

Verify hardware configuration. Check naibrd_GetModuleID() return value against the AR module IDs (AR1: 0x41523120, AR2: 0x41523220, CM2: 0x434D3220, CM5: 0x434D3520).

RX Available interrupt never fires

Rx not enabled on the channel, no ARINC transmitter active on the bus, or data rate mismatch between transmitter and receiver

Verify naibrd_AR_SetRxEnable() was called with TRUE. Confirm an ARINC transmitter is connected and sending. Check that both ends use the same data rate (high speed 100 kbps or low speed 12.5 kbps).

BIT failure interrupt fires unexpectedly

Internal loopback path issue, channel configured in a mode that disrupts BIT, or hardware fault

Read the BIT status register to identify which channel failed. If the failure is persistent, it indicates a real hardware issue — consult the AR-01 manual for BIT diagnostics. Transient BIT failures may self-clear due to the add-2/subtract-1 filtering scheme.

FIFO overflow (data lost)

Messages arriving faster than the application reads them, FIFO depth exceeded (255 words for AR1, 1024 for AR2)

Increase your read rate, use level-triggered interrupts to ensure continuous notification while data remains in the FIFO, or reduce the incoming message rate. Check AR_RX_FIFO_OVERFLOW (bit 3) in the status register.

Timestamps show as zero

Timestamp feature not enabled before first message arrived, or module does not support timestamps in the current mode

Call Cfg_Rx_AR() with timeStampEnable set to TRUE before enabling Rx. Timestamp configuration must be applied before the first message is received.

Steering mismatch — ISR never called

Steering mode does not match the IRQ ID used in naibrd_InstallISR(), or physical bus type does not match

Match steering to where your application executes. Onboard: ON_BOARD_0. External PCI: CPCI_APP. External PCIe: PCIE_APP. Verify setIRQ() output matches your naibrd_InstallISR() call.

Wrong trigger mode for ARINC receive

Edge-triggered mode selected, but handler does not drain the full FIFO before clearing — subsequent messages missed

Use level-triggered mode (default) for ARINC receive interrupts. Level mode re-fires as long as unread data remains in the FIFO. If you must use edge-triggered mode, read all FIFO messages before clearing the status.

Interrupts stop after first event

Status register not cleared after handling (edge-triggered mode)

Call naibrd_AR_ClearStatus() with 0xFFFF after reading the FIFO and processing the data. This re-arms the interrupt for the next event.

Full Source

The complete source for this sample is provided below for reference. The sections above explain each part in detail. This sample consists of two source files: the main application and shared ARINC interrupt utilities.

Full Source — AR_Interrupt_Basic.c (SSK 1.x)
/**************************************************************************************************************/
/**
<summary>

The AR_Interrupt_Basic program demonstrates how to perform an interrupt when a single channel receives
an ar message. The purpose of this program is to demonstrate the method calls in the naibrd library for performing
the interrupt. More information on this process can be found in the naibrd SSK Quick Guide (Interrupts) file.

</summary>
*/
/**************************************************************************************************************/

/************************/
/* Include Declarations */
/************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* Common Module Specific Sample Program include files */
#include "nai_ar_int.h"
#include "nai_ar_cfg.h"

/* Common Sample Program include files */
#include "include/naiapp_interrupt.h"
#include "include/naiapp_interrupt_ether.h"
#include "include/naiapp_boardaccess_menu.h"
#include "include/naiapp_boardaccess_query.h"
#include "include/naiapp_boardaccess_access.h"
#include "include/naiapp_boardaccess_display.h"
#include "include/naiapp_boardaccess_utils.h"

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"

/* Module Specific NAI Board Library files */
#include "functions/naibrd_ar.h"

InterruptConfig inputInterruptConfig;

/* Extern Functions or Variables*/
extern ArConfig inputARConfig;

/*********************************************/
/* Application Name and Revision Declaration */
/*********************************************/
static const int8_t *CONFIG_FILE = (int8_t *)"default_AR_Interrupt_Basic.txt";

/********************************/
/* Internal Function Prototypes */
/********************************/
static bool_t Run_AR_Interrupt_Basic();

/**************************************************************************************************************/
/*****                                     Main Routine                                                   *****/
/**************************************************************************************************************/
/**************************************************************************************************************/
/**
<summary>

The main routine assists in gaining access to the board.

The following routines from the nai_sys_cfg.c file are
called to assist with accessing and configuring the board.

 - ConfigDevice
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - CheckModule

</summary>
*/
/*****************************************************************************/
#if defined (__VXWORKS__)
int32_t AR_Interrupt_Basic(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   initializeARConfigurations(0,0,0,0,0,0,MAX_FIFO_COUNT, DEF_AR_TIMESTAMP,FALSE);
   initializeInterruptConfigurations(FALSE,FALSE,FALSE,0,0,0,0);

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         /* Query the user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         inputARConfig.cardIndex = cardIndex;
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Query the user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            inputARConfig.module = module;
            if (stop != TRUE)
            {
               inputARConfig.modid = naibrd_GetModuleID(cardIndex, module);
               if ((inputARConfig.modid != 0))
               {
                  Run_AR_Interrupt_Basic();
               }
            }
         }
         printf("\nType Q to quit or Enter key to restart application:\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   printf("\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();

   return 0;
}

/**************************************************************************************************************/
/**
<summary>

This function is broken into the following major steps. These steps correspond with the steps provided
in the naibrd SSK Quick Guide (Interrupts) file.

2. Bus Interrupt Handling - Install ISR

   API CALLS - naibrd_InstallISR

3. Enable Module Interrupts- Configures module to interrupt when channel receives AR message.

   API CALLS - naibrd_AR_SetInterruptEdgeLevel, naibrd_AR_SetIntVector, naibrd_AR_SetInterruptSteering, naibrd_AR_SetIntEnable

4. Configure Module to Cause Rx Interrupt - sets the BAUD Rate to 1mbit/s (AR AB) or 500k bits/s (AR J1939) as definted in nai_ar_cfg.h
   It also enables the particular channel on the module to receive ar messages

   API CALLS - naibrd_AR_SetBitTiming , naibrd_AR_SetRxEnable

5. Show Interrupt Handling - Check if any interrupt has occurred and report back the status and vector

6. Re-arming Interrupts - Clear the status register to allow interrupts to occur again. This is done by writing to the status register.
   In this program, we use an API call to do this.

   API CALLS - naibrd_AR_ClearStatusRaw

7. Clear Module Configurations

   API CALLS - naibrd_AR_SetRxEnable

8. Clear Board Configurations

   API CALLS - naibrd_UninstallISR

</summary>
*/
/**************************************************************************************************************/
static bool_t Run_AR_Interrupt_Basic()
{
   bool_t bQuit = FALSE;
   inputARConfig.maxChannel = NAI_GEN5_AR_MAX_CHANNEL_COUNT;
   inputARConfig.minChannel = 1;

   /* Query user for RX channel */
   if (!bQuit)
   {
      printf( "\nWhich channel would you like to Receive on? \n" );
      bQuit = naiapp_query_ChannelNumber( inputARConfig.maxChannel, inputARConfig.minChannel, &inputARConfig.channel );
   }

   /* Query user for Trigger Status of interrupts */
   if (!bQuit)
   {
      bQuit = GetARLatchStatusTriggerMode( &inputInterruptConfig.interrupt_Edge_Trigger );
   }

   /* Query user for location interrupt will be sent out to */
   if (!bQuit)
   {
      bQuit = GetIntSteeringTypeFromUser( &inputInterruptConfig.steering );
   }

   if (!bQuit)
   {
      bQuit = QueryUserForTimeStampEnable( &inputARConfig.timeStampEnable );
   }

   if (!bQuit)
   {
      /**** 2. Implement Bus Interrupt Handling ****/
      setIRQ( inputInterruptConfig.steering, &inputInterruptConfig.irq );
      check_status( naibrd_InstallISR( inputARConfig.cardIndex, inputInterruptConfig.irq, basic_ISR_AR, NULL ) );

      /**** 3. configure Module to perform interrupts ****/
      configureARToInterruptOnRx( inputInterruptConfig, inputARConfig );
      enableARInterrupts( inputARConfig, TRUE );

      /**** 4. Configure Module to cause Interrupts ****/
      Cfg_Rx_AR( inputARConfig );

      /**** 5. Show Interrupt Handling (contains step 6) ****/
      bQuit = checkForARInterrupt( inputARConfig );

      /***** 7. Clear Module Configurations *****/
      check_status( naibrd_AR_SetRxEnable( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, FALSE ) );
      check_status( naibrd_AR_ClearStatus( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, 0xFFFF ) );

      /***** 8. Clear Board Configurations *****/
      check_status( naibrd_UninstallISR( inputARConfig.cardIndex ) );
   }
   return bQuit;
}
Full Source — nai_ar_int.c (SSK 1.x)
/* Common Sample Program include files */
#include "include/naiapp_interrupt.h"
#include "include/naiapp_interrupt_ether.h"
#include "include/naiapp_boardaccess_query.h"
#include "include/naiapp_boardaccess_access.h"
#include "include/naiapp_boardaccess_display.h"
#include "include/naiapp_boardaccess_utils.h"

/* Common AR Sample Program include files */
#include "nai_ar_int.h"
#include "nai_ar_cfg.h"

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "naibrd_ether.h"
#include "functions/naibrd_ar.h"
#include "maps/nai_map_ar.h"

#include <stdlib.h>

bool_t interruptOccured; /* used by checkForInterrupt to see if interrupt occurred */
int32_t frameCount;	/* counter increment when frames are found */
uint32_t interruptVector; /* used by checkForInterrupt to get vector of the interrupt that occurred in myIsr */
FIFO fifo12Chans[NAI_GEN5_AR_MAX_CHANNEL_COUNT];

/* Extern Functions or Variables*/
extern InterruptConfig inputInterruptConfig;
extern ArConfig inputARConfig;
extern FILE* fifoDataFile;

/***********************/
/* Function Prototypes */
/***********************/
void promptUserToClearInterrupt_AR();

/**************************************************************************************************************/
/**
<summary>
Prompts user to check if an interrupt has occurred. MyIsr() should be installed if using this function.
</summary>
*/
/**************************************************************************************************************/
bool_t checkForARInterrupt( ArConfig inputARConfig )
{
   bool_t bQuit;
   int32_t cardIndex;
   int32_t module;
   int32_t channel;
   nai_ar_status_t status;
   int32_t count;
   int32_t i;
   uint32_t fifoLength;
   int32_t maxFifoLength;
   uint16_t msgStatus;
   uint32_t msgData;
   uint32_t msgTStamp;
   uint32_t statArr[NAI_AR_MAX_DATA_LEN];
   uint32_t dataArr[NAI_AR_MAX_DATA_LEN];
   uint32_t tstampArr[NAI_AR_MAX_DATA_LEN];
   int32_t outnummsgs;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   cardIndex = inputARConfig.cardIndex;
   module = inputARConfig.module;
   channel = inputARConfig.channel;
   status = 0;
   bQuit = FALSE;
   interruptOccured = FALSE;
   while (!bQuit)
   {
      printf( "\nPress enter to check if interrupt Occurred (press Q to quit):" );
      bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
      if (!bQuit)
      {
         if (interruptOccured)
         {
            naibrd_Wait( 1000000 );
            check_status( naibrd_AR_GetStatus( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, NAI_AR_STATUS_LATCHED, &status ) );
            check_status( naibrd_AR_GetRxBufferCnt( cardIndex, module, channel, &count ) );
            check_status( naibrd_AR_ReadFifo( cardIndex, module, channel, inputARConfig.timeStampEnable, count, statArr, dataArr, tstampArr, &outnummsgs ) );
            printf( "\nVector = %#x \n", interruptVector );
            printf( "Status = %#x \n\n", status );
            maxFifoLength = NAI_AR_MAX_DATA_LEN;
            fifoLength = count;
            printf( "Max FIFO Word Count: %d\n", maxFifoLength );
            printf( "Messages Received (FIFO Word Count): %d\n", fifoLength );
            if ( count == 1 )
            {
               msgStatus = (uint16_t)statArr[0];
               msgData = dataArr[0];
               msgTStamp = tstampArr[0];
               printf( "\n" );
               printf( "Message Status: %#x", msgStatus );
               printf( "\n" );
               printf( "Message Data: %#x", msgData );
               printf( "\n" );
               printf( "Time Stamp: %#x", msgTStamp );
               printf( "\n\n" );
            }
            else if ( count > 1 )
            {
               for ( i = 0; i < count; i++ )
               {
                  printf( "\nMessage Number %d:", i + 1 );
                  msgStatus = (uint16_t)statArr[i];
                  msgData = dataArr[i];
                  msgTStamp = tstampArr[i];
                  printf( "\n" );
                  printf( "Message Status: %#x", msgStatus );
                  printf( "\n" );
                  printf( "Message Data: %#x", msgData );
                  printf( "\n" );
                  printf( "Time Stamp: %#x", msgTStamp );
                  printf( "\n\n" );
               }
            }
            else if ( count < 1 )
            {
               printf( "ERROR! naibrd_AR_GetRxBufferCnt returned an invalid value." );
            }
            interruptOccured = FALSE;
         }
         else
         {
            printf( "\nNo Interrupt Occurred" );
         }
         printf( "\n\nWould you like to clear the status register? (default:Y):" );

         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
         if ( inputBuffer[0] == 'y' || inputBuffer[0] =='Y' || inputResponseCnt == 0 )
         {
            check_status( naibrd_AR_ClearStatus( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, 0xFFFF ) );
         }
      }
   }
   return bQuit;
}

/**************************************************************************************************************/
/**
<summary>
This function configures an interrupt to occur when a message is received on the AR channel specified by the
user.
</summary>
*/
/**************************************************************************************************************/
void configureARToInterruptOnRx( InterruptConfig inputInterruptConfig, ArConfig inputARConfig )
{
   int32_t cardIndex = inputARConfig.cardIndex;
   int32_t module = inputARConfig.module;
   int32_t channel = inputARConfig.channel;
   int32_t vector = NAI_AR_INTERRUPT_VECTOR;
   int32_t interrupt_Edge_Trigger = inputInterruptConfig.interrupt_Edge_Trigger;
   int32_t steering = inputInterruptConfig.steering;

   /* clear interruptConfigs of previous channels */
   check_status( naibrd_AR_SetInterruptEnable( cardIndex, module, channel, 0 ) );
   check_status( naibrd_AR_ClearStatus( cardIndex, module, channel, 0xFFFF ) );

   check_status( naibrd_AR_SetInterruptVector( cardIndex, module, channel, vector ) );
   check_status( naibrd_AR_SetInterruptEdgeLevel( cardIndex, module, channel, interrupt_Edge_Trigger ) );  /* Edge triggered */
   check_status( naibrd_AR_SetInterruptSteering( cardIndex, module, channel, steering ) );
}

/**************************************************************************************************************/
/**
<summary>
This function configures an interrupt to occur when a message is received on any of the AR channels specified.
</summary>
*/
/**************************************************************************************************************/
void configureARToInterruptOnRxMultiChan( InterruptConfig inputInterruptConfig, ArConfig inputARConfig )
{
   int32_t idxChan;
   int32_t cardIndex = inputARConfig.cardIndex;
   int32_t module = inputARConfig.module;
   int32_t minChan = inputARConfig.minChannel;
   int32_t maxChan = inputARConfig.maxChannel;
   int32_t vector = NAI_AR_INTERRUPT_VECTOR;
   int32_t interrupt_Edge_Trigger = inputInterruptConfig.interrupt_Edge_Trigger;
   int32_t steering = inputInterruptConfig.steering;

   /* clear interruptConfigs of previous channels */
   for ( idxChan = minChan; idxChan <= maxChan; idxChan++ )
   {
      check_status( naibrd_AR_SetInterruptEnable( cardIndex, module, idxChan, 0 ) );
      check_status( naibrd_AR_ClearStatus( cardIndex, module, idxChan, 0xFFFF ) );

      check_status( naibrd_AR_SetInterruptVector( cardIndex, module, idxChan, vector ) );
      check_status( naibrd_AR_SetInterruptEdgeLevel( cardIndex, module, idxChan, interrupt_Edge_Trigger ) );  /* Edge triggered */
      check_status( naibrd_AR_SetInterruptSteering( cardIndex, module, idxChan, steering ) );
   }
}

/**************************************************************************************************************/
/**
<summary>
DisplayMessage_ARInterrupt handles displaying the messages associated with the msgId passed in.
</summary>
*/
/**************************************************************************************************************/
void DisplayMessage_ARInterrupt( int32_t msgId )
{
   switch (msgId)
   {
      case (int32_t)MSG_BANNER_AR_INT:
      {
         printf( "\n********************************************************************************" );
         printf( "\n******                        AR INTERRUPT                               ******" );
         printf( "\nAn interrupt will occur when the AR module receives a message				   " );
         printf( "\n********************************************************************************" );
      }
      break;

      case (int32_t)MSG_USER_TRIGGER_AR_INT:
      {
         printf( "\nPress \"Q\" to quit the application.\nPlease trigger AR interrupt (Recv Msg):" );
      }
      break;

      case (int32_t)MSG_USER_CLEAR_AR_INT:
      {
         printf( "Press \"C\" to clear interrupts... " );
      }
      break;
   }
}

/**************************************************************************************************************/
/**
<summary>
Enables the channels within the (minChannel, maxChannel) range to interrupt
if enable is true and disables them otherwise.
</summary>
*/
/**************************************************************************************************************/
void enableARInterrupts( ArConfig inputARConfig, bool_t enable )
{
   int32_t channel = inputARConfig.channel;
   int32_t idxChan;

   if ( channel == 0 )
   {
      for ( idxChan = 1; idxChan <= inputARConfig.maxChannel; idxChan++ )
      {
         check_status( naibrd_AR_SetInterruptEnable( inputARConfig.cardIndex, inputARConfig.module, idxChan, enable ) );
      }
   }
   else
   {
      check_status( naibrd_AR_SetInterruptEnable( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, enable ) );
   }
}

/**************************************************************************************************************/
/**
<summary>
GetARLatchStatusTriggerMode handles prompting the user for the trigger mode for the latched status register
(Edge Triggered or Level Triggered).
</summary>
*/
/**************************************************************************************************************/
bool_t GetARLatchStatusTriggerMode( int32_t* interrupt_Edge_Trigger )
{
   bool_t bQuit;
   uint32_t temp;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf( "\nEnter Latched Status Trigger Mode (Edge=0, Level=1) (Default=1): " );
   bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
   if (!bQuit)
   {
      if ( inputResponseCnt > 0 )
      {
         temp = (int32_t)atol( (const char*)inputBuffer );

         if ( temp == 0 || temp == 1 )
         {
            *interrupt_Edge_Trigger = temp;
         }
         else
         {
            printf( "ERROR: Invalid Interrupt Trigger Mode.\n" );
         }
      }
      else
         *interrupt_Edge_Trigger = 1;
   }
   return( bQuit );
}

/**************************************************************************************************************/
/**
<summary>
The routine is called to handle a interrupt. This function alerts checkForInterrupt that an interrupt has occurred.
In vxWorks you must clear the Interrupt on the board within the ISR.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
 void basic_ISR_AR( uint32_t param )
#else
void basic_ISR_AR( void *param, uint32_t vector )
#endif
{
   interruptOccured = TRUE;

#if defined (WIN32)
   UNREFERENCED_PARAMETER( param );
#endif

   #if defined (__VXWORKS__)
      interruptVector = nai_Onboard_GetInterruptVector();
      nai_Onboard_ClearInterrupt();
   #else
      interruptVector = vector;
   #endif
}

/**************************************************************************************************************/
/**
<summary>
This routine takes in the vector of the AR RX interrupt that has just occurred. And gets the status, fifo status,
and fifo data of all channels that interrupted, and prints it.
</summary>
*/
/**************************************************************************************************************/
void handleARInterrupt( uint32_t nVector )
{
   static uint32_t status[NAI_GEN5_AR_MAX_CHANNEL_COUNT + 1];
   static FIFO fifoArrayToPrint[NAI_GEN5_AR_MAX_CHANNEL_COUNT + 1];

   int32_t index;
   int32_t idxChan;
   int32_t minChan;
   int32_t maxChan;
   int32_t outnummsgs;
   int32_t pathDeterminant;

   int32_t bufferCountsArray[NAI_GEN5_AR_MAX_CHANNEL_COUNT + 1];

   uint32_t mask = AR_RX_DATA_AVAIL;
   uint32_t statusMasked;
   uint32_t statArr[NAI_AR_MAX_DATA_LEN];
   uint32_t dataArr[NAI_AR_MAX_DATA_LEN];
   uint32_t tstampArr[NAI_AR_MAX_DATA_LEN];
   minChan = inputARConfig.minChannel;
   maxChan = inputARConfig.maxChannel;

   pathDeterminant = maxChan - minChan;

   naibrd_Wait( 1000000 );

   if ( pathDeterminant >= 0 )
   {
      for ( idxChan = minChan; idxChan <= maxChan; idxChan++ )
      {
         check_status( naibrd_AR_GetStatus( inputARConfig.cardIndex, inputARConfig.module, idxChan, NAI_AR_STATUS_LATCHED, &status[idxChan] ) );
         statusMasked = status[idxChan] & mask;
         if ( statusMasked == mask )
         {
            int32_t outcount;

            fifoArrayToPrint[idxChan].maxDataLength = NAI_AR_MAX_DATA_LEN;
            check_status( naibrd_AR_GetRxBufferCnt( inputARConfig.cardIndex, inputARConfig.module, idxChan, &outcount ) );
            check_status( naibrd_AR_ReadFifo( inputARConfig.cardIndex, inputARConfig.module, idxChan, inputARConfig.timeStampEnable, bufferCountsArray[idxChan], statArr, dataArr, tstampArr, &outnummsgs ) );
            for ( index = 0; index < outcount; index++ )
            {
               fifoArrayToPrint[idxChan].data[index].fifoData = dataArr[index];
               fifoArrayToPrint[idxChan].data[index].fifoStatus = (uint16_t)statArr[index];
               fifoArrayToPrint[idxChan].data[index].fifoTimeStamp = tstampArr[index];
            }
            fifoArrayToPrint[idxChan].length = bufferCountsArray[idxChan] = outcount;
         }
      }
   }
   else if ( pathDeterminant < 0 )
   {
      printf( "ERROR! Min Channel is greater than Max Channel" );
   }
   printf( "\nInterrupt Occurred\n" );
   if ( inputInterruptConfig.bPromptForInterruptClear == TRUE )
   {
      promptUserToClearInterrupt_AR();
   }
   for ( idxChan = minChan; idxChan <= maxChan; idxChan++ )
   {
      check_status( naibrd_AR_ClearStatus( inputARConfig.cardIndex, inputARConfig.module, idxChan, 0xFFFF ) );
   }
   printInterruptInformation_AR( nVector, status, fifoDataFile, bufferCountsArray, fifoArrayToPrint );
}

/**************************************************************************************************************/
/**
<summary>
Function will print the fifoData provided for each channel that has been set in the status register.
It will also print the status and idr id or vector.
</summary>
*/
/**************************************************************************************************************/
void printInterruptInformation_AR( int32_t interruptID, uint32_t* statuses, FILE* stream, int32_t* counts, FIFO* fifos )
{
   uint8_t dataAvailStatus;
   int32_t interruptChannels[NAI_GEN5_AR_MAX_CHANNEL_COUNT + 1];
   uint16_t fifoElementStatus;
   uint32_t fifoElementData;
   uint32_t fifoElementTimeStamp;
   uint32_t fifoLength;
   int32_t maxFifoLength;
   int32_t i;
   int32_t j;

   for ( i = 1; i <= NAI_GEN5_AR_MAX_CHANNEL_COUNT; i++ )
   {
      dataAvailStatus = statuses[i] & AR_RX_DATA_AVAIL;
      if ( dataAvailStatus == 1 )
      {
         interruptChannels[i] = i;
      }
      else
      {
         interruptChannels[i] = 0;
      }
   }

   for ( i = 1; i <= NAI_GEN5_AR_MAX_CHANNEL_COUNT; i++ )
   {
      if ( interruptChannels[i] > 0 )
      {
         fprintf( stream, "Interrupt Information\n" );
         fprintf( stream, "-----------------------------------\n" );
         fprintf( stream, "\nInterrupt Channel = %d \n", i );
         fprintf( stream, "IDR ID = %#x \n", interruptID );
         fprintf( stream, "Status = %#x \n", statuses[i] );

         dataAvailStatus = statuses[i] & AR_RX_DATA_AVAIL;
         if (dataAvailStatus)
         {
            if ( counts[i] == 1 )
            {
               fifoElementStatus = fifos[i].data[0].fifoStatus;
               fifoElementData = fifos[i].data[0].fifoData;
               fifoElementTimeStamp = fifos[i].data[0].fifoTimeStamp;
               fprintf( stream, "\n" );
               fprintf( stream, "Message Status: %#x", fifoElementStatus );
               fprintf( stream, "\n" );
               fprintf( stream, "Message Data: %#x", fifoElementData );
               fprintf( stream, "\n" );
               fprintf( stream, "Time Stamp: %#x", fifoElementTimeStamp );
               fprintf( stream, "\n\n" );
            }
            else if ( counts[i] > 1 )
            {
               fifoLength = fifos[i].length;
               maxFifoLength = fifos[i].maxDataLength;
               fprintf( stream, "\nMax FIFO Word Count: %d\n", maxFifoLength );
               fprintf( stream, "Messages Received (FIFO Word Count): %d\n", fifoLength );
               for ( j = 0; j < counts[i]; j++ )
               {
                  fprintf( stream, "\nMessage Number %d:", j+1 );
                  fifoElementStatus = fifos[i].data[j].fifoStatus;
                  fifoElementData = fifos[i].data[j].fifoData;
                  fifoElementTimeStamp = fifos[i].data[j].fifoTimeStamp;
                  fprintf( stream, "\n" );
                  fprintf( stream, "Message Status: %#x", fifoElementStatus );
                  fprintf( stream, "\n" );
                  fprintf( stream, "Message Data: %#x", fifoElementData );
                  fprintf( stream, "\n" );
                  fprintf( stream, "Time Stamp: %#x", fifoElementTimeStamp );
                  fprintf( stream, "\n\n" );
               }
            }
            else if ( counts[i] < 1 )
            {
               fprintf( stream, "ERROR! naibrd_AR_GetRxBufferCnt returned an invalid value." );
            }
         }
         fprintf( stream, "\n-----------------------------------\n" );
      }
   }
}

void promptUserToClearInterrupt_AR()
{
   /* Prompt the user to clear the interrupt received */
   SetUserRequestClearInt( FALSE );
   printf( "\n" );
   DisplayMessage_ARInterrupt( MSG_USER_CLEAR_AR_INT );

   /* Wait for the user to respond */
   while ( !GetUserRequestClearInt() )
   {
      nai_msDelay( 10 );
   }
}

/**************************************************************************************************************/
/**
<summary>
QueryUserForTimeStampEnable handles querying the user to see if he wants time stamps to be enabled and
included in AR messages. If the user specifies 'N', time stamping will be disabled, else time stamping will
be enabled.
</summary>
*/
/**************************************************************************************************************/
bool_t QueryUserForTimeStampEnable( bool_t* tstampEnable )
{
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* Query the user to determine if he wants time stamps to be included in AR messages */
   printf( "\nWould you like to enable time stamping for messages received? (Y or N) (Default: Y): " );
   bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
   if (!bQuit)
   {
      if ( inputResponseCnt != 0 )
      {
         if ( ( inputBuffer[0] == 'N' ) || ( inputBuffer[0] == 'n' ) )
         {
            *tstampEnable = FALSE;
         }
         else
         {
            *tstampEnable = TRUE;
         }
      }
      else
      {
         *tstampEnable = TRUE;
      }
   }
   return bQuit;
}

void ClearInterrupt_AR()
{
	uint32_t status;
	if (inputInterruptConfig.bPromptForInterruptClear)
	{
		promptUserToClearInterrupt_AR();
	}
   naibrd_AR_GetStatus( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, NAI_AR_STATUS_LATCHED, &status );
   naibrd_AR_ClearStatus( inputARConfig.cardIndex, inputARConfig.module, inputARConfig.channel, status );
}

Help Bot

X