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 Recv

M1553 RT Recv Sample Application (SSK 2.x)

Overview

The M1553 RT Recv sample application demonstrates how to configure a MIL-STD-1553 channel as a Remote Terminal (RT) and receive messages using the NAI Software Support Kit (SSK 2.x). Unlike a Bus Controller (BC), which initiates transfers on the bus, an RT passively waits for a BC to send commands before responding. This sample shows how to set up that passive responder role.

The application configures a channel as an RT, legalizes a user-selected subaddress for Tx, Rx, and Broadcast messages, and sets up double-buffered Rx data blocks and two alternating Tx data blocks (active/inactive). While the RT is running, the application periodically updates the Tx buffer data by incrementing all 32 words so that the BC sees changing data on each RT-to-BC request. When Rx messages arrive (BC-to-RT), the received data is decoded and displayed.

The key message retrieval API calls demonstrated are:

  • naibrd_1553_RtMsgGetFromStackRaw() — reads one raw message at a time from the RT command stack.

  • naibrd_1553_RtMsgDecodeRaw() — decodes the raw message into a structured format with block status, time tag, command word, and data payload.

  • naibrd_1553_RtDataBlkWrite() — writes data into an RT Tx data block.

  • naibrd_1553_RtTxDataBlkSwap() — atomically swaps the active and inactive Tx data blocks.

  • naibrd_1553_Free() — releases the 1553 device when the application exits.

For detailed 1553 protocol specifications, message formats, and hardware register descriptions, see the FTA-FTF Manual.

For the SSK 1.x version, see M1553 RT Receive (SSK 1.x).

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a 1553 module installed (FTA-FTF, FTJ-FTK).

  • SSK 2.x installed on your development host.

  • The sample applications built. Refer to the SSK 2.x Software Development Guide for platform-specific build instructions.

  • A Bus Controller on the same 1553 bus to send commands to this RT.

How to Run

Launch the m1553_rt_recv executable from your build output directory. On startup the application looks for a configuration file (default_1553_RTReceive.txt). This file does not ship with the SSK — it is created when you save your connection settings from the board menu. On the first run the board menu always appears. Once connected, the application prompts for RT channel, RT address, subaddress, logical device number, and RT address source (software or hardware). The user then enters a duration (in seconds) for the RT to run, during which it processes incoming messages and periodically updates Tx buffers.

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. For details on board connection configuration, see the First Time Setup Guide.

The main() function follows the standard SSK 2.x startup flow: board menu, card index query, module selection, and module ID retrieval. After confirming a valid module is present, it calls Run_M1553_RT_Receive().

