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 Receive

AR Receive Sample Application (SSK 1.x)

Overview

The AR Receive sample application demonstrates how to receive ARINC 429 data words using the NAI Software Support Kit (SSK 1.x). ARINC 429 is an avionics data bus standard (ARINC Specification 429) that defines a unidirectional, point-to-point serial bus for communication between aircraft systems. Each ARINC 429 word is 32 bits and carries a structured payload:

Bits Field Description

1-8

Label

Identifies the data type (octal-encoded, transmitted LSB first)

9-10

SDI

Source/Destination Identifier — selects which receiver(s) should process the word

11-29

Data

Payload field (format depends on label definition: BNR, BCD, or discrete)

30-31

SSM

Sign/Status Matrix — indicates data validity, sign, or operational mode

32

Parity

Odd parity bit covering all 32 bits

This sample shows three receive modes:

  • Receive without validation — the channel accepts all incoming ARINC words into the receive FIFO regardless of their label or SDI values. This is the simplest approach and is useful for bus monitoring or diagnostics.

  • Receive with validation — the channel filters incoming words against a validation memory table. Only words whose SDI/Label combination is enabled in the table are stored in the receive FIFO. All other words are discarded. This reduces processing overhead when you only need specific data items.

  • Receive with mailbox — the channel operates in mailbox mode with validation enabled. Incoming words that pass validation are routed to per-SDI/Label mailboxes. The FIFO contains only the SDI/Label identifiers of mailboxes that have received new data. You read the FIFO to discover which mailboxes have been updated, then read the individual mailboxes to retrieve the latest data. This mode is ideal when you need the most recent value for each label rather than a sequential history.

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

For the transmit side of ARINC 429 operations, see AR Transmit. For interrupt-driven receive notification, see AR Interrupt Basic. Consult your AR module’s manual for hardware-specific specifications including FIFO depth, data rate timing, and channel count.

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.

  • An ARINC 429 transmitter connected to the receive channel’s bus (either an external device, a bus analyzer, or another channel on the same module configured for Tx using the AR Transmit sample).

How to Run

Launch the AR_Receive executable from your build output directory. On startup the application looks for a configuration file (CONFIG_FILE.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 channel number, data rate, and timestamp enable setting, then presents a menu to select one of the three receive modes.

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_Receive() on VxWorks) follows a standard SSK 1.x startup flow:

  1. Call naiapp_RunBoardMenu() to load a saved configuration file or present the interactive board menu. The configuration file (CONFIG_FILE.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.

  2. If the board connection succeeds, enter the main application loop by calling Run_AR_Receive().

  3. After returning from the receive loop, prompt the user to quit or restart.

  4. Close all open board connections with naiapp_access_CloseAllOpenCards().

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

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         Run_AR_Receive();
      }

      printf("\nType Q to quit or Enter key to restart application:\n");
      stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   }

   naiapp_access_CloseAllOpenCards();
   return 0;
}
Important

Common Connection Errors

  • No board found — verify the board is powered on and connected. Check your Ethernet cable or PCI seating.

  • Connection timeout — confirm the board’s IP address matches your configuration. Ensure no firewall is blocking the connection.

  • Invalid card/module index — the card index is zero-based. Module numbers depend on the physical slot. Use the board menu to verify available modules.

  • Module not present — the selected slot does not contain an AR module. Verify the module is installed and recognized by the board firmware.

Program Structure

Application Parameters and Defaults

The sample defines default values that serve as prompts during interactive configuration. In your own application, you would set these values directly rather than prompting a user:

#define DEF_AR_CARD_INDEX          0
#define DEF_AR_MODULE              1
#define DEF_AR_RECV_CHANNEL        2
#define DEF_AR_DATA_RATE           AR_SPEED_LOW
#define DEF_AR_TIMESTAMP_ENABLED   TRUE
  • DEF_AR_DATA_RATE — AR_SPEED_LOW selects 12.5 kHz (low speed); the alternative is AR_SPEED_HIGH for 100 kHz (high speed). These are the two data rates defined by ARINC 429.

  • DEF_AR_RECV_CHANNEL — the default receive channel. Channel numbering starts at 1 for this module type. AR1 modules have up to 12 channels; AR2 modules have 2 channels. CM2 and CM5 have 8 AR channels.

  • DEF_AR_TIMESTAMP_ENABLED — when TRUE, each received ARINC word is accompanied by a hardware timestamp. Timestamps are useful for message timing analysis.

