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

AR2 Receive

AR2 Receive

Explanation

About This Code

This C code demonstrates the methods required to configure an ARINC channel to receive ARINC messages using North Atlantic Industries (NAI) libraries. It uses the NAI Software Support Kit (SSK) to interact with embedded function modules. The code supports different ARINC channels and displays received ARINC data in a sequence.

Key Components

Include Files

  • Standard Libraries:

  • stdio.h, stdlib.h, string.h, time.h, ctype.h

  • NAI Application-Specific Libraries:

  • naiapp_boardaccess_menu.h, naiapp_boardaccess_query.h, naiapp_boardaccess_access.h, naiapp_boardaccess_display.h, naiapp_boardaccess_utils.h, nai_ar_utils.h

  • nai.h, naibrd.h, naibrd_ar.h

Constants

  • static const int8_t *CONFIG_FILE: Configuration file for default ARINC receive settings, "default_AR2Recv.txt".

Function Prototypes

  • Top-Level and Utility Functions

  • void Run_AR2_Receive(int32_t cardIndex, int32_t module)

  • static nai_status_t AR_Rx568(int32_t paramCount, int32_t* p_params)

  • static nai_status_t AR_Rx579(int32_t paramCount, int32_t* p_params)

  • static bool_t RxAndDisplayFIFOMsgs(int32_t cardIndex, int32_t module, int32_t channel)

Enumerations and Command Tables

  • enum arfuncgen_commands: Enumerations for different ARINC receive commands.

  • AR_FUNCGEN_CMD_RX_568

  • AR_FUNCGEN_CMD_RX_579

  • AR_FUNCGEN_CMD_COUNT

  • static naiapp_cmdtbl_params_t AR_FuncGenMenuCmds[]: Command descriptions and associated functions.

  • Example: {"568 ", "AR Receive on AR-568 Channel", AR_FUNCGEN_CMD_RX_568, AR_Rx568}

Default Configuration Values

  • Defaults for card index, module, channel, data rate, and timestamp options:

  • #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

Main Function

Conditional Compilation

  • #if defined (VXWORKS) / #else: Compiling consideration for different platforms (VxWorks or other).

Initialization and Loop

  • Initialization and User Query:

  • The code initializes stop, cardIndex, and other variables.

  • Queries the user for the card index and module number using NAI library functions (naiapp_query_CardIndex, naiapp_query_ModuleNumber).

  • Loop Mechanism:

  • The user is repeatedly prompted to either quit or restart the application:

  • "Type Q to quit or Enter key to restart application"

Execution

  • Configuration Setup:

  • The code clears previous configurations and retrieves the new setup using helper functions from nai_sys_cfg.c.

  • ARINC Receive Operations:

  • The Run_AR2_Receive function handles receiving operations depending on the user inputs.

  • Configurations are set using methods from the naibrd library.

Functions for Specific ARINC Channels

  • AR_Rx568: Configures and fetches ARINC data for AR-568 channel.

  • AR_Rx579: Configures and fetches ARINC data for AR-579 channel.

Helper Fuctions - RxAndDisplayFIFOMsgs: Receives and displays data from the Rx FIFO buffer. - Resets and configures the channel. - Enables/Disables Rx and Tx. - Fetches and displays ARINC messages. - Handles periodic checks and data retrieval.

Summary

This code shows how to use the NAI’s SSK to configure and receive ARINC messages from specified channels. The process involves querying the user for configuration parameters, setting up the ARINC channel using the naibrd functions, and displaying the received data. The code is highly modular, handling different ARINC channels and displaying data based on FIFO statuses and timestamps if enabled.

#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 *)"default_AR2Recv.txt";

/* Function prototypes */
void Run_AR2_Receive(int32_t cardIndex, int32_t module);
static nai_status_t AR_Rx568(int32_t paramCount, int32_t* p_params);
static nai_status_t AR_Rx579(int32_t paramCount, int32_t* p_params);
static bool_t RxAndDisplayFIFOMsgs( int32_t cardIndex, int32_t module, int32_t channel );

/****** Command Table *******/
enum arfuncgen_commands
{
   AR_FUNCGEN_CMD_RX_568,
   AR_FUNCGEN_CMD_RX_579,
   AR_FUNCGEN_CMD_COUNT
};

/****** Command Tables *******/
static naiapp_cmdtbl_params_t AR_FuncGenMenuCmds[] =
{
   {"568 ", "AR Receive on AR-568 Channel    ", AR_FUNCGEN_CMD_RX_568,  AR_Rx568},
   {"579 ", "AR Receive on AR-579 Channel    ", AR_FUNCGEN_CMD_RX_579,  AR_Rx579}
};

