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

M1553 RT Receive FIFO

M1553 RT Receive FIFO Sample Application (SSK 1.x)

Overview

The M1553 RT Receive FIFO sample application demonstrates how to configure a MIL-STD-1553 channel as a Remote Terminal (RT) with FIFO-based message retrieval using the NAI Software Support Kit (SSK 1.x). Unlike the stack-based approach used by the M1553_RT_Receive sample, FIFO mode stores messages in a dedicated hardware FIFO that supports bulk reads and provides full-status monitoring. This sample shows how to enable FIFO mode during initialization, read messages in bulk from the FIFO, decode them individually, and monitor FIFO full status.

The key FIFO message retrieval API calls demonstrated are:

  • naibrd_1553_ClearMsgFIFO() — clears the message FIFO before starting the RT.

  • naibrd_1553_GetMsgFIFOCount() — returns the number of words currently in the message FIFO.

  • naibrd_1553_ReadMsgFIFO() — reads a bulk block of FIFO data into a local buffer.

  • naibrd_1553_DecodeFIFOMsg() — decodes individual messages from the bulk FIFO data buffer.

  • naibrd_1553_GetMsgFIFOFullStatus() — checks whether the FIFO has reached capacity.

Note
FIFO mode is only available on modules FTA, FTB, FTC, FTD, and FTF. It is not supported on all FT-series modules. Consult your module’s manual to verify FIFO support before using this sample.

This sample supports the following 1553 module types (with FIFO capability):

  • 4-channel modules: FTA, FTB, FTC, FTD, FTF

  • Combination modules: CM1, CM5, and CM8 (where the 1553 function is an FTA-FTF variant)

For detailed register maps and module-specific behavior, refer to the FTA-FTF Manual.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a supported 1553 module that supports FIFO mode (FTA/FTB/FTC/FTD/FTF).

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

How to Run

Launch the M1553_RT_Receive_FIFO executable from your build output directory. On startup the application looks for a configuration file (default_1553_RTReceive_FIFO.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 walks you through RT-specific settings (channel, RT address, subaddress, address source, Rx buffer type) and then enters a timed monitoring loop that processes messages from the FIFO.

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 1553.

The main() function follows a standard SSK 1.x startup flow:

  1. Call naiapp_RunBoardMenu() to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_1553_RTReceive_FIFO.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear.

  2. Query the user for a card index with naiapp_query_CardIndex().

  3. Query for a module slot with naiapp_query_ModuleNumber().

  4. Retrieve the module ID with naibrd_GetModuleID() so downstream code can adapt to the specific 1553 variant installed.

  5. If a valid module is found, call Run_M1553_RT_Receive_FIFO() to begin RT configuration and FIFO-based message processing.

#if defined (__VXWORKS__)
int32_t M1553_RT_Receive_FIFO(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)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  Run_M1553_RT_Receive_FIFO(cardIndex, module, moduleID);
               }
            }
         }

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

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

   return 0;
}
Important

Common connection errors you may encounter at this stage:

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

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

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

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

Program Structure

Entry Point

The program entry point is main() on most platforms or M1553_RT_Receive_FIFO() on VxWorks. After the board connection and module selection described above, the application calls Run_M1553_RT_Receive_FIFO(), which handles all RT-specific configuration and FIFO-based message processing.

User Input Flow

Once inside Run_M1553_RT_Receive_FIFO(), the application collects RT operating parameters through the same utility functions used by other 1553 RT samples:

  1. Get1553RTCfg() — prompts for the 1553 channel number and RT address.

  2. Get1553Address() — prompts for the subaddress to legalize for Tx, Rx, and broadcast traffic. The default is subaddress 2.

  3. Get1553LogicalDevNum() — prompts for a logical device number (default: device 1).

  4. Get1553RTAddressSource() — asks whether to set the RT address in software or use the hardware address pins.

  5. Get1553RxBufferType() — prompts the user to select the Rx data block buffering mode (single, double, or circular).