Command Menu

The sample presents a three-command menu after channel configuration is complete:

Command Description

NORMAL

Receive ARINC words without validation (all words accepted)

VALID

Receive ARINC words with SDI/Label validation filtering

MAILBOX

Receive ARINC words using mailbox mode with validation

The menu system is a sample convenience — in your own code, call the same naibrd_AR_* API functions directly without the menu infrastructure.

Channel Configuration

Before entering any receive mode, Run_AR_Receive() configures the ARINC channel. This configuration sequence runs each time the user returns to the mode selection menu, ensuring the channel is in a known state. To set up an ARINC receive channel in your own application, follow this sequence:

1. Query for card, module, and channel using the GetARCfg() utility from nai_ar_utils.c. This utility prompts for the card index, module number, and channel number, validating each against the hardware. In your own code, you would supply these values directly.

2. Query for the data rate using GetARINCDataRate(). The data rate must match the transmitter on the bus — a mismatch will cause the receiver to see no data or corrupted data.

3. Reset the channel to clear any prior state:

check_status(naibrd_AR_ChannelReset(cardIndex, module, archan));

4. Disable both transmitter and receiver to prevent activity during configuration:

check_status(naibrd_AR_SetTxEnable(cardIndex, module, archan, AR_DISABLE));
check_status(naibrd_AR_SetRxEnable(cardIndex, module, archan, AR_DISABLE));

5. Set the data rate to either low speed (12.5 kHz) or high speed (100 kHz):

check_status(naibrd_AR_SetDataRate(cardIndex, module, archan, datarate));

The datarate value is AR_SPEED_LOW or AR_SPEED_HIGH. Both the transmitter and receiver on a given bus must use the same data rate.

6. Query the FIFO size and set the receive FIFO threshold to the maximum supported by the module:

moduleID = naibrd_GetModuleID(cardIndex, module);
AR_FIFO_Size = naibrd_AR_GetMaxFifoCount(moduleID);
check_status(naibrd_AR_SetRxFifoThreshold(cardIndex, module, archan, AR_FIFO_Size));

The FIFO threshold determines when the FIFO-almost-full status flag is set. Setting it to the maximum FIFO depth means the flag will indicate when the FIFO is completely full. Consult your module’s manual for the actual FIFO depth — it varies by module type.

7. Configure parity handling so that bit 32 of each received word is treated as an odd parity bit:

check_status(naibrd_AR_SetParityAsData(cardIndex, module, archan, AR_PAR_ODD));

With AR_PAR_ODD, the hardware validates the odd parity bit (bit 32) on each received word and flags parity errors in the status word. If you set AR_PAR_DATA, bit 32 is treated as a data bit and parity checking is disabled.

8. Enable error storage so that words with errors are still stored in the FIFO (with error flags in the status word) rather than being silently discarded:

check_status(naibrd_AR_SetRxStoreErrorDisable(cardIndex, module, archan, AR_STORE_ON_ERROR_ENABLE));

This is useful for diagnostics — you can see which words arrived with parity or gap errors. If you prefer to discard erroneous words, pass AR_STORE_ON_ERROR_DISABLE.

9. Configure timestamp mode to attach a hardware timestamp to each received word:

naibrd_AR_SetRxTimeStampEn(cardIndex, module, archan, bTimestampEnabled);

When enabled, each FIFO read returns a timestamp value alongside the data and status words. Timestamps record the time of arrival relative to the module’s internal clock. This is useful for measuring inter-message timing or correlating data across channels.

Important

Common Configuration Errors

  • NAI_ERROR_NOT_SUPPORTED — the selected channel number exceeds the channel count for this module type. AR2 modules have 2 channels; AR1 modules have up to 12; CM2 and CM5 have 8.

  • Data rate mismatch — if the receiver and transmitter are on different data rates, the receiver will see no data. Ensure both sides use the same setting.

  • Parity errors on every word — if the transmitter uses AR_PAR_DATA (parity as data) but the receiver expects AR_PAR_ODD, every word will be flagged with a parity error. Ensure both sides agree on parity handling.

Receive Without Validation (FIFO Mode)

This is the simplest receive mode. The channel accepts all incoming ARINC words into the receive FIFO regardless of their SDI/Label values. Every word that arrives on the bus is stored and can be read. This mode is well-suited for bus monitoring, diagnostics, or scenarios where you need to capture all traffic.

Configuring the Mode

To receive without validation, set the receive mode to FIFO and explicitly disable validation:

/* Enable FIFO mode */
check_status(naibrd_AR_SetRxMode(cardIndex, module, channel, AR_RX_FIFO_MODE));

/* Disable Validation */
naibrd_AR_SetRxValidationEn(cardIndex, module, channel, FALSE);

AR_RX_FIFO_MODE configures the channel so that all received words are placed sequentially into the receive FIFO. Disabling validation with naibrd_AR_SetRxValidationEn(…​, FALSE) ensures that no SDI/Label filtering is applied — every word is accepted.

Reading the FIFO

After configuring the mode, clear the FIFO of any stale data and enable the receiver:

/* Clear Rx FIFO */
check_status(naibrd_AR_ClearRxFifo(cardIndex, module, channel));

/* Enable Receiver */
check_status(naibrd_AR_SetRxEnable(cardIndex, module, channel, AR_ENABLE));

To read received data, poll the FIFO buffer count and read when data is available:

check_status(naibrd_AR_GetRxBufferCnt(cardIndex, module, channel, &nNumWordsRecv));
if (nNumWordsRecv > 0)
{
   check_status(naibrd_AR_ReadFifo(cardIndex, module, channel, bTimestampEnabled,
      nNumWordsRecv, RecvStatusWd, RecvData, RecvTimeStamp, &nNumWordsRecv));
}

Parameters for naibrd_AR_ReadFifo():

  • cardIndex, module, channel — identify the receive channel.

  • bTimestampEnabled — set to TRUE if timestamps were enabled during channel configuration. This tells the API to read timestamp values alongside each data word.

  • nNumWordsRecv (input) — the number of words to read from the FIFO.

  • RecvStatusWd — output array of 32-bit status words, one per received ARINC word. Status bits indicate parity errors, gap errors, and other conditions. Consult your module’s manual for the status word bit definitions.

  • RecvData — output array of 32-bit received ARINC data words.

  • RecvTimeStamp — output array of 32-bit timestamp values (only populated when timestamps are enabled).

  • nNumWordsRecv (output) — the actual number of words read.

The sample polls in a timed loop, reading for a user-specified duration. In your own application, you could also use interrupt-driven notification (see the AR Interrupt Basic sample) to avoid polling.

Important

Common Errors — Receive Without Validation

  • FIFO empty (no data received) — verify that a transmitter is active on the bus, the data rate matches, and the receiver is enabled. Check physical cabling.

  • FIFO overflow — if you do not read the FIFO frequently enough, it will fill up and new words will be lost. Increase your polling frequency or use interrupts.

  • Parity error flags in status words — check parity settings on both transmitter and receiver. Also verify that the bus is electrically clean.

Receive With Validation (FIFO Mode)

Validation mode adds SDI/Label filtering to FIFO reception. The channel maintains a validation memory table with 1024 entries (one per possible SDI/Label combination, from 0x000 to 0x3FF). Only words whose SDI/Label combination has its validation bit set to TRUE are stored in the receive FIFO. All other words are silently discarded by the hardware.

This mode is useful when you only need specific data items from a busy ARINC bus — it prevents unwanted messages from filling the FIFO and reduces the processing load on your application.

Configuring the Mode

To receive with validation, set the receive mode to FIFO (same as without validation) and then enable and configure the validation table:

/* Enable FIFO mode */
check_status(naibrd_AR_SetRxMode(cardIndex, module, channel, AR_RX_FIFO_MODE));

/* Enable Validation for select SDI/Labels */
EnableValidation(cardIndex, module, channel);

Setting Up the Validation Table

The EnableValidation() function demonstrates how to configure the validation memory. The validation table has 1024 entries indexed by the 10-bit SDI/Label value (SDI in bits 9-8, Label in bits 7-0). Each entry is a boolean that controls whether words with that SDI/Label combination are accepted or rejected.

To enable validation and write the table in your own application:

/* Enable Validation */
naibrd_AR_SetRxValidationEn(cardIndex, module, channel, TRUE);

/* Build the validation array */
bool_t ValEnableArray[0x400] = { FALSE };

/* Enable every 8th SDI/Label combination */
for (i = 0; i < sizeof(ValEnableArray); i++)
{
   if ((i + 1) % 8 == 0)
   {
      ValEnableArray[i] = TRUE;
   }
}

/* Write the validation table to hardware */
check_status(naibrd_AR_WrRxValMemRange(cardIndex, module, channel, 0x000, 0x3FF, ValEnableArray));