#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t m1553_rt_recv(void)
#else
int32_t main(void)
#endif
{
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   bool_t  stop = NAI_FALSE;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == (bool_t)NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         /* Select Card Index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Select Module */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               if ((moduleID != 0))
               {
                  Run_M1553_RT_Receive(cardIndex, module, moduleID);
               }
            }
         }

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

   naiif_printf("\r\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

  • No board found — verify the board is powered and the connection is active.

  • Invalid card/module index — indices are 0-based for cards and 1-based for modules.

  • Module not present — confirm the 1553 module is physically installed in the expected slot.

Program Structure

Entry Point

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

User Input Flow

Once inside Run_M1553_RT_Receive(), the application collects RT operating parameters through a series of utility functions:

  1. Get1553RTCfg() — prompts for the 1553 channel number and RT address. It uses the module ID to determine valid channel ranges. The defaults are channel 1 and RT address 1.

  2. Get1553Address() — prompts for the subaddress to legalize for Tx, Rx, and broadcast traffic. Valid subaddresses are 1 through 31. The default is subaddress 2.

  3. Get1553LogicalDevNum() — prompts for a logical device number. The logical device number is a software handle that the naibrd library uses to associate a specific card/module/channel combination with subsequent API calls. The default is device 1.

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

Application Flow

The main loop asks the user for a duration, starts the RT with naibrd_1553_RtStart(), calls ProcessMessages() to poll for and display incoming messages, then stops the RT with naibrd_1553_RtStop(). This loop repeats until the user quits.

RT Initialization

The application opens the 1553 channel and initializes it in RT mode:

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

/* Initialize Device */
result = naibrd_1553_Init(DevNum, NAIBRD_1553_ACCESS_CARD, NAIBRD_1553_MODE_RT, 0, 0, 0);
  • naibrd_1553_Open() associates the card, module, and channel with a logical device number. All subsequent API calls use this device number.

  • naibrd_1553_Init() initializes the device in RT mode. NAIBRD_1553_ACCESS_CARD indicates direct hardware access. The three trailing zeros are reserved parameters unused for RT initialization.

RT Address Configuration

The RT address can be set from two sources: software control or hardware address pins. The application calls Get1553RTAddressSource() to let the user choose.

Software Addressing

When software addressing is selected, the application writes to the auxiliary registers to enable software RT address control:

if (bSoftwareRTAddr)
{
   /* Set RTAD_SW_EN and RT_ADR_LAT in software */
   result = naibrd_1553_WriteAuxRegister(DevNum, NAIBRD_1553_AUX_ADDRESS_MISC_BITS, 0x0018);

   if(IsFTx1553(modid)) /* For non-1760 modules only */
      result = naibrd_1553_RtSetAddrSrc(DevNum, NAIBRD_1553_RT_ADDR_SOURCE_INTERNAL);

   /* Set RT address */
   result = naibrd_1553_RtSetAddr(DevNum, rtaddr);
}

The value 0x0018 sets both the RTAD_SW_EN and RT_ADR_LAT bits in auxiliary register NAIBRD_1553_AUX_ADDRESS_MISC_BITS. naibrd_1553_RtSetAddrSrc() selects internal addressing on FTx (non-1760) modules, and naibrd_1553_RtSetAddr() programs the desired address.

Hardware Pin Addressing

When hardware addressing is selected, the application reads the RT address from the module’s external address pins:

else
{
   if(IsFTx1553(modid))
   {
      /* Unset RTAD_SW_EN and set RT_ADR_LAT in software */
      result = naibrd_1553_WriteAuxRegister(DevNum, NAIBRD_1553_AUX_ADDRESS_MISC_BITS, 0x0008);

      result = naibrd_1553_RtSetAddrSrc(DevNum, NAIBRD_1553_RT_ADDR_SOURCE_EXTERNAL);
   }
}

The value 0x0008 sets only the RT_ADR_LAT bit (without RTAD_SW_EN), so the RT address is read from the hardware pins. naibrd_1553_RtSetAddrSrc() with NAIBRD_1553_RT_ADDR_SOURCE_EXTERNAL tells the module to use the external pin value.

Hardware pin addressing is required in some MIL-STD-1760 installations where the platform wiring determines the RT address.

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). Address 31 is reserved for broadcast.

Data Block Configuration

The sample creates four data blocks to handle Rx, broadcast, and Tx traffic on the configured subaddress.

Data Block IDs

Constant ID Description

DATA_BLOCK_ID_TX1

1

First Tx data block (single, 32 words). Used for ping-pong buffering.

DATA_BLOCK_ID_TX2

2

Second Tx data block (single, 32 words). Used for ping-pong buffering.

DATA_BLOCK_ID_RX

3

Rx data block (double-buffered). Receives BC-to-RT messages.

DATA_BLOCK_ID_BCST

4

Broadcast Rx data block (double-buffered). Receives broadcast messages.

Rx Data Block Creation and Mapping

The application creates a double-buffered Rx data block and maps it to the user-selected subaddress:

/* Create a Rx Buffer data block and map to the desired subaddress */
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_RX, NAIBRD_1553_RT_DATABLOCK_DOUBLE, NULL, 0);
result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_RX, sa, NAIBRD_1553_RT_MESSAGE_TYPE_RX,
   NAIBRD_1553_RT_DATABLOCK_IRQ_NONE, 1);

naibrd_1553_RtDataBlkCreate() allocates the data block on the module. NAIBRD_1553_RT_DATABLOCK_DOUBLE creates a double-buffered block — the hardware maintains two buffers (A and B) and automatically swaps between them on each message, preventing data tearing. The NULL and 0 arguments are for an optional user-supplied buffer pointer and size (not used here).

naibrd_1553_RtDataBlkMapToSA() binds the block to a subaddress. The final argument (1) is the legalization flag — setting it to 1 legalizes the subaddress so the RT will respond to BC commands targeting it.