Note
The menu system is a sample convenience — in your own code, call these API functions directly with the appropriate parameters.

FIFO Mode Initialization

The critical difference between this sample and the stack-based M1553_RT_Receive sample is the initialization mode flag. To enable FIFO mode, OR the NAI_1553_MESSAGE_FIFO_MODE flag with NAI_1553_MODE_RT when calling naibrd_1553_Initialize():

swResult = naibrd_1553_Initialize(DevNum, NAI_1553_ACCESS_CARD,
   NAI_1553_MODE_RT | NAI_1553_MESSAGE_FIFO_MODE, 0, 0, 0);

This tells the 1553 hardware to route incoming messages into the FIFO instead of (or in addition to) the RT command stack. Without this flag, the FIFO API calls (GetMsgFIFOCount, ReadMsgFIFO, DecodeFIFOMsg) will not function correctly.

Important
  • FIFO mode not supported — if your module does not support FIFO mode (e.g., FT0-FT9, FTE), naibrd_1553_Initialize() may return an error or the FIFO will remain empty. FIFO mode is only available on FTA, FTB, FTC, FTD, and FTF modules.

  • Initialization order — naibrd_1553_Initialize() must be called before any RT configuration APIs. Calling RT setup functions before initialization will fail.

RT Address Configuration

The RT address configuration in this sample is identical to the stack-based M1553_RT_Receive sample. The address can be set from software or hardware pins.

Software Addressing

To set the RT address in software, write RTAD_SW_EN and RT_ADR_LAT bits (value 0x0018) to auxiliary register 0x2, set the address source to internal, and program the address:

swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0018);
swResult = naibrd_1553_RtSetAddressSource(DevNum, NAI_1553_RT_ADDR_SOURCE_INTERNAL);
swResult = naibrd_1553_RtSetAddress(DevNum, rtaddr);

Hardware Pin Addressing

To use the hardware address pins, set only the RT_ADR_LAT bit (value 0x0008) and set the address source to external:

swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0008);
swResult = naibrd_1553_RtSetAddressSource(DevNum, NAI_1553_RT_ADDR_SOURCE_EXTERNAL);

For complete register bit definitions, refer to the FTA-FTF Manual.

Important
  • RT not responding — verify that the address and source mode match. A common mistake is configuring software addressing while the hardware is wired for pin addressing, or vice versa.

  • RT address conflict — two RTs with the same address on the same bus cause unpredictable behavior. Each RT on a bus must have a unique address (0-30).

Buffer Types and Data Block Configuration

This sample creates and maps data blocks for Rx, broadcast Rx, and Tx traffic on the configured subaddress, using the same pattern as the stack-based M1553_RT_Receive sample.

Rx and Broadcast Data Blocks

/* Create Rx data block and map to the desired subaddress */
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_RX, nDataBlockType, NULL, 0);
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_RX, sa,
   NAI_1553_RT_MESSAGE_TYPE_RX, NAI_1553_RT_DATABLOCK_IRQ_NONE, 1);

/* Create Broadcast Rx data block and map to the desired subaddress */
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_BCST, nDataBlockType, NULL, 0);
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_BCST, sa,
   NAI_1553_RT_MESSAGE_TYPE_BROADCAST, 0, 1);

Note that the FIFO sample uses NAI_1553_RT_DATABLOCK_IRQ_NONE as the IRQ parameter for the Rx mapping. This is appropriate when using FIFO-based retrieval since message notification comes through the FIFO count rather than through interrupts.

Tx Double-Buffering Pattern

The Tx configuration is identical to the stack-based sample — two single-type data blocks with explicit swapping:

swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX1, nDataBlockType, NULL, 0);
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX2, nDataBlockType, NULL, 0);
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_TX1, sa,
   NAI_1553_RT_MESSAGE_TYPE_TX, 0, 1);
