AR Receive
Edit this on GitLab
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:
-
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. -
If the board connection succeeds, enter the main application loop by calling
Run_AR_Receive(). -
After returning from the receive loop, prompt the user to quit or restart.
-
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
|
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_LOWselects 12.5 kHz (low speed); the alternative isAR_SPEED_HIGHfor 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— whenTRUE, 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 |
|---|---|
|
Receive ARINC words without validation (all words accepted) |
|
Receive ARINC words with SDI/Label validation filtering |
|
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
|
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 toTRUEif 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
|
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 ofbool_tvalues.TRUEenables reception for that SDI/Label;FALSEdisables 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
|
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 toTRUEif 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
|
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. |
|
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 |
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 ( |
Data rate mismatch (receiver sees no data) |
Transmitter and receiver configured for different speeds |
Set both to |
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 |
Timestamps all zero |
Timestamp mode not enabled during channel configuration |
Call |
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));
}