The same pattern is used for the broadcast Rx block:

/* Create a Broadcast Rx Buffer data block and map to the desired subaddress */
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_BCST, NAIBRD_1553_RT_DATABLOCK_DOUBLE, NULL, 0);
result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_BCST, sa, NAIBRD_1553_RT_MESSAGE_TYPE_BROADCAST,
   NAIBRD_1553_RT_DATABLOCK_IRQ_NONE, 1);

Tx Double-Buffering Pattern

For transmit, the sample creates two single-type data blocks and maps the first one as the active Tx block:

/* Create two Tx Buffer data blocks and map the first to the desired subaddress */
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_TX1, NAIBRD_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_TX2, NAIBRD_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_TX1, sa, NAIBRD_1553_RT_MESSAGE_TYPE_TX,
   NAIBRD_1553_RT_DATABLOCK_IRQ_NONE, 1);
currDataBlock = DATA_BLOCK_ID_TX1;

TX1 is mapped as the active block and currDataBlock tracks which block the BC is currently reading from. The application writes new data into the inactive block, then swaps. This ensures the BC always reads a complete, consistent data set.

Note
Rx double-buffering is handled automatically by the hardware when you create a single DOUBLE-type block. Tx double-buffering is done explicitly in software using two SINGLE-type blocks and the naibrd_1553_RtTxDataBlkSwap() API.
Important
  • Data block creation failure — verify that the block type is valid and that 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 before mapping.

  • Subaddress not legalized — set the legalization flag to 1 in naibrd_1553_RtDataBlkMapToSA(). Without legalization, the RT will not respond to BC commands targeting that subaddress.

Processing Messages

The ProcessMessages() function is the core runtime loop. It runs for a user-specified duration (default 5 seconds), polling the RT command stack every 10 ms for new messages. On each iteration it reads raw messages from the stack, decodes them, and periodically updates the Tx data block contents.

Stack-Based Message Retrieval

Each iteration calls naibrd_1553_RtMsgGetFromStackRaw() to read one raw message from the RT command stack:

result = naibrd_1553_RtMsgGetFromStackRaw(DevNum, wsBuffer, NAIBRD_1553_MAX_MESSAGE_SIZE_RT);
if (result < 0)
{
   naiif_printf("Error: naibrd_1553_RtMessageGetFromStackRaw %d\r\n\r\n", result);
   return 0;
}
else if (result > 0)
{
   /* Decode Raw Message */
   result = naibrd_1553_RtMsgDecodeRaw(DevNum, wsBuffer, &DecodedMsgStruct);
}

The return value conventions are:

  • Less than 0 — an error occurred.

  • 0 — no new messages are available.

  • Greater than 0 — a message was retrieved (value is the message size).

The stack is a hardware-managed FIFO. If it fills before the application reads messages out, older messages are lost. Call the retrieval function frequently enough to keep up with the incoming message rate.

Message Type Discrimination

The command word’s TR (transmit/receive) bit — bit 10 (mask 0x0400) — determines the direction of the transfer:

if ((DecodedMsgStruct.commandWord1 & 0x0400) != 0x0400)   /* If this is a Rx message */
{
   naiif_printf("Rx Msg Received\r\n");
   naiif_printf("\r\n\r\nDecoded Message:\r\n\r\n");
   naiif_printf("Block Status - 0x%04X\r\n", DecodedMsgStruct.blockStatus);
   naiif_printf("Time Tag - 0x%04X\r\n", DecodedMsgStruct.timeTag);
   naiif_printf("Command Word - 0x%04X\r\n", DecodedMsgStruct.commandWord1);
   naiif_printf("Data Word Count - 0x%04X\r\n", DecodedMsgStruct.dataWordCount);
   naiif_printf("Data:");
   for (i = 0; i < DecodedMsgStruct.dataWordCount; i++)
   {
      if (i % 8 == 0)
      {
         naiif_printf("\r\n");
      }
      naiif_printf("0x%04X ", DecodedMsgStruct.data[i]);
   }
   naiif_printf("count: %d\r\n", count++);
   naiif_printf("\r\n\r\n");
}
else
{
   naiif_printf("Tx Msg Received\r\n");
   naiif_printf("\r\n\r\nDecoded Message:\r\n\r\n");
   naiif_printf("Block Status - 0x%04X\r\n", DecodedMsgStruct.blockStatus);
   naiif_printf("Time Tag - 0x%04X\r\n", DecodedMsgStruct.timeTag);
   naiif_printf("Command Word - 0x%04X\r\n", DecodedMsgStruct.commandWord1);
   naiif_printf("Data Word Count - 0x%04X\r\n", DecodedMsgStruct.dataWordCount);
   naiif_printf("count: %d\r\n", count++);
   naiif_printf("\r\n\r\n");
}
  • When the TR bit is clear (0), this is an Rx message — the BC sent data to the RT. The application prints the full decoded message including the data payload.

  • When the TR bit is set (1), this is a Tx message — the BC requested data from the RT. The application prints the header fields but omits the data words since the data was written by the RT itself.