currDataBlock = DATA_BLOCK_ID_TX1;
Important
  • Data block creation failure — verify that the block type is valid and the block ID has not already been allocated.

  • Subaddress mapping failure — the subaddress must be in the range 1-30 and the data block must already be created.

  • Tx data stale — after writing new data to the inactive Tx block, you must call naibrd_1553_RtTxDataBlockSwap() to make it active.

FIFO Message Processing Loop

The ProcessMessages() function is the core runtime loop, and it is where the FIFO approach differs significantly from the stack-based approach. Before entering the loop, the sample clears the FIFO to discard any stale data:

swResult = naibrd_1553_ClearMsgFIFO(DevNum);

Checking FIFO Count

Each iteration of the loop checks how many words are available in the FIFO:

swResult = naibrd_1553_GetMsgFIFOCount(DevNum, &fifoCount);

If fifoCount is greater than 0, messages are available for reading. If it is 0, no new messages have arrived.

Bulk FIFO Read

When messages are available, the sample reads the entire FIFO contents into a local buffer in a single bulk operation. Before reading, it zeroes the buffer to prevent stale data from being decoded:

memset(fifoData, 0, sizeof(fifoData));
swResult = naibrd_1553_ReadMsgFIFO(DevNum, fifoCount, fifoData);

The fifoData buffer is a uint32_t[1024] array. The fifoCount parameter tells the API how many words to read. This bulk approach is more efficient than reading one message at a time, especially when multiple messages have accumulated between polling intervals.

Iterative Message Decode

After the bulk read, the sample decodes messages one at a time from the buffer using naibrd_1553_DecodeFIFOMsg(). The function takes a current block index and returns the next block index, allowing the application to iterate through all messages in the buffer:

currBlockIndex = 0;
do
{
   swResult = naibrd_1553_DecodeFIFOMsg(fifoData, currBlockIndex, &nextBlockIndex, &msgStruct);
   if (swResult == 0)
   {
      /* Process decoded message */
   }
   else if (swResult != (uint32_t)NAI_1553_CMD_NO_MSG_TO_DECODE)
   {
      printf("Error: naibrd_1553_DecodeFIFOMsg  %d", swResult);
      return TRUE;
   }

   currBlockIndex = nextBlockIndex;  /* Advance to next message */
   nai_msDelay(1);

} while ((swResult == NAI_SUCCESS) && (time(NULL) < end));

The decoded message structure (naiDecodedMessageStructureFIFO) contains the same fields as the stack-based structure: block status, time tag, command word, data word count, and payload.

Note
Updating currBlockIndex = nextBlockIndex after each decode call is critical. Without this, the loop would decode the same message repeatedly.

FIFO Full Status Monitoring

After processing the batch of messages, the sample checks whether the FIFO has reached capacity:

swResult = naibrd_1553_GetMsgFIFOFullStatus(DevNum, NAI_1553_STATUS_REALTIME, &FIFIOfullStatusBit);
if (swResult == NAI_SUCCESS)
{
   printf("FIFO status: %d", FIFIOfullStatusBit);
   printf((FIFIOfullStatusBit == TRUE) ? " Full\r\n" : " Not full\r\n");
}

If the FIFO is full, new incoming messages may be lost. Monitor this status to detect overflow conditions. If the FIFO fills frequently, increase the polling rate or reduce the message rate on the bus.

Message Type Discrimination

The command word’s TR bit (bit 0x0400) distinguishes Rx from Tx messages, just as in the stack-based approach. For Rx messages, the decoded output includes the full data payload. For Tx messages, only the header fields are displayed.

Important
  • No messages appearing — verify that the RT has been started with naibrd_1553_RtStart(), the subaddress is legalized, and the BC is targeting this RT address and subaddress. Also verify that FIFO mode was enabled during initialization.

  • FIFO full / messages lost — the application is not reading the FIFO frequently enough. Increase the polling rate or reduce the BC message rate.

  • Stale data in FIFO buffer — always zero the local fifoData array with memset() before calling naibrd_1553_ReadMsgFIFO(). Old data left in the buffer can cause naibrd_1553_DecodeFIFOMsg() to decode stale messages.

  • Tx data not updating — naibrd_1553_RtTxDataBlockSwap() is not being called, or the application is writing to the wrong (active) block.