#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 AR2_Receive(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;

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

            /* Query the user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               Run_AR2_Receive(cardIndex, module);

            }
         }
         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;
}

static nai_status_t AR_Rx568(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 Receiver and Display Data Received in the Rx FIFO */
   bQuit = RxAndDisplayFIFOMsgs( cardIndex, module, channel );    /* Channel 1 is AR-568 */

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t AR_Rx579(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 Receiver and Display Data Received in the Rx FIFO */
   bQuit = RxAndDisplayFIFOMsgs( cardIndex, module, channel );    /* Channel 2 is AR-579 */

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Run_AR2_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_AR2_Receive(int32_t cardIndex, int32_t module)
{
   bool_t bQuit = FALSE;
   bool_t bContinue, bCmdFound;
   int32_t cmd;
   naiapp_AppParameters_t  ar2_params;
   p_naiapp_AppParameters_t ar2_receive_params = &ar2_params;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   bQuit = GetAR2Cfg( DEF_AR_CARD_INDEX, DEF_AR_MODULE, &cardIndex, &module );
   ar2_receive_params->cardIndex = cardIndex;
   ar2_receive_params->module = module;

   if (!bQuit)
   {
      bContinue = TRUE;

      naiapp_utils_LoadParamMenuCommands( AR_FUNCGEN_CMD_COUNT, AR_FuncGenMenuCmds );
      while (bContinue)
      {
         naiapp_display_ParamMenuCommands( (int8_t *)"AR2 Receive Mode Menu" );
         printf( "\nType AR2 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_568: /* Channel 1 is AR-568 */
                     case AR_FUNCGEN_CMD_RX_579: /* Channel 2 is AR-579 */
                        ar2_receive_params->channel = cmd + 1;
                        AR_FuncGenMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)ar2_receive_params);
                        break;
                     default:
                        printf( "Invalid command entered\n" );
                        break;
                  }
               }
               else
                  printf( "Invalid command entered\n" );
            }
         }
         else
            bContinue = FALSE;
      }
   }
   return;
}

static 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, nNumMsgsRecv;
   uint32_t RecvStatusWd[AR2_MAX_FIFO_COUNT];
   uint32_t RecvData[AR2_MAX_FIFO_COUNT];
   uint32_t RecvTimeStamp[AR2_MAX_FIFO_COUNT];
   int32_t duration;
   uint32_t moduleID;
   int32_t AR_FIFO_Size;
   bool_t bRxBoundedFIFOenable;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* Reset the channel */
   check_status( naibrd_AR_ChannelReset( cardIndex, module, channel ) );

   /* Disable Tx/Rx */
   check_status( naibrd_AR_SetTxEnable( cardIndex, module, channel, AR_DISABLE ) );
   check_status( naibrd_AR_SetRxEnable( cardIndex, module, channel, AR_DISABLE ) );

   /* Set the Rx Almost Full Fifo Threshold to the maximum size of the FIFO and the Almost Empty Threshold to zero */
   moduleID = naibrd_GetModuleID( cardIndex, module );
   AR_FIFO_Size = naibrd_AR_GetMaxFifoCount( moduleID );
   check_status( naibrd_AR_SetRxFifoThresholds( cardIndex, module, channel, 0, AR_FIFO_Size - 1 ) );

   bQuit = GetARRxBoundedFIFOEnable(AR_ENABLE, &bRxBoundedFIFOenable);
   if (!bQuit)
   {
      check_status( naibrd_AR_SetRxFifoBounded( cardIndex, module, channel, bRxBoundedFIFOenable ) );

      if (channel == 2) /* AR-579 */
      {
         /* 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, channel, AR_PAR_ODD ) );
         check_status( naibrd_AR_SetRxStoreErrorDisable( cardIndex, module, channel, 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, channel, bTimestampEnabled );
         }
      }

      /* 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 )
               {
                  check_status( naibrd_AR_ReadFifo( cardIndex, module, channel, bTimestampEnabled, nNumWordsRecv, RecvStatusWd, RecvData, RecvTimeStamp, &nNumMsgsRecv ) ); /* read back data */
                  printf( "\nReading back %d messages ...\n", nNumMsgsRecv );
                  for ( i = 0; i < nNumMsgsRecv; i++ )
                  {
                     if (channel == 2) /* AR-579 */
                     {
                        if (bTimestampEnabled)
                        {
                           printf( "Status: 0x%08X ", RecvStatusWd[i] );
                           printf( "Data: 0x%08X ", RecvData[i] );
                           printf( "TimeStamp: 0x%08X\n", RecvTimeStamp[i] );
                        }
                        else
                        {
                           printf( "Data: 0x%08X\n", RecvData[i] );
                        }
                     }
                     else
                     {
                        printf( "Data: 0x%08X\n", RecvData[i] );
                     }
                  }
               }
   #if defined (__VXWORKS__)
               taskDelay(1);
   #endif
            }
         }
         else
            bContinue = FALSE;
      }
   }

   return bQuit;
}

Help Bot

X