Parameters for naibrd_AR_WrRxValMemRange():

  • cardIndex, module, channel — identify the receive channel.

  • 0x000 — the starting SDI/Label index.

  • 0x3FF — the ending SDI/Label index (inclusive). The full range is 0x000 to 0x3FF (1024 entries).

  • ValEnableArray — array of bool_t values. TRUE enables reception for that SDI/Label; FALSE disables it.

The sample enables every 8th SDI/Label combination as a demonstration. In your own application, you would set specific entries to TRUE based on the labels and SDI values you need to receive. For example, to accept only Label 0x15 with SDI 0, you would set ValEnableArray[0x015] = TRUE and leave all others FALSE.

Reading Validated Data

After configuring validation, the FIFO reading process is identical to receive without validation — call naibrd_AR_ClearRxFifo(), naibrd_AR_SetRxEnable(), then poll with naibrd_AR_GetRxBufferCnt() and naibrd_AR_ReadFifo(). The only difference is that the FIFO now contains only words that passed the validation filter.

Important

Common Errors — Receive With Validation

  • FIFO empty despite active transmitter — validation is enabled but no SDI/Label combinations are set to TRUE in the validation table. Verify that the labels being transmitted are enabled in your validation array.

  • Missing expected labels — the SDI/Label index is a 10-bit value combining SDI (bits 9-8) and Label (bits 7-0). Make sure you are computing the correct index for the label and SDI values you expect to receive.

  • Receiving unexpected words — verify that only the intended entries in the validation array are set to TRUE. A stale validation table from a previous run may contain unintended entries. Call naibrd_AR_ChannelReset() or rewrite the entire table to start clean.

Receive With Mailbox

Mailbox mode changes how received data is organized. Instead of storing complete ARINC words sequentially in the FIFO, the hardware routes each validated word to a dedicated mailbox indexed by its SDI/Label value. The FIFO then contains only the SDI/Label identifiers of mailboxes that have received new data since the last read. This provides a "latest value" model — each mailbox always holds the most recent word for its SDI/Label combination.

This mode is ideal for applications that need to monitor the current state of multiple data parameters. Instead of processing every received word in arrival order, you simply read the mailbox for each label of interest to get the latest value.

Configuring the Mode

To receive in mailbox mode, set the receive mode to mailbox and enable validation. Validation is required for mailbox mode because the hardware uses the SDI/Label value to route words to the correct mailbox.

/* Enable MailBox mode */
check_status(naibrd_AR_SetRxMode(cardIndex, module, channel, AR_RX_MBOX_MODE));

/* Enable Validation for select SDI/Labels */
EnableValidation(cardIndex, module, channel);

AR_RX_MBOX_MODE tells the hardware to operate in mailbox mode. The validation table setup is the same as for receive with validation — call naibrd_AR_SetRxValidationEn() and naibrd_AR_WrRxValMemRange() as described in the previous section.

Reading Mailbox Data

In mailbox mode, reading is a two-step process:

Step 1: Read the FIFO to discover which mailboxes have new data. Each FIFO entry contains the SDI/Label identifier (not the full ARINC word) of a mailbox that received a new message:

check_status(naibrd_AR_SetRxEnable(cardIndex, module, channel, AR_ENABLE));

check_status(naibrd_AR_GetRxBufferCnt(cardIndex, module, channel, &nNumWordsRecv));
if (nNumWordsRecv > 0)
{
   /* Read FIFO words for new MailBox addresses */
   for (i = 0; i < nNumWordsRecv; i++)
   {
      check_status(naibrd_AR_ReadFifoMBox(cardIndex, module, channel, &Label[i]));
   }
}

naibrd_AR_ReadFifoMBox() reads one SDI/Label identifier from the FIFO. The Label value is a 10-bit index (0x000 to 0x3FF) that identifies which mailbox has new data.

Step 2: Read each mailbox to get the latest data. Using the SDI/Label identifiers from Step 1, read the corresponding mailboxes:

for (i = 0; i < nNumWordsRecv; i++)
{
   check_status(naibrd_AR_ReadMBox(cardIndex, module, channel, bTimestampEnabled,
      Label[i], &MailRecvStatusWd, &MailRecvData, &MailRecvTimeStamp));
}