Troubleshooting Reference

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

Error / Symptom Possible Causes Suggested Resolution

No board found or connection timeout

Board not powered, missing configuration file, network issue

Verify hardware and configuration file. If file doesn’t exist, configure and save from board menu.

FIFO mode not working

Module does not support FIFO (FT0-FT9, FTE), or NAI_1553_MESSAGE_FIFO_MODE not passed to Initialize()

Verify module type supports FIFO (FTA/FTB/FTC/FTD/FTF). Check initialization flags.

Device open or initialization failure

Wrong card/module/channel, or device already in use

Verify parameters. Close other applications using this channel.

RT address mismatch

RT address doesn’t match what BC is targeting

Confirm address set via RtSetAddress() or hardware pins matches BC command word.

RT address source conflict

Software address set but hardware pin mode active, or vice versa

Match WriteAuxReg(0x2, …​) value to desired source: 0x0018 for software, 0x0008 for hardware pins.

No messages appearing

RT not started, subaddress not legalized, FIFO mode not enabled, or BC not sending to this RT/subaddress

Verify RtStart() was called, subaddress is legalized, FIFO mode enabled, and BC is targeting correct address.

FIFO full / message overflow

Application not reading FIFO fast enough

Increase polling rate, reduce bus message rate, or process messages more quickly.

Stale data decoded from FIFO

Local buffer not zeroed before ReadMsgFIFO()

Always memset(fifoData, 0, sizeof(fifoData)) before each bulk read.

Data block creation or mapping failure

Invalid block type, ID, or subaddress out of range

Verify block type constants and subaddress range (1-30 for data, 0/31 for mode codes).

Tx data stale from BC perspective

RtTxDataBlockSwap() not called after updating inactive block

Always swap after writing to the inactive block. Verify currDataBlock tracking is correct.

Rx data tearing

Wrong buffer type for message rate — single buffer under load

Switch to double-buffered (NAI_1553_RT_DATABLOCK_DOUBLE) or circular for higher rates.

Full Source

The complete source for this sample is provided below for reference. The sections above explain each part in detail.

Full Source — M1553_RT_Receive_FIFO.c (SSK 1.x)
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <time.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"

/* Common 1553 Sample Program include files */
#include "nai_1553_utils.h"

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_1553.h"
#include "functions/naibrd_1553_assisted.h"

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

/* Function prototypes */
static bool_t Run_M1553_RT_Receive_FIFO(int32_t cardIndex, int32_t module, uint32_t modid);
static int32_t UpdateTxDataBlock(uint16_t DevNum, uint8_t Subaddress);
static int32_t UpdateTxBuffer(uint16_t DevNum, uint16_t nDataBlkID);
static int32_t ProcessMessages(uint16_t DevNum, uint8_t Subaddress, int32_t duration);

static const uint16_t DATA_BLOCK_ID_TX1   = 1;
static const uint16_t DATA_BLOCK_ID_TX2   = 2;
static const uint16_t DATA_BLOCK_ID_RX	   = 3;
static const uint16_t DATA_BLOCK_ID_BCST  = 4;

static const int32_t DEF_RT_CHANNEL       = 1;
static const int16_t DEF_RT_DEV_NUM       = 1;
static const uint8_t DEF_RT_ADDRESS       = 1;
static const uint8_t DEF_RT_SUBADDR       = 2;
static const uint16_t DEF_RT_RX_BUF_TYPE  = NAI_1553_RT_DATABLOCK_DOUBLE;
static const uint16_t RTBC_WORDCNT        = 32;

/* Global Variables */
static int32_t currDataBlock;

