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 Transmit

AR2 Transmit

Explanation

About the Sample Application Code

This sample C application demonstrates how to interact with North Atlantic Industries (NAI) embedded function modules, specifically focusing on transmitting ARINC messages using the NAI Board Support Package (SSK). The application is structured to provide an interface for configuring and transmitting ARINC messages via different modes (immediate and triggered). Below is a detailed explanation of the components and flow of the code:

Include Statements

#include <stdio.h>
#include <stdlib.h>
#include <string.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"

These include statements import standard libraries and NAI-specific headers required for accessing board functionality, user interaction, and ARINC operations.

Constants and Global Variables

static const int8_t *CONFIG_FILE = (int8_t *)"default_AR2Xmit.txt";
static int32_t AR_FIFO_Size = 1024;

These constants and global variables hold configuration file names and default buffer sizes for ARINC transmission.

Function Prototypes

void Run_AR2_Transmit(void);
static nai_status_t AR2_TxImmediate(int32_t paramCount, int32_t* p_params);
static nai_status_t AR2_TxTriggered(int32_t paramCount, int32_t* p_params);

Function prototypes are declared for the core functionalities to be defined later in the application.

Enumerations and Command Tables

enum arfuncgen_commands
{
   AR_FUNCGEN_CMD_TX_IMMEDIATE,
   AR_FUNCGEN_CMD_TX_TRIGGERED,
   AR_FUNCGEN_CMD_COUNT
};

static naiapp_cmdtbl_params_t AR_FuncGenMenuCmds[] =
{
   {"FIFO  ", "AR Transmit Immediate Mode ", AR_FUNCGEN_CMD_TX_IMMEDIATE, AR2_TxImmediate},
   {"TRIG  ", "AR Transmit Triggered Mode ", AR_FUNCGEN_CMD_TX_TRIGGERED, AR2_TxTriggered}
};

#define DEF_AR_CARD_INDEX  0
#define DEF_AR_MODULE      1
#define DEF_AR_XMIT_CHANNEL 1
#define DEF_AR_XMIT_DATA_COUNT 1

An enumeration and corresponding command tables are defined to list the available transmission commands (immediate and triggered). Constants for default values are also declared.

Main Function

#if defined (__VXWORKS__)
int32_t AR2_Transmit(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   ...
   return 0;
}

This is the entry point of the application. It is designed to be compatible with different environments (e.g., VxWorks or standard main for others). The function sets up a loop to query the user for configuration parameters and invokes the ARINC transmission routines.

AR2_TxImmediate Function