Decoded Message Fields

Each decoded message (naibrd_1553_msgstruct_t) contains:

Field Description

blockStatus

Hardware-generated status flags for the message transfer. Indicates error conditions, bus selection (A or B), and message type.

timeTag

Hardware timestamp marking when the transaction was received. Resolution depends on module configuration.

commandWord1

The 1553 command word containing the RT address (bits 15-11), TR bit (bit 10), subaddress (bits 9-5), and word count (bits 4-0).

dataWordCount

Number of data words in the message payload (0 to 32).

data[]

The actual data words. Displayed for Rx messages only. Up to 32 16-bit words.

Tx Buffer Updates

Every 1 second during the monitoring loop, UpdateTxDataBlock() refreshes the Tx data by writing to the inactive buffer and swapping it with the active buffer.

UpdateTxDataBlock()

This function determines which data block is currently inactive and calls UpdateTxBuffer() to write new data, then calls naibrd_1553_RtTxDataBlkSwap() to atomically make the updated block active:

static int32_t UpdateTxDataBlock(uint16_t DevNum, naibrd_1553_rt_subaddress_t Subaddress)
{
   if (currDataBlock == DATA_BLOCK_ID_TX1)
   {
      UpdateTxBuffer(DevNum, DATA_BLOCK_ID_TX2);
      naibrd_1553_RtTxDataBlkSwap(DevNum, DATA_BLOCK_ID_TX2, Subaddress);
      currDataBlock = DATA_BLOCK_ID_TX2;
   }
   else
   {
      UpdateTxBuffer(DevNum, DATA_BLOCK_ID_TX1);
      naibrd_1553_RtTxDataBlkSwap(DevNum, DATA_BLOCK_ID_TX1, Subaddress);
      currDataBlock = DATA_BLOCK_ID_TX1;
   }

   return 0;
}

The swap is atomic from the BC’s perspective — the BC always reads from a complete, consistent buffer.

UpdateTxBuffer() and naibrd_1553_RtDataBlkWrite()

UpdateTxBuffer() increments a static 32-word array and writes it to the specified data block:

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

   uint32_t result;

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

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

   return 1;
}

naibrd_1553_RtDataBlkWrite() writes RTBC_WORDCNT (32) words from wBuffer into the specified data block starting at offset 0. This is how the RT populates data that the BC will read on the next RT-to-BC transfer. The static wBuffer array persists between calls, so each update increments the values from the previous write, giving the BC visibly changing data.

Important
  • Tx data stale — after writing new data to the inactive Tx block, you must call naibrd_1553_RtTxDataBlkSwap() to make it active. Forgetting the swap means the BC continues reading the old block.

  • Write failure — verify the block ID exists and was created with naibrd_1553_RtDataBlkCreate() before writing.

Device Cleanup

When the user quits the application, the 1553 device must be released by calling naibrd_1553_Free():

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

naibrd_1553_Free() releases all resources associated with the logical device number, including data blocks and stack buffers. Always call this function when you are done with the 1553 channel to avoid resource leaks. After calling naibrd_1553_Free(), the device number is invalid and must not be used in subsequent API calls without re-opening.

Troubleshooting Reference

Error / Symptom Possible Causes Suggested Resolution

naibrd_1553_Open returns non-zero

Channel already open, invalid indices

Verify indices, ensure no other application holds the channel.