Parameters for naibrd_AR_ReadMBox():

  • cardIndex, module, channel — identify the receive channel.

  • bTimestampEnabled — set to TRUE if timestamps were enabled during channel configuration.

  • Label[i] — the SDI/Label index of the mailbox to read (obtained from the FIFO in Step 1).

  • MailRecvStatusWd — output 16-bit status word for the mailbox entry. Consult your module’s manual for status bit definitions.

  • MailRecvData — output 32-bit ARINC data word (the most recent word received for this SDI/Label).

  • MailRecvTimeStamp — output 32-bit timestamp (only populated when timestamps are enabled).

Note that unlike FIFO mode, the mailbox always contains only the most recent word for each SDI/Label. If multiple words with the same SDI/Label arrive between reads, only the last one is retained. If your application needs to process every individual word, use FIFO mode instead.

Important

Common Errors — Mailbox Mode

  • FIFO empty despite active transmitter — validation is required for mailbox mode. Verify that validation is enabled and the transmitted SDI/Label combinations are enabled in the validation table.

  • Stale mailbox data — a mailbox retains its last value until overwritten by a new word with the same SDI/Label. If the transmitter stops, the mailbox will still return the last received value. Check the FIFO to determine whether new data has actually arrived.

  • Duplicate SDI/Label entries in the FIFO — if the transmitter sends the same SDI/Label faster than you read, the FIFO may contain multiple entries for the same mailbox. Reading the mailbox returns the latest value regardless of how many FIFO entries point to it.

  • NAI_ERROR_NOT_SUPPORTED — mailbox mode may not be available on all module types. Consult your module’s manual for feature availability.

Troubleshooting Reference

Note
This section summarizes errors covered in the preceding sections. Consult your AR module’s manual for hardware-specific diagnostics and status register definitions.
Error / Symptom Possible Causes Suggested Resolution

No board found at startup

Board not powered, cable disconnected, wrong IP address

Verify power, cabling, and network configuration. Re-run the board menu to reconfigure.

Module not present

Selected slot does not contain an AR module

Verify the module is physically installed. Use the board menu to check available modules.

NAI_ERROR_NOT_SUPPORTED

Channel number exceeds module’s channel count; feature not available on this module type

Check the channel count for your module type (AR1: up to 12, AR2: 2, CM2/CM5: 8).

No data received (FIFO empty)

No transmitter on the bus; data rate mismatch; receiver not enabled; validation enabled with no labels set to TRUE

Verify a transmitter is active, data rates match, receiver is enabled with naibrd_AR_SetRxEnable(), and validation settings are correct.

FIFO overflow / data lost

Not reading the FIFO frequently enough; transmitter sending faster than software can consume

Increase polling frequency, use interrupts (see AR Interrupt Basic), or increase the FIFO threshold.

Parity errors on every word

Transmitter and receiver parity settings do not match

Ensure both sides use the same parity mode (AR_PAR_ODD or AR_PAR_DATA).

Data rate mismatch (receiver sees no data)

Transmitter and receiver configured for different speeds

Set both to AR_SPEED_LOW (12.5 kHz) or both to AR_SPEED_HIGH (100 kHz).

Validation filtering wrong labels

Incorrect SDI/Label index calculation; stale validation table from previous run

The index is a 10-bit value: SDI in bits 9-8, Label in bits 7-0. Reset the channel or rewrite the full validation table.

Mailbox returns stale data

Transmitter stopped; mailbox retains last value until overwritten

Check the FIFO for new SDI/Label entries before reading mailboxes. A mailbox read without a corresponding FIFO entry returns the previously stored value.

Missing labels in mailbox mode

Validation not enabled; SDI/Label not set to TRUE in validation table

Mailbox mode requires validation. Verify naibrd_AR_SetRxValidationEn() is called with TRUE and the correct entries are enabled.

Timestamps all zero

Timestamp mode not enabled during channel configuration

Call naibrd_AR_SetRxTimeStampEn() with TRUE before enabling the receiver.

Full Source

Full Source — AR_Receive.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

/* Common Sample Program include files */
#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"
#include "nai_ar_utils.h"

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

static const int8_t *CONFIG_FILE = (int8_t *)"CONFIG_FILE.txt";

/* Function prototypes */
void Run_AR_Receive(void);
nai_status_t AR_RxWithoutValidation(int32_t paramCount, int32_t* p_params);
nai_status_t AR_RxWithValidation(int32_t paramCount, int32_t* p_params);
nai_status_t AR_RxWithMailbox(int32_t paramCount, int32_t* p_params);
bool_t RxAndDisplayFIFOMsgs(int32_t cardIndex, int32_t module, int32_t channel);
bool_t RxandDisplayFIFOandMailBox(int32_t cardIndex, int32_t module, int32_t channel);
void EnableValidation(int32_t cardIndex, int32_t module, int32_t channel);