/**************************************************************************************************************/
/**
<summary>
The purpose of the M1553_RT_Receive is to illustrate the methods to call in the naibrd library to configure
the 1553 channel as a Remote Terminal, legalize Subaddress 2 for Tx, Rx and Broadcast messages, and set it up to receive data
using double buffers and transmit data from two alternating Tx buffers (active and inactive). If a Rx message
is received, the received data and message information will be displayed via message FIFO.
If a Tx message is received, the data in the active Tx buffer will be sent to the bus. While the RT is running, Tx
buffer data will be updated periodically by incrementing all 32 data words of Tx data. If a Tx message
is received, the message information will be displayed via message FIFO.
This application demonstrates the usage of the following naibrd 1553 routines.
- naibrd_1553_GetChannelCount
- naibrd_1553_InternalLoopback
- naibrd_1553_Open
- naibrd_1553_Initialize
- naibrd_1553_WriteAuxReg
- naibrd_1553_RtSetAddress
- naibrd_1553_RtGetAddress
- naibrd_1553_RtSetAddressSource
- naibrd_1553_RtGetAddressSource
- naibrd_1553_RtDataBlockCreate
- naibrd_1553_RtDataBlockMapToSubaddress
- naibrd_1553_RtDataBlockWrite
- naibrd_1553_RtAddressRelatch
- naibrd_1553_RtStart
- naibrd_1553_RtStop
- naibrd_1553_RtTxDataBlockSwap
- naibrd_1553_RtMessageGetFromStackRaw
- naibrd_1553_RtMessageDecodeRaw
- naibrd_1553_Free

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.
- ConfigDevice
- DisplayDeviceCfg
- GetBoardSNModCfg
- CheckModule
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t M1553_RT_Receive_FIFO(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_M1553_RT_Receive_FIFO(cardIndex, module, moduleID);
               }
            }
         }

         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 bool_t Run_M1553_RT_Receive_FIFO(int32_t cardIndex, int32_t module, uint32_t modid)
{
   /* Variables */
   bool_t bQuit = FALSE;
   int32_t rtchan;
   uint8_t rtaddr;
   uint8_t sa = DEF_RT_SUBADDR;
   int16_t DevNum           = 0;
   int32_t swResult;
   uint16_t nDataBlockType = 0;
   bool_t bContinue = TRUE;
   int32_t duration;
   bool_t bSoftwareRTAddr;
   bool_t busAPassed, busBPassed;
   uint16_t usData;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* Get Card, Module, Channel Numbers and Open a Handle */
   bQuit = Get1553RTCfg(modid, DEF_RT_CHANNEL, DEF_RT_ADDRESS, &rtchan, &rtaddr);
   if (bQuit)
   {
      return bQuit;
   }

   printf("Enter Subaddress\n");
   bQuit = Get1553Address(31, DEF_RT_SUBADDR, &sa);

   /* Get Logical Device # */
   bQuit = Get1553LogicalDevNum(DEF_RT_DEV_NUM, &DevNum);
   if (bQuit)
   {
      return bQuit;
   }

   /* OPTIONAL: Loopback Test to verify hardware operation */
   swResult = naibrd_1553_InternalLoopback(cardIndex, module, rtchan, &busAPassed, &busBPassed);
   if (swResult == NAI_SUCCESS)
   {
      printf("Bus A Internal Loopback Test %s\n", busAPassed ? "PASSED" : "FAILED");
      printf("Bus B Internal Loopback Test %s\n", busBPassed ? "PASSED" : "FAILED");
   }

   /* Associate Card, Module and Channel Numbers with the Logical Device # */
   swResult = naibrd_1553_Open(cardIndex, module, rtchan, DevNum);
   if(swResult)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_Open  %d", swResult);
      return bQuit;
   }

   /* Initialize Device */
   swResult = naibrd_1553_Initialize(DevNum,NAI_1553_ACCESS_CARD,NAI_1553_MODE_RT | NAI_1553_MESSAGE_FIFO_MODE,0,0,0);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_Initialize  %d", swResult);
      return bQuit;
   }

   /* Get RT Address Source from user */
   bQuit = Get1553RTAddressSource(TRUE, &bSoftwareRTAddr);
   if (bQuit)
   {
      return bQuit;
   }

   if (bSoftwareRTAddr)
   {
      /* Set RTAD_SW_EN and RT_ADR_LAT in software */
      swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0018);
      swResult = naibrd_1553_RtSetAddressSource(DevNum, NAI_1553_RT_ADDR_SOURCE_INTERNAL);

      /* Set RT address */
      swResult = naibrd_1553_RtSetAddress(DevNum, rtaddr);
      if(swResult != 0)
      {
         bQuit = TRUE;
         printf("Error: naibrd_1553_RtSetAddress  %d", swResult);
         return bQuit;
      }
   }
   else
   {
      /* Unset RTAD_SW_EN and set RT_ADR_LAT in software */
      /* NOTE: If RT_ADR_LAT is not set, the device RT address will always reflect the state of the */
      /* RT address pins, even if the state changes while the RT is running. This behavior is */
      /* undesirable in most applications of 1553. */
      swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0008);
      swResult = naibrd_1553_RtSetAddressSource(DevNum, NAI_1553_RT_ADDR_SOURCE_EXTERNAL);
   }

   if (modid == NAI_MODULE_ID_FT8)
   {
      /* Simplex Enable (for internal NAI testing only, do not enable) */
      /*naibrd_1553_WriteAuxReg(DevNum, 0x3, 0x4000);
        naibrd_1553_WriteAuxReg(DevNum, 0xF, 0x1);*/
   }

   /* Select Single Buffer, Double Buffer or Circular Buffer for Rx Messages */
   bQuit = Get1553RxBufferType(DEF_RT_RX_BUF_TYPE, &nDataBlockType);
   if (bQuit)
   {
      return bQuit;
   }

   /* Get RT Address Source (External Pins or Internal via Software) */
   swResult = naibrd_1553_RtGetAddressSource(DevNum, &usData);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtGetAddressSource  %d", swResult);
      return bQuit;
   }

   printf("\nRT Address set %sly ", (usData == NAI_1553_RT_ADDR_SOURCE_INTERNAL) ? "internal" : "external");

   /* Read RT Address */
   swResult = naibrd_1553_RtGetAddress(DevNum, &usData);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtGetAddress  %d", swResult);
      return bQuit;
   }

   printf("to %d\n\n", usData);

   /* Create a Rx Buffer data block and map to the desired subaddress */
   swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_RX, nDataBlockType, NULL, 0);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockCreate  %d", swResult);
      return bQuit;
   }
   swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_RX, sa, NAI_1553_RT_MESSAGE_TYPE_RX, NAI_1553_RT_DATABLOCK_IRQ_NONE, 1);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockMapToSubaddress  %d", swResult);
      return bQuit;
   }

   /* Create a Broadcast Rx Buffer data block and map to the desired subaddress */
   swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_BCST, nDataBlockType, NULL, 0);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockCreate  %d", swResult);
      return bQuit;
   }
   swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_BCST, sa, NAI_1553_RT_MESSAGE_TYPE_BROADCAST, 0, 1);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockMapToSubaddress  %d", swResult);
      return bQuit;
   }

   /* Create two Tx Buffer data blocks and map the first to the desired subaddress */
   swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX1, nDataBlockType, NULL, 0);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockCreate  %d", swResult);
      return bQuit;
   }
   swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX2, nDataBlockType, NULL, 0);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockCreate  %d", swResult);
      return bQuit;
   }
   swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_TX1, sa, NAI_1553_RT_MESSAGE_TYPE_TX, 0, 1);
   if(swResult < 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockMapToSubaddress  %d", swResult);
      return bQuit;
   }

   currDataBlock = DATA_BLOCK_ID_TX1;

   while (bContinue)
   {
      /* If the RT address is being read from external pins, give the user the option to relatch the RT address before running the RT */
      if (!bSoftwareRTAddr)
      {
         printf("\nRelatch RT Address (Y or N)? ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (toupper(inputBuffer[0]) == 'Y')
            {
               naibrd_1553_RtAddressRelatch(DevNum);
            }
         }
      }

      /* Run the RT */
      printf("\nType duration (in seconds) to run RT 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 = (int)atol((const char*)inputBuffer);
         }

         swResult = naibrd_1553_ClearMsgFIFO(DevNum);
         if (swResult != 0)
         {
            bQuit = TRUE;
            printf("Error: naibrd_1553_ClearMsgFIFO  %d", swResult);
            return bQuit;
         }

         /* Start RT */
         swResult = naibrd_1553_RtStart(DevNum);
         if(swResult != 0)
         {
            bQuit = TRUE;
            printf("Error: naibrd_1553_RtStart  %d", swResult);
            return bQuit;
         }

         /* Process New Messages */
         ProcessMessages(DevNum, sa, duration);

         /* Stop RT */
         swResult = naibrd_1553_RtStop(DevNum);
         if(swResult != 0)
         {
            bQuit = TRUE;
            printf("Error: naibrd_1553_RtStop  %d", swResult);
            return bQuit;
         }
      }
      else
         bContinue = FALSE;
   }

   /* Free 1553 Device */
   swResult = naibrd_1553_Free(DevNum);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_Free  %d", swResult);
      return bQuit;
   }

   return bQuit;
}