naibrd_1553_Init returns non-zero

Device not opened, wrong mode

Ensure naibrd_1553_Open() succeeded before calling Init().

RT does not respond to BC

Wrong RT address, subaddress not legalized, bus wiring issue

Verify RT address matches BC target, check subaddress mapping and legalization flag.

No Rx messages displayed

BC not sending to correct subaddress, address source mismatch

Verify BC is targeting the correct RT address and subaddress.

RT address source error

Software address not set, external pins not wired

Use software RT address for bench testing.

Tx data not updating

Ping-pong swap not happening, duration too short

Ensure duration is at least 2 seconds for periodic updates.

Stack overflow / lost messages

Application not reading from stack frequently enough

Increase polling rate or reduce BC message rate.

Data block creation or mapping failure

Invalid block type, duplicate ID, or subaddress out of range

Verify block type constants and subaddress range (1-30).

naibrd_1553_Free returns non-zero

Device not opened or already freed

Ensure each Open() is paired with exactly one Free().

Full Source

Full Source — m1553_rt_recv.c (SSK 2.x)
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"

/* naibrd include files */
#include "nai_libs/naibrd/include/naibrd.h"
#include "nai_libs/naibrd/include/functions/naibrd_1553.h"

/* naiif include files */
#include "nai_libs/naiif/include/naiif.h"
#include "nai_libs/naiif/include/naiif_stdio.h"


/* Common Sample Program include files */
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_menu.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_query.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_access.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_display.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_utils.h"

/* Common 1553 Sample Program include files */
#include "nai_sample_apps/naiapp_src/board_modules/1553/m1553_common_utils/m1553_common_utils.h"

static const int8_t *DEF_CONFIG_FILE = (int8_t *)"default_1553_RTReceive.txt";