/****** Command Table *******/
enum arfuncgen_commands
{
   AR_FUNCGEN_CMD_RX_WITHOUT_VALIDATION,
   AR_FUNCGEN_CMD_RX_WITH_VALIDATION,
   AR_FUNCGEN_CMD_RX_WITH_MAILBOX,
   AR_FUNCGEN_CMD_COUNT
};

/****** Command Tables *******/
static naiapp_cmdtbl_params_t AR_FuncGenMenuCmds[] =
{
   {"NORMAL ", "AR Receive Without Validation", AR_FUNCGEN_CMD_RX_WITHOUT_VALIDATION,  AR_RxWithoutValidation},
   {"VALID  ", "AR Receive With Validation   ", AR_FUNCGEN_CMD_RX_WITH_VALIDATION,     AR_RxWithValidation},
   {"MAILBOX", "AR Receive Using Mailbox     ", AR_FUNCGEN_CMD_RX_WITH_MAILBOX,        AR_RxWithMailbox}
};

#define DEF_AR_CARD_INDEX                 0
#define DEF_AR_MODULE                     1
#define DEF_AR_RECV_CHANNEL               2
#define DEF_AR_DATA_RATE                  AR_SPEED_LOW
#define DEF_AR_TIMESTAMP_ENABLED          TRUE

static bool_t bTimestampEnabled = FALSE;

/**************************************************************************************************************/
/**
<summary>
The purpose of the AR_Receive is to illustrate the methods to call in the naibrd library to configure
the ARINC channel to receive ARINC messages. ARINC data messages can be retrieved as follows:
a)  Using Validation to selectively receive data that match enabled SDI/Labels, or
b)  Using Mailbox mode to read mailboxes of the matched SDI/Labels found in the receive FIFO, or
c)  Receiving all of the transmitted data in the receive FIFO (without validation).

The following system configuration routines from the nai_sys_cfg.c file are called to assist with the configuration
setup for this program prior to calling the naibrd ARINC routines.
 - ClearDeviceCfg
 - QuerySystemCfg
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - SaveDeviceCfg

Note, the AR_Receive application can run in conjunction with the AR_Transmit applications to illustrate
ARINC receive and transmit operations together with the NAI ARINC module.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t AR_Receive(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         Run_AR_Receive();
      }

      printf("\nType Q to quit or Enter key to restart application:\n");
      stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   }

   naiapp_access_CloseAllOpenCards();

   return 0;
}

nai_status_t AR_RxWithoutValidation(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit;
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t channel = p_ad_params->channel;

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

   /* Enable FIFO mode */
   check_status(naibrd_AR_SetRxMode(cardIndex, module, channel, AR_RX_FIFO_MODE));

   /* Disable Validation */
   naibrd_AR_SetRxValidationEn(cardIndex, module, channel, FALSE);

   /* Enable Receiver and Display Data Received in the Rx FIFO */
   bQuit = RxAndDisplayFIFOMsgs(cardIndex, module, channel);

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