static int32_t UpdateTxDataBlock(uint16_t DevNum, uint8_t Subaddress)
{
   /* Update Data in TX Data Block */
   if (currDataBlock == DATA_BLOCK_ID_TX1)
   {
      UpdateTxBuffer(DevNum, DATA_BLOCK_ID_TX2);

      /* Change data pointer to block 2 */
      naibrd_1553_RtTxDataBlockSwap(DevNum, DATA_BLOCK_ID_TX2, Subaddress);
      currDataBlock = DATA_BLOCK_ID_TX2;
   }
   else
   {
      UpdateTxBuffer(DevNum, DATA_BLOCK_ID_TX1);

      /* Change data pointer to block 1 */
      naibrd_1553_RtTxDataBlockSwap(DevNum, DATA_BLOCK_ID_TX1, Subaddress);
      currDataBlock = DATA_BLOCK_ID_TX1;
   }

   return 0;
}

static int ProcessMessages(uint16_t DevNum, uint8_t Subaddress, int32_t duration)
{
   time_t end, period;
   uint32_t swResult;
   int32_t i;
   uint32_t fifoCount;
   int32_t currBlockIndex = 0, nextBlockIndex = 0;
   naiDecodedMessageStructureFIFO msgStruct;
   uint32_t fifoData[1024];
   int32_t count = 0;
   bool_t FIFIOfullStatusBit;

   end = time(NULL) + duration;
   period = time(NULL) + 1;

   while (time(NULL) < end)
   {
      /* Update Tx Data Block periodically */
      if (time(NULL) > period)
      {
         UpdateTxDataBlock(DevNum, Subaddress);

         period = time(NULL) + 1;
      }

      swResult = naibrd_1553_GetMsgFIFOCount(DevNum, &fifoCount);
      if (swResult != 0)
      {
         printf("Error: naibrd_1553_GetMsgFIFOCount  %d", swResult);
         return TRUE;
      }
      else
      {
         if (fifoCount > 0)
         {
            currBlockIndex = 0;

            /* This is necessary because otherwise, fifoData array gets used over and over without getting zero'ed out. */
            /* When the array gets decoded, old data may get decoded unintentionally */
            memset(fifoData, 0, sizeof(fifoData));

            /* Read Message FIFO */
            swResult = naibrd_1553_ReadMsgFIFO(DevNum, fifoCount, fifoData);
            if (swResult != 0)
            {
               printf("Error: naibrd_1553_ReadMsgFIFO  %d", swResult);
               return TRUE;
            }
            else
            {
               /* Read Messages */
               do
               {
                  swResult = naibrd_1553_DecodeFIFOMsg(fifoData, currBlockIndex, &nextBlockIndex, &msgStruct);
                  if (swResult == 0)
                  {
                     if ((msgStruct.wCommandWord1 & 0x0400) != 0x0400)   /* If this is a Rx message */
                     {
                        printf("Rx Msg Received\n");
                        printf("\n\nDecoded Message:\n\n");
                        printf("Block Status - 0x%04X\n", msgStruct.wBlockStatus);
                        printf("Time Tag - 0x%04X\n", msgStruct.wTimeTag);
                        printf("Command Word - 0x%04X\n", msgStruct.wCommandWord1);
                        printf("Data Word Count - 0x%04X\n", msgStruct.wDataWordCount);

                        printf((msgStruct.wDataWordCount > 0) ? ("Data:") : (""));

                        for (i = 0; i < msgStruct.wDataWordCount; i++)
                        {
                           if (i % 8 == 0)
                           {
                              printf("\n");
                           }
                           printf("0x%04X ", msgStruct.waData[i]);
                        }
                        printf("count: %d\n", count++);
                        printf("\n\n");
                     }
                     else
                     {
                        printf("Tx Msg Received\n");
                        printf("\n\nDecoded Message:\n\n");
                        printf("Block Status - 0x%04X\n", msgStruct.wBlockStatus);
                        printf("Time Tag - 0x%04X\n", msgStruct.wTimeTag);
                        printf("Command Word - 0x%04X\n", msgStruct.wCommandWord1);
                        printf("Data Word Count - 0x%04X\n", msgStruct.wDataWordCount);
                        printf("count: %d\n", count++);
                        printf("\n\n");
                     }
                  }
                  else if(swResult != (uint32_t)NAI_1553_CMD_NO_MSG_TO_DECODE)
                  {
                     printf("Error: naibrd_1553_DecodeFIFOMsg  %d", swResult);
                     return TRUE;
                  }

                  /*** IMPORTANT !!! ***/
                  currBlockIndex = nextBlockIndex;

                  nai_msDelay(1);

               } while ((swResult == NAI_SUCCESS) && (time(NULL) < end));
            }

            swResult = naibrd_1553_GetMsgFIFOFullStatus(DevNum, NAI_1553_STATUS_REALTIME, &FIFIOfullStatusBit);
            if (swResult == NAI_SUCCESS)
            {
               printf("FIFO status: %d", FIFIOfullStatusBit);
               printf((FIFIOfullStatusBit == TRUE) ? " Full\r\n" : " Not full\r\n");
            }
            else
            {
               printf("Error: naibrd_1553_GetMsgFIFOFullStatus  %d", swResult);
               return TRUE;
            }
         }
      }
   }

   return 1;
}

static int32_t UpdateTxBuffer(uint16_t DevNum, uint16_t nDataBlkID)
{
   static uint16_t wBuffer[32] = { 0x0000 };
   uint16_t i = 0x0000;

   uint32_t swResult;

   /* Increment Tx buffer data */
   for (i = 0; i < 32; i++)
   {
      wBuffer[i] += 1;
   }

   /* Write new data to Tx buffer */
   swResult = naibrd_1553_RtDataBlockWrite(DevNum, nDataBlkID, wBuffer, RTBC_WORDCNT, 0);
   if (swResult < 0)
   {
      printf("Error: naibrd_1553_RtDataBlockWrite %d\n\n", swResult);
      return 0;
   }
   else
   {
      printf("New data written to Tx Buffer\n\n");
   }

   return 1;
}

Help Bot

X