/* Function prototypes */
static bool_t Run_M1553_RT_Receive(int32_t cardIndex, int32_t module, uint32_t modid);
static int32_t UpdateTxDataBlock(uint16_t DevNum, naibrd_1553_rt_subaddress_t Subaddress);
static int32_t UpdateTxBuffer(uint16_t DevNum, uint16_t nDataBlkID);
static int32_t ProcessMessages(uint16_t DevNum, naibrd_1553_rt_subaddress_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 uint16_t DEF_RT_ADDRESS                             = 1;
static const uint16_t DEF_RT_SUBADDR                             = 2;
static const uint16_t RTBC_WORDCNT                                = 32;

/* Global Variables */
static int32_t currDataBlock;

/**************************************************************************************************************/
/** \defgroup M1553_RT_Receive

\brief This sample application demonstrates how to configure a channel as a Remote Terminal and receive messages.

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 will be displayed.
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.

The main steps include:
- Querying the user for the card index and module number.
- Configuring the channel for Remote Terminal functionality.
- Starting the RT to start receiving messages.
- Displaying any messages received by the RT, while periodically updating the TX buffer.
*/
/**************************************************************************************************************/
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t m1553_rt_recv(void)
#else
int32_t main(void)
#endif
{
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   bool_t  stop = NAI_FALSE;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == (bool_t)NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         /* Select Card Index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Select Module */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               if ((moduleID != 0))
               {
                  Run_M1553_RT_Receive(cardIndex, module, moduleID);
               }
            }
         }

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

   naiif_printf("\r\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(int32_t cardIndex, int32_t module, uint32_t modid)
{
   /* Variables */
   bool_t bQuit = NAI_FALSE;
   int32_t rtchan;
   naibrd_1553_rt_address_t rtaddr;
   naibrd_1553_rt_subaddress_t sa = DEF_RT_SUBADDR;
   uint16_t DevNum           = 0;
   int32_t result;
   bool_t bContinue = NAI_TRUE;
   int32_t duration;
   bool_t bSoftwareRTAddr;
   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;
   }

   naiif_printf("Enter Subaddress\r\n");
   bQuit = Get1553Address(NAIBRD_1553_RT_SA_31_MODECODE, DEF_RT_SUBADDR, &sa);

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

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

   /* Initialize Device */

   result = naibrd_1553_Init(DevNum, NAIBRD_1553_ACCESS_CARD, NAIBRD_1553_MODE_RT, 0, 0, 0);
   if (result != 0)
   {
      bQuit = NAI_TRUE;
      naiif_printf("Error: naibrd_1553_Init  %d", result);
      return bQuit;
   }

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

   if (bSoftwareRTAddr)
   {
      /* Set RTAD_SW_EN and RT_ADR_LAT in software */
      result = naibrd_1553_WriteAuxRegister(DevNum, NAIBRD_1553_AUX_ADDRESS_MISC_BITS, 0x0018);

      if(IsFTx1553(modid)) /* For non-1760 modules only */
         result = naibrd_1553_RtSetAddrSrc(DevNum, NAIBRD_1553_RT_ADDR_SOURCE_INTERNAL);

      /* Set RT address */
      result = naibrd_1553_RtSetAddr(DevNum, rtaddr);
      if (result != 0)
      {
         bQuit = NAI_TRUE;
         naiif_printf("Error: naibrd_1553_RtSetAddr  %d", result);
         return bQuit;
      }
   }
   else
   {
      if(IsFTx1553(modid))
      {
         /* Unset RTAD_SW_EN and set RT_ADR_LAT in software */
         result = naibrd_1553_WriteAuxRegister(DevNum, NAIBRD_1553_AUX_ADDRESS_MISC_BITS, 0x0008);

         result = naibrd_1553_RtSetAddrSrc(DevNum, NAIBRD_1553_RT_ADDR_SOURCE_EXTERNAL);
      }
   }

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

   /* Create a Rx Buffer data block and map to the desired subaddress */
   result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_RX, NAIBRD_1553_RT_DATABLOCK_DOUBLE, NULL, 0);
   if (result != 0)
   {
      bQuit = NAI_TRUE;
      naiif_printf("Error: naibrd_1553_RtDatBlkCreate  %d", result);
      return bQuit;
   }
   result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_RX, sa, NAIBRD_1553_RT_MESSAGE_TYPE_RX,
      NAIBRD_1553_RT_DATABLOCK_IRQ_NONE, 1);
   if (result != 0)
   {
      bQuit = NAI_TRUE;
      naiif_printf("Error: naibrd_1553_RtDatBlkMapToSA  %d", result);
      return bQuit;
   }

   /* Create a Broadcast Rx Buffer data block and map to the desired subaddress */
   result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_BCST, NAIBRD_1553_RT_DATABLOCK_DOUBLE, NULL, 0);
   if (result != 0)
   {
      bQuit = NAI_TRUE;
      naiif_printf("Error: naibrd_1553_RtDatBlkCreate  %d", result);
      return bQuit;
   }
   result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_BCST, sa, NAIBRD_1553_RT_MESSAGE_TYPE_BROADCAST,
      NAIBRD_1553_RT_DATABLOCK_IRQ_NONE, 1);
   if (result != 0)
   {
      bQuit = NAI_TRUE;
      naiif_printf("Error: naibrd_1553_RtDatBlkMapToSA  %d", result);
      return bQuit;
   }

   /* Create two Tx Buffer data blocks and map the first to the desired subaddress */
   result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_TX1, NAIBRD_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
   if (result != 0)
   {
      bQuit = NAI_TRUE;
      naiif_printf("Error: naibrd_1553_RtDatBlkCreate  %d", result);
      return bQuit;
   }
   result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_TX2, NAIBRD_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
   if (result != 0)
   {
      bQuit = NAI_TRUE;
      naiif_printf("Error: naibrd_1553_RtDatBlkCreate  %d", result);
      return bQuit;
   }
   result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_TX1, sa, NAIBRD_1553_RT_MESSAGE_TYPE_TX,
      NAIBRD_1553_RT_DATABLOCK_IRQ_NONE, 1);
   if (result < 0)
   {
      bQuit = NAI_TRUE;
      naiif_printf("Error: naibrd_1553_RtDatBlkMapToSA  %d", result);
      return bQuit;
   }
   currDataBlock = DATA_BLOCK_ID_TX1;

   while (bContinue)
   {
      naiif_printf("\r\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);
         }

         /* Start RT */
         result = naibrd_1553_RtStart(DevNum);
         if (result != 0)
         {
            bQuit = NAI_TRUE;
            naiif_printf("Error: naibrd_1553_RtStart  %d", result);
            return bQuit;
         }

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

         /* Stop RT */
         result = naibrd_1553_RtStop(DevNum);
         if (result != 0)
         {
            bQuit = NAI_TRUE;
            naiif_printf("Error: naibrd_1553_RtStop  %d", result);
            return bQuit;
         }
      }
      else
         bContinue = NAI_FALSE;
   }

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

   return bQuit;
}