nai_status_t AR_RxWithValidation(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit;
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t channel = p_ad_params->channel;

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

   /* Enable FIFO mode */
   check_status(naibrd_AR_SetRxMode(cardIndex, module, channel, AR_RX_FIFO_MODE));

   /* Enable Validation for select SDI/Labels */
   EnableValidation(cardIndex, module, channel);

   /* Enable Receiver and Display Data Received in the Rx FIFO */
   bQuit = RxAndDisplayFIFOMsgs(cardIndex, module, channel);

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

nai_status_t AR_RxWithMailbox(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit;
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t channel = p_ad_params->channel;

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

   /* Enable MailBox mode */
   check_status(naibrd_AR_SetRxMode(cardIndex, module, channel, AR_RX_MBOX_MODE));

   /* Enable Validation for select SDI/Labels */
   EnableValidation(cardIndex, module, channel);

   /* Enable Receiver and Read FIFO for Mailbox Addresses that have new messages, then read these Mailboxes to get new data */
   bQuit = RxandDisplayFIFOandMailBox(cardIndex, module, channel);

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Run_AR_Receive queries the user for the card, module and channel to configure as the ARINC receiver
as well as the data rate (high (100KHz) or low (12.5KHz)) and how to retrieve the ARINC messages.
Methods in the naibrd library are invoked to configure the ARINC channel.
</summary>
*/
/**************************************************************************************************************/
void Run_AR_Receive(void)
{
   int32_t cardIndex, module, archan;
   bool_t bQuit = FALSE;
   bool_t bContinue, bCmdFound;
   int32_t cmd;
   nai_ar_datarate_t datarate;
   uint32_t moduleID;
   int32_t AR_FIFO_Size;
   naiapp_AppParameters_t  ar_params;
   p_naiapp_AppParameters_t ar_receive_params = &ar_params;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   bQuit = GetARCfg(DEF_AR_CARD_INDEX, DEF_AR_MODULE, DEF_AR_RECV_CHANNEL, &cardIndex, &module, &archan);
   ar_receive_params->cardIndex = cardIndex;
   ar_receive_params->module = module;
   ar_receive_params->channel = 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));
         /* Disable Tx/Rx */
         check_status(naibrd_AR_SetTxEnable(cardIndex, module, archan, AR_DISABLE));
         check_status(naibrd_AR_SetRxEnable(cardIndex, module, archan, AR_DISABLE));
         /* Set the transmission speed */
         check_status(naibrd_AR_SetDataRate(cardIndex, module, archan, datarate));
         /* Set the Rx Fifo Threshold to the maximum size of the FIFO */
         moduleID = naibrd_GetModuleID(cardIndex, module);
         AR_FIFO_Size = naibrd_AR_GetMaxFifoCount(moduleID);
         check_status(naibrd_AR_SetRxFifoThreshold(cardIndex, module, archan, AR_FIFO_Size));
         /* Set the Parity Disable bit to cause the ARINC bit 32 to be treated as an odd parity bit */
         check_status(naibrd_AR_SetParityAsData(cardIndex, module, archan, AR_PAR_ODD));
         check_status(naibrd_AR_SetRxStoreErrorDisable(cardIndex, module, archan, AR_STORE_ON_ERROR_ENABLE));

         /* Query for Timestamp Mode Enable */
         bQuit = GetARReceiverTimestampEnabled(DEF_AR_TIMESTAMP_ENABLED, &bTimestampEnabled);
         if (!bQuit)
         {
            /* Set Timestamp Enable */
            naibrd_AR_SetRxTimeStampEn(cardIndex, module, archan, bTimestampEnabled);

            bContinue = TRUE;

            naiapp_utils_LoadParamMenuCommands(AR_FUNCGEN_CMD_COUNT, AR_FuncGenMenuCmds);
            while (bContinue)
            {
               naiapp_display_ParamMenuCommands((int8_t *)"AR Receive Mode Menu");
               printf("\nType AR command or %c to quit : ", NAI_QUIT_CHAR);
               bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               if (!bQuit)
               {
                  if (inputResponseCnt > 0)
                  {
                     bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
                     if (bCmdFound)
                     {
                        switch (cmd)
                        {
                        case AR_FUNCGEN_CMD_RX_WITHOUT_VALIDATION:
                        case AR_FUNCGEN_CMD_RX_WITH_VALIDATION:
                        case AR_FUNCGEN_CMD_RX_WITH_MAILBOX:
                           AR_FuncGenMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)ar_receive_params);
                           break;
                        default:
                           printf("Invalid command entered\n");
                           break;
                        }
                     }
                     else
                        printf("Invalid command entered\n");
                  }
               }
               else
                  bContinue = FALSE;
            }
         }
      }
   }
   return;
}