static nai_status_t AR2_TxImmediate(int32_t paramCount, int32_t* p_params)
{
   ...
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

This function handles immediate mode transmission. It configures the card, prepares and sends a specified number of data words in an immediate transmission mode.

AR2_TxTriggered Function

static nai_status_t AR2_TxTriggered(int32_t paramCount, int32_t* p_params)
{
   ...
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

This function handles triggered mode transmission. It configures the transmission to occur upon a specific trigger, ensuring the data is sent when the trigger signal is received.

Run_AR2_Transmit Function

void Run_AR2_Transmit(void)
{
   ...
}

This function initiates the ARINC transmission configuration process. It queries the user for parameters, displays menu commands, and calls the appropriate transmission functions based on user input.

Summary The provided C code is a sample application for configuring and transmitting ARINC messages using North Atlantic Industries' embedded function modules. It interacts with the NAI board support libraries to offer two transmission modes: immediate and triggered. The code covers user interaction for setting up the transmission and managing the data flow to the ARINC channels on the NAI hardware. Each function is well-defined for configuration, data handling, and user responsiveness.

#include <stdio.h>
#include <stdlib.h>
#include <string.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_AR2Xmit.txt";

/* Function prototypes */
void Run_AR2_Transmit(void);
static nai_status_t AR2_TxImmediate(int32_t paramCount, int32_t* p_params);
static nai_status_t AR2_TxTriggered(int32_t paramCount, int32_t* p_params);

/****** Command Table *******/
enum arfuncgen_commands
{
   AR_FUNCGEN_CMD_TX_IMMEDIATE,
   AR_FUNCGEN_CMD_TX_TRIGGERED,
   AR_FUNCGEN_CMD_COUNT
};

/****** Command Tables *******/
static naiapp_cmdtbl_params_t AR_FuncGenMenuCmds[] =
{
   {"FIFO  ", "AR Transmit Immediate Mode ", AR_FUNCGEN_CMD_TX_IMMEDIATE, AR2_TxImmediate},
   {"TRIG  ", "AR Transmit Triggered Mode ", AR_FUNCGEN_CMD_TX_TRIGGERED, AR2_TxTriggered}
};

#define DEF_AR_CARD_INDEX                 0
#define DEF_AR_MODULE                     1
#define DEF_AR_XMIT_CHANNEL               1
#define DEF_AR_XMIT_DATA_COUNT            1

/***** Global Variables *****/
static int32_t AR_FIFO_Size = 1024;

/**************************************************************************************************************/
/**
<summary>
The purpose of the AR_Transmit is to illustrate the methods to call in the naibrd library to configure
the ARINC channel to transmit ARINC messages in FIFO or scheduled mode.

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 1553 routines.
 - ClearDeviceCfg
 - QuerySystemCfg
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - SaveDeviceCfg

Note, the AR_Transmit application can run in conjunction with the AR_Receive, AR_ReceiveInterruptEther or
AR_ReceiveInterruptBus applications to illustrate ARINC transmit and receive operations together with the NAI ARINC module.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t AR2_Transmit(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   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)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  Run_AR2_Transmit();
               }
            }
         }

         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 AR2_TxImmediate(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   int32_t nNumWordsToSend = 1;
   int32_t nNumWordsSent;
   int32_t i, j;
   int32_t blockCnt, dataCnt, dataIndex;
   int32_t increment = 0x55555555;
   uint32_t SendData[1024];

   p_naiapp_AppParameters_t p_ar_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ar_params->cardIndex;
   int32_t module = p_ar_params->module;
   int32_t channel = p_ar_params->channel;

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

   /* Set Immediate FIFO Transmission mode */
   check_status(naibrd_AR_SetTxSendMode(cardIndex, module, channel, AR_TX_SENDMODE_IMMED));

   /* Enable transmitter */
   check_status(naibrd_AR_SetTxEnable(cardIndex, module, channel, AR_ENABLE));

   while (!bQuit)
   {
      /* Query for the number of data words to send */
      bQuit = GetARTransmitDataCount(DEF_AR_XMIT_DATA_COUNT, &nNumWordsToSend);
      if (!bQuit)
      {
         /* Break up the FIFO updates to blocks of AR_FIFOSize */
         blockCnt = nNumWordsToSend / AR_FIFO_Size;
         if (blockCnt * AR_FIFO_Size < nNumWordsToSend)
            blockCnt++;

         dataCnt = 0;
         for (i = 0; i < blockCnt; i++)
         {
            dataIndex = 0;
            do
            {
               SendData[dataIndex++] = (uint32_t)increment++; /* incremental data */
               dataCnt++;
            } while ((dataIndex < AR_FIFO_Size) && (dataCnt < nNumWordsToSend));

            printf("\nSending %d words ...\n", dataIndex);
            for (j = 0; j < dataIndex; j++)
               printf("Sent 0x%08X\n", SendData[j]);

            check_status(naibrd_AR_TransmitBuffer(cardIndex, module, channel, dataIndex, SendData, &nNumWordsSent)); /* send data */
            printf(" %d words sent. Total words sent = %d\n", nNumWordsSent, dataCnt);

            naibrd_Wait(1000000);  /* Delay is necessary to allow the FIFO buffer to empty before filling it up with more data */
         }
      }
   }

   /* Disable transmitter */
   check_status(naibrd_AR_SetTxEnable(cardIndex, module, channel, AR_DISABLE));

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t AR2_TxTriggered(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   int32_t nNumWordsToSend = 1;
   int32_t nNumWordsSent;
   int32_t i;
   int32_t dataCnt;
   int32_t increment = 0x55555555;
   uint32_t SendData[1024];
   nai_ar_status_t fifostatus;

   p_naiapp_AppParameters_t p_ar_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ar_params->cardIndex;
   int32_t module = p_ar_params->module;
   int32_t channel = p_ar_params->channel;

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

   /* Set Immediate FIFO Transmission mode */
   check_status(naibrd_AR_SetTxSendMode(cardIndex, module, channel, AR_TX_SENDMODE_TRGF));

   /* Enable transmitter */
   check_status(naibrd_AR_SetTxEnable(cardIndex, module, channel, AR_ENABLE));

   while (!bQuit)
   {
      /* Query for the number of data words to send */
      bQuit = GetARTransmitDataCount(DEF_AR_XMIT_DATA_COUNT, &nNumWordsToSend);
      if (!bQuit)
      {
         dataCnt = 0;

         /* Load Tx Buffer with nNumWordsToSend number of words or 1024 if nNumWordsToSend is greater than 1024 */
         if (nNumWordsToSend <= 1024)
         {
            for (i = 0; i < nNumWordsToSend; i++)
            {
               SendData[i] = (uint32_t)increment++; /* incremental data */
            }
            printf("\nLoading %d words ...\n", nNumWordsToSend);
            check_status(naibrd_AR_TransmitBuffer(cardIndex, module, channel, nNumWordsToSend, SendData, &nNumWordsSent)); /* load data */
            nNumWordsToSend = 0;
            dataCnt += nNumWordsSent;
         }
         else
         {
            for (i = 0; i < 1024; i++)
            {
               SendData[i] = (uint32_t)increment++; /* incremental data */
            }
            printf("\nLoading %d words ...\n", 1024);
            check_status(naibrd_AR_TransmitBuffer(cardIndex, module, channel, 1024, SendData, &nNumWordsSent)); /* load data */
            nNumWordsToSend -= 1024;
            dataCnt += nNumWordsSent;
         }

         nai_msDelay(1000);

         /* Trigger Tx */
         printf("\nSent Trigger Signal\n");
         check_status(naibrd_AR_SetTxSendTrigger(cardIndex, module, channel));

         while (nNumWordsToSend > 0)   /* If there are more words to send */
         {
            /* Wait for Tx Buffer to go below Almost Empty Threshold */
            do
            {
               check_status(naibrd_AR_GetTxFifoStatus(cardIndex, module, channel, NAI_AR_STATUS_REALTIME, &fifostatus));
            } while ((fifostatus & AR2_TX_FIFO_ALM_EMPTY) == 0);

            if (nNumWordsToSend > 800)
            {
               /* Load 800 more words */
               for (i = 0; i < 800; i++)
               {
                  SendData[i] = (uint32_t)increment++; /* incremental data */
               }
               printf("\nLoading %d more words ...\n", 800);
               check_status(naibrd_AR_TransmitBuffer(cardIndex, module, channel, 800, SendData, &nNumWordsSent)); /* load data */
               nNumWordsToSend -= 800;
               dataCnt += nNumWordsSent;
            }
            else
            {
               /* Load nNumWordsToSend more words */
               for (i = 0; i < nNumWordsToSend; i++)
               {
                  SendData[i] = (uint32_t)increment++; /* incremental data */
               }
               printf("\nLoading %d more words ...\n", nNumWordsToSend);
               check_status(naibrd_AR_TransmitBuffer(cardIndex, module, channel, nNumWordsToSend, SendData, &nNumWordsSent)); /* load data */
               nNumWordsToSend = 0;
               dataCnt += nNumWordsSent;
            }
         }

         /* Wait for Tx Buffer to go to Empty */
         do
         {
            check_status(naibrd_AR_GetTxFifoStatus(cardIndex, module, channel, NAI_AR_STATUS_REALTIME, &fifostatus));
         } while ((fifostatus & AR2_TX_FIFO_EMPTY) == 0);

         printf("Total words sent = %d\n", dataCnt);
      }
   }

   /* Disable transmitter */
   check_status(naibrd_AR_SetTxEnable(cardIndex, module, channel, AR_DISABLE));

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Run_AR2_Transmit queries the user for the card, module and channel to configure as the ARINC transmitter
as well as the data rate (high (100KHz) or low (12.5KHz)) and the type of message transmission (FIFO or scheduled).
Methods in the naibrd library are invoked to configure the ARINC channel.
Once the ARINC channel is configured and running, the user can:
1) In FIFO mode, enter the number of words to transmit. Note, the data sent is an incremental value.
2) In Scheduled mode, transmit an async ARINC data word.
</summary>
*/
/**************************************************************************************************************/
void Run_AR2_Transmit(void)
{
   int32_t cardIndex, module, archan;
   bool_t bQuit = FALSE;
   bool_t bContinue, bCmdFound;
   int32_t cmd;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   naiapp_AppParameters_t  ar_params;
   p_naiapp_AppParameters_t ar_receive_params = &ar_params;

   bQuit = GetARCfg(DEF_AR_CARD_INDEX, DEF_AR_MODULE, DEF_AR_XMIT_CHANNEL, &cardIndex, &module, &archan);
   ar_receive_params->cardIndex = cardIndex;
   ar_receive_params->module = module;
   ar_receive_params->channel = archan;

   if (!bQuit)
   {
      bContinue = TRUE;

      naiapp_utils_LoadParamMenuCommands(AR_FUNCGEN_CMD_COUNT, AR_FuncGenMenuCmds);
      while (bContinue)
      {
         /* 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 for Bounded Tx FIFO */
         check_status(naibrd_AR_SetTxFifoBounded(cardIndex, module, archan, AR_ENABLE));

         /* Set the Tx Fifo Almost Full Threshold to 800 and Almost Empty Threshold to 200 */
         check_status(naibrd_AR_SetTxFifoThresholds(cardIndex, module, archan, 200, 800));

         /* Set gap time */
         naibrd_AR_SetTxIntervalRate(cardIndex, module, archan, 6);

         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_TX_IMMEDIATE:
                     case AR_FUNCGEN_CMD_TX_TRIGGERED:
                        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;
}

Help Bot

X