static int32_t UpdateTxDataBlock(uint16_t DevNum, naibrd_1553_rt_subaddress_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_RtTxDataBlkSwap(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_RtTxDataBlkSwap(DevNum, DATA_BLOCK_ID_TX1, Subaddress);
      currDataBlock = DATA_BLOCK_ID_TX1;
   }

   return 0;
}

static int32_t ProcessMessages(uint16_t DevNum, naibrd_1553_rt_subaddress_t Subaddress, int32_t duration)
{
   int32_t counter_mS = 0, end_mS = 0, period_mS = 0;
   int32_t result;
   int32_t i;
   naibrd_1553_msgstruct_t DecodedMsgStruct;
   uint16_t wsBuffer[72] = { 0x0000 };
   int32_t count = 0;

   end_mS = counter_mS + duration*1000;
   period_mS = counter_mS + 1000;

   while (counter_mS < end_mS)
   {
      /* Update Tx Data Block periodically */
      if (counter_mS > period_mS)
      {
         UpdateTxDataBlock(DevNum, Subaddress);

         period_mS = counter_mS + 1000;
      }

      /* If the stack pointer has updated (new data arrived), read one message at a time */
      result = naibrd_1553_RtMsgGetFromStackRaw(DevNum, wsBuffer, NAIBRD_1553_MAX_MESSAGE_SIZE_RT);
      if (result < 0)
      {
         naiif_printf("Error: naibrd_1553_RtMessageGetFromStackRaw %d\r\n\r\n", result);
         return 0;
      }
      else if (result > 0)
      {
         /* Decode Raw Message */
         result = naibrd_1553_RtMsgDecodeRaw(DevNum, wsBuffer, &DecodedMsgStruct);
         if (result < 0)
         {
            naiif_printf("Error: naibrd_1553_RtMessageDecodeRaw %d\r\n\r\n", result);
            return 0;
         }

         if ((DecodedMsgStruct.commandWord1 & 0x0400) != 0x0400)   /* If this is a Rx message */
         {
            naiif_printf("Rx Msg Received\r\n");
            naiif_printf("\r\n\r\nDecoded Message:\r\n\r\n");
            naiif_printf("Block Status - 0x%04X\r\n", DecodedMsgStruct.blockStatus);
            naiif_printf("Time Tag - 0x%04X\r\n", DecodedMsgStruct.timeTag);
            naiif_printf("Command Word - 0x%04X\r\n", DecodedMsgStruct.commandWord1);
            naiif_printf("Data Word Count - 0x%04X\r\n", DecodedMsgStruct.dataWordCount);
            naiif_printf("Data:");
            for (i = 0; i < DecodedMsgStruct.dataWordCount; i++)
            {
               if (i % 8 == 0)
               {
                  naiif_printf("\r\n");
               }
               naiif_printf("0x%04X ", DecodedMsgStruct.data[i]);
            }
            naiif_printf("count: %d\r\n", count++);
            naiif_printf("\r\n\r\n");
         }
         else
         {
            naiif_printf("Tx Msg Received\r\n");
            naiif_printf("\r\n\r\nDecoded Message:\r\n\r\n");
            naiif_printf("Block Status - 0x%04X\r\n", DecodedMsgStruct.blockStatus);
            naiif_printf("Time Tag - 0x%04X\r\n", DecodedMsgStruct.timeTag);
            naiif_printf("Command Word - 0x%04X\r\n", DecodedMsgStruct.commandWord1);
            naiif_printf("Data Word Count - 0x%04X\r\n", DecodedMsgStruct.dataWordCount);
            naiif_printf("count: %d\r\n", count++);
            naiif_printf("\r\n\r\n");
         }
      }
      naibrd_msDelay(10);
      counter_mS += 10;
   }

   return 1;
}

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

   uint32_t result;

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

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

   return 1;
}

Help Bot

X