bool_t RxAndDisplayFIFOMsgs(int32_t cardIndex, int32_t module, int32_t channel)
{
   time_t end;
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   int32_t i;
   int32_t nNumWordsRecv;
   uint32_t RecvStatusWd[A4_MAX_FIFO_COUNT];
   uint32_t RecvData[A4_MAX_FIFO_COUNT];
   uint32_t RecvTimeStamp[A4_MAX_FIFO_COUNT];
   int32_t duration;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* Clear Rx FIFO */
   check_status(naibrd_AR_ClearRxFifo(cardIndex, module, channel));

   /* Enable Receiver */
   check_status(naibrd_AR_SetRxEnable(cardIndex, module, channel, AR_ENABLE));

   bContinue = TRUE;
   while (bContinue)
   {
      printf("\nType duration (in seconds) for ARINC receive messages test or %c to quit (default: 300) : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         duration = 5;
         if (inputResponseCnt > 0)
            duration = (int32_t)atol((const char*)inputBuffer);

         end = time(NULL) + duration;

         /* Read data */
         while (time(NULL) < end)
         {
            check_status(naibrd_AR_GetRxBufferCnt(cardIndex, module, channel, &nNumWordsRecv));
            if (nNumWordsRecv > 0)
            {
               printf("\nReading back %d words ...\n", nNumWordsRecv);
               check_status(naibrd_AR_ReadFifo(cardIndex, module, channel, bTimestampEnabled, nNumWordsRecv, RecvStatusWd, RecvData, RecvTimeStamp, &nNumWordsRecv)); /* read back data */
               for (i = 0; i < nNumWordsRecv; i++)
               {
                  printf("Status: 0x%08X ", RecvStatusWd[i]);
                  printf("Data: 0x%08X ", RecvData[i]);
                  if (bTimestampEnabled)
                  {
                     printf("TimeStamp: 0x%08X\n", RecvTimeStamp[i]);
                  }
               }
            }
#if defined (__VXWORKS__)
            taskDelay(1);
#endif
         }
      }
      else
         bContinue = FALSE;
         }
   return bQuit;
      }

bool_t RxandDisplayFIFOandMailBox(int32_t cardIndex, int32_t module, int32_t channel)
{
   time_t end;
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   uint32_t Label[A4_MAX_FIFO_COUNT];
   int32_t nNumWordsRecv = 16;
   uint16_t MailRecvStatusWd;
   uint32_t MailRecvData;
   uint32_t MailRecvTimeStamp;
   int32_t duration;
   int32_t i;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* Enable Receiver */
   check_status(naibrd_AR_SetRxEnable(cardIndex, module, channel, AR_ENABLE));

   while (bContinue)
   {
      printf("\nType duration (in seconds) for ARINC receive messages test or %c to quit (default: 5) : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         duration = 5;
         if (inputResponseCnt > 0)
            duration = (int32_t)atol((const char*)inputBuffer);

         end = time(NULL) + duration;

         /* Read data */
         while (time(NULL) < end)
         {
            check_status(naibrd_AR_GetRxBufferCnt(cardIndex, module, channel, &nNumWordsRecv));
            if (nNumWordsRecv > 0)
            {
               /* Read FIFO words for new MailBox addresses */
               printf(" %d words received\n", nNumWordsRecv);
               printf("\nSDI/Labels in FIFO\n");
               for (i = 0; i < nNumWordsRecv; i++)
               {
                  check_status(naibrd_AR_ReadFifoMBox(cardIndex, module, channel, &Label[i]));
                  printf("Label %d = %03X\n", i, Label[i]);
               }

               /* Using SDI / Labels from FIFO, read MailBoxes to get new data */
               printf("\nMailboxes with SDI/Labels read from FIFO\n");
               for (i = 0; i < nNumWordsRecv; i++)
               {
                  check_status(naibrd_AR_ReadMBox(cardIndex, module, channel, bTimestampEnabled, Label[i], &MailRecvStatusWd, &MailRecvData, &MailRecvTimeStamp)); /* read MailBox */
                  if (bTimestampEnabled)
                  {
                     printf("SDI/Label %03X status = %04X, data = %08X, timestamp = %08X\n",
                        Label[i], MailRecvStatusWd, MailRecvData, MailRecvTimeStamp);
                  }
                  else
                  {
                     printf("SDI/Label %03X status = %04X, data = %08X\n",
                        Label[i], MailRecvStatusWd, MailRecvData);
                  }
               }
            }
#if defined (__VXWORKS__)
            taskDelay(1);
#endif
         }
      }
      else
         bContinue = FALSE;
         }
   return bQuit;
      }

void EnableValidation(int32_t cardIndex, int32_t module, int32_t channel)
{
   int32_t i;
   bool_t ValEnableArray[0x400] = { FALSE };

   /* Enable Validation */
   naibrd_AR_SetRxValidationEn(cardIndex, module, channel, TRUE);

   /* Create array of size 0x400 where every 8th element is set TRUE and all others FALSE */
   for (i = 0; i < sizeof(ValEnableArray); i++)
   {
      if ((i + 1) % 8 == 0)
      {
         ValEnableArray[i] = TRUE;
      }
   }
   /* Enable Validation for every 8th SDI/Label combination from 0x000 to 0x3FF */
   check_status(naibrd_AR_WrRxValMemRange(cardIndex, module, channel, 0x000, 0x3FF, ValEnableArray));
}

Help Bot

X