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 RTMT Receive

M1553 RTMT Receive Sample Application (SSK 1.x)

Overview

The M1553 RTMT Receive sample application demonstrates how to operate a MIL-STD-1553 channel in combined Remote Terminal and Monitor Terminal (RT+MT) mode using the NAI Software Support Kit (SSK 1.x). In this dual-role configuration, a single channel simultaneously acts as an RT — responding to BC commands on a specific address — and as an MT — passively capturing all bus traffic. This is useful when you need your terminal to participate in bus transactions while also logging what other terminals are doing.

The sample legalizes a user-specified subaddress for Tx, Rx, and Broadcast messages on the RT side, sets up double-buffered Tx data with active/inactive buffer swapping via naibrd_1553_RtTxDataBlockSwap(), and configures the MT side with selective message filtering using naibrd_1553_MtMessageMonitoringDisable(). During operation, both the RT and MT stacks are polled independently, and received messages from each role are decoded and displayed separately.

This sample supports the following 1553 module types:

  • FT0 through FTF — 4-channel 1553 modules

  • FTJ / FTK — 2-channel MIL-STD-1760 modules

  • CM1, CM5, CM8 — combination modules with 1553 functionality

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

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a supported 1553 module installed.

  • 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_RTMT_Receive executable from your build output directory. On startup the application looks for a configuration file (default_1553_RTMTReceive.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+MT-specific settings (channel, RT address, subaddress, Rx buffer type) and then enters a timed monitoring loop that processes messages from both the RT and MT stacks.

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_RTMTReceive.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_RTMT_Receive() to begin RT+MT configuration and message processing.

#if defined (__VXWORKS__)
int32_t M1553_RTMT_Receive(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_RTMT_Receive(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

The entry point is main() on most platforms, or M1553_RTMT_Receive() on VxWorks. Both resolve to the same logic.

User Input Sequence

After the board connection is established, Run_M1553_RTMT_Receive() collects the remaining configuration through a series of prompts:

  1. RT channel and address — Get1553RTCfg() asks for the 1553 channel and the 5-bit RT address (0-31).

  2. Subaddress — Get1553Address() asks for the subaddress to legalize for Tx, Rx, and Broadcast messages (default: 2).

  3. Logical device number — Get1553LogicalDevNum() assigns a logical device handle used by all subsequent naibrd API calls (default: 1).

  4. RT address source — Get1553RTAddressSource() asks whether to set the RT address via software or read it from external hardware pins.

  5. Rx buffer type — Get1553RxBufferType() selects single, double, or circular buffering for incoming Rx messages (default: double buffer).

  6. Monitoring duration — the application prompts for how many seconds to run (default: 5 seconds). You can run multiple cycles without restarting.

Timed Monitoring Loop

Once configuration is complete, the application enters a loop that repeats until the user quits:

  1. Optionally relatch the RT address (if using external pins and not on FTK modules).

  2. Prompt for a duration in seconds.

  3. Call naibrd_1553_RtMtStart() to begin combined RT+MT operation.

  4. Run ProcessMessages() for the specified duration, polling both the RT and MT stacks.

  5. Call naibrd_1553_RtMtStop() to halt both roles.

  6. Prompt again — enter a new duration to continue, or press Q to exit.

Device Initialization and RT Address Configuration

The combined RT+MT mode requires initialization with NAI_1553_MODE_RTANDMT, which enables both terminal roles on the same channel simultaneously.

Opening and Initializing the Device

To set up the combined mode, open the device and initialize it with the RT+MT mode flag:

swResult = naibrd_1553_Open(cardIndex, module, rtmtchan, DevNum);

swResult = naibrd_1553_Initialize(DevNum, NAI_1553_ACCESS_CARD, NAI_1553_MODE_RTANDMT, 0, 0, 0);

The NAI_1553_MODE_RTANDMT flag tells the hardware to operate as both an RT (responding to BC commands) and an MT (passively capturing all bus traffic) on the same channel. The three trailing zeros are reserved parameters unused for RT+MT initialization.

Optional Loopback Test

Before opening the device, the sample optionally runs an internal loopback test to verify the hardware is functioning correctly:

swResult = naibrd_1553_InternalLoopback(cardIndex, module, rtmtchan, &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");
}

This tests both Bus A and Bus B independently. A failure indicates a hardware problem on that bus — check cabling and module seating before proceeding.

RT Address Source

The RT address can be set from two sources. In software mode, your application writes the address directly via the API. In external mode, the address comes from hardware pins on the module. The sample supports both:

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);
}
else
{
   /* Unset RTAD_SW_EN and set RT_ADR_LAT in software */
   swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0008);
   swResult = naibrd_1553_RtSetAddressSource(DevNum, NAI_1553_RT_ADDR_SOURCE_EXTERNAL);
}

For software addressing, auxiliary register 0x2 is written with 0x0018 to enable both the software RT address enable (RTAD_SW_EN) and the address latch (RT_ADR_LAT) bits. For external addressing, 0x0008 sets the latch bit only — without the latch, the RT address will track the hardware pins in real time, which is undesirable in most 1553 applications because the address could change while the RT is running.

RT Address Relatch

On modules that support it (FT1-FT6 and CM1, but not FTK), the application offers the option to relatch the RT address from external pins before each monitoring cycle:

naibrd_1553_RtAddressRelatch(DevNum);

This re-reads the hardware pins and updates the latched address. Use this when you have changed the external address switch settings and want the RT to pick up the new address without reinitializing.

Important

Common initialization issues you may encounter:

  • Device open or init failure — naibrd_1553_Open() or naibrd_1553_Initialize() returned a non-zero error code. Verify that the card index, module number, and channel are correct and that no other process already holds the device open.

  • Loopback test failure — one or both buses failed the internal loopback. This indicates a hardware issue. Check module seating and cable connections before proceeding.

  • RT address not set correctly — if using software addressing, confirm that both RTAD_SW_EN and RT_ADR_LAT are set in auxiliary register 0x2. If using external pins, verify the physical switch settings and use naibrd_1553_RtGetAddress() to read back the current address.

MT Message Filtering

In combined RT+MT mode, the MT side captures all bus traffic by default. The sample demonstrates how to filter out unwanted traffic by disabling monitoring for subaddress 3 across all RT addresses:

swResult = naibrd_1553_MtMessageMonitoringDisable(DevNum, NAI_1553_RT_ADDR_ALL, NAI_1553_MT_FILTER_ALL, 1 << SA_DISABLE);

The parameters break down as follows:

  • NAI_1553_RT_ADDR_ALL — apply the filter to all RT addresses (0-31).

  • NAI_1553_MT_FILTER_ALL — disable monitoring in both Rx and Tx directions.

  • 1 << SA_DISABLE (value 1 << 3 = 8) — a bitmask identifying subaddress 3. Bit N corresponds to subaddress N.

After this call, the MT will silently ignore any transaction involving subaddress 3, regardless of which RT is addressed. The RT side is unaffected — it will still respond to BC commands on subaddress 3 if it is legalized.

To monitor a broader or narrower set of traffic, adjust the RT address parameter and the subaddress bitmask. Multiple subaddresses can be disabled in a single call by OR-ing their bit positions together.

Data Block Setup

The RT side requires data blocks to be created and mapped to subaddresses before it can participate in bus transactions. The sample creates four data blocks: one for Rx, one for Broadcast Rx, and two for Tx (to support double-buffered transmit).

Rx and Broadcast Data Blocks

To receive data from the BC on your chosen subaddress, create an Rx data block and map it:

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, 0, 1);

A separate Broadcast data block handles broadcast messages (RT address 31) on the same 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);

The nDataBlockType is the buffer type selected by the user — NAI_1553_RT_DATABLOCK_SINGLE, NAI_1553_RT_DATABLOCK_DOUBLE, or NAI_1553_RT_DATABLOCK_CIRCULAR. Double buffering (the default) prevents data from being overwritten mid-read by the hardware.

Tx Data Blocks (Double-Buffered)

The sample creates two Tx data blocks to support ping-pong buffering. Only one is mapped to the subaddress at any time — the other is the inactive buffer being updated with new data:

swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX1, NAI_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX2, NAI_1553_RT_DATABLOCK_SINGLE_32, 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;

Initially DATA_BLOCK_ID_TX1 is the active Tx buffer. When the application updates the Tx data, it writes to the inactive buffer and then swaps.

Important

Common data block issues you may encounter:

  • Data block creation failure — the device may have run out of memory for data blocks. Each data block consumes on-device RAM. Reduce the number of data blocks or use smaller buffer types.

  • Subaddress mapping failure — verify that the subaddress is in the valid range (0-31) and that no conflicting mapping already exists for the same subaddress and message type.

Tx Buffer Ping-Pong Update

During operation, the application periodically updates the Tx data to demonstrate active/inactive buffer swapping. This pattern ensures the BC always reads consistent data — it reads from the active buffer while your application writes to the inactive one.

Update Cycle

Every second, UpdateTxDataBlock() writes new data to the inactive buffer and swaps it to become the active buffer:

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

Writing to the Inactive Buffer

UpdateTxBuffer() increments all 32 data words and writes them to the specified data block:

for (i = 0; i < 32; i++)
{
   wBuffer[i] += 1;
}

swResult = naibrd_1553_RtDataBlockWrite(DevNum, nDataBlkID, wBuffer, RTBC_WORDCNT, 0);

The key point is that naibrd_1553_RtDataBlockWrite() writes to the inactive buffer. The naibrd_1553_RtTxDataBlockSwap() call then atomically points the hardware at the newly updated buffer. This prevents the BC from reading partially updated data.

Message Processing — Dual Stack Polling

The ProcessMessages() function is the core of the combined RT+MT operation. It polls two independent message stacks — one for the RT and one for the MT — in each iteration of the monitoring loop. Both stacks are checked on every pass, with a 10ms delay between passes.

RT Stack Polling

The RT stack captures messages addressed to this terminal. To retrieve the next message from the RT stack:

swResult = naibrd_1553_RtMessageGetFromStackRaw(DevNum, wsBuffer, NAI_1553_MAX_MESSAGE_SIZE_RT);
if (swResult > 0)
{
   swResult = naibrd_1553_RtMessageDecodeRaw(DevNum, wsBuffer, &DecodedMsgStruct);
}

The return value of naibrd_1553_RtMessageGetFromStackRaw() indicates the result: negative means error, zero means no message available, and positive means a message was retrieved. When a message is retrieved, naibrd_1553_RtMessageDecodeRaw() parses the raw buffer into a naiDecodedMessageStructure with named fields for block status, time tag, command word, data word count, and data payload.

MT Stack Polling

The MT stack captures all bus traffic that passes the filter configuration. The MT polling uses a parallel set of API calls:

swResult = naibrd_1553_MtMessageGetFromStackRaw(DevNum, wsBuffer, NAI_1553_MAX_MESSAGE_SIZE_MT, NAI_1553_MT_STACK_ACTIVE);
if (swResult > 0)
{
   swResult = naibrd_1553_MtMessageDecodeRaw(DevNum, wsBuffer, &DecodedMsgStruct);
}

Note that the MT retrieval function takes an additional parameter (NAI_1553_MT_STACK_ACTIVE) specifying which stack to read from. Both the RT and MT decode functions populate the same naiDecodedMessageStructure type.

Message Direction

Both the RT and MT display logic use bit 10 (mask 0x0400) of command word 1 to distinguish Rx from Tx messages:

  • When the TR bit is clear (0), this is an Rx message — the BC sent data to the RT. The full data payload is displayed.

  • When the TR bit is set (1), this is a Tx message — the BC requested data from the RT. Only the message header is displayed.

The application prefixes each message with RT: or MT: to indicate which stack it came from. This makes it clear when the same transaction is captured by both the RT (because it was addressed to this terminal) and the MT (because it was observed on the bus).

Concurrent RT and MT Observation

In combined RT+MT mode, the same transaction may appear in both stacks. For example, when the BC sends an Rx command to this RT’s address and subaddress, the RT stack will contain the transaction because the RT responded to it, and the MT stack will also contain it because the MT captured the bus traffic. The sample displays both, allowing you to verify that the RT response matches what the MT observed on the bus.

Important

Common message processing issues you may encounter:

  • No messages on RT stack — verify that a BC is sending commands to the RT address and subaddress you configured. The RT only captures messages addressed to it.

  • No messages on MT stack — check that naibrd_1553_MtMessageMonitoringDisable() has not filtered out the traffic you expect. Also verify that naibrd_1553_RtMtStart() was called (not just naibrd_1553_RtStart()).

  • Stack overflow — if messages are not polled fast enough, either stack can overflow. Reduce the polling delay or increase the monitoring loop frequency.

  • Decode error — verify that the buffer size is at least NAI_1553_MAX_MESSAGE_SIZE_RT for RT messages or NAI_1553_MAX_MESSAGE_SIZE_MT for MT messages, and that the retrieval call returned a positive value before decoding.

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. If file doesn’t exist, configure and save from board menu.

Module not recognized as 1553

Selected module is not FT-series or CM with 1553

Verify module type at the selected slot.

Device open or initialization failure

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

Verify parameters. Close other applications using this channel.

Loopback test failure on Bus A or B

Hardware fault on that bus, loose cabling

Check module seating and cable connections. Replace module if fault persists.

RT address not set correctly

Missing RTAD_SW_EN or RT_ADR_LAT bits in auxiliary register

For software addressing, write 0x0018 to aux register 0x2. For external, verify pin settings.

No messages on RT stack

No BC is addressing this RT, or subaddress not legalized

Verify a BC is active on the bus and sending to the configured RT address and subaddress.

No messages on MT stack

MT filtering disabled all relevant traffic, or RtMtStart() not called

Check filter state. Ensure you called naibrd_1553_RtMtStart() (not RtStart()).

Same message appears in both RT and MT stacks

Normal behavior in combined mode

This is expected. Both stacks independently capture transactions involving this RT.

Stack overflow — messages lost

Application not polling fast enough for the bus traffic rate

Reduce the polling delay interval or process messages more efficiently.

Tx data appears stale to BC

Buffer swap not called after writing new data

Always call naibrd_1553_RtTxDataBlockSwap() after writing to the inactive buffer.

RT address relatch has no effect

Module does not support relatch (FTK), or using software addressing

Relatch only works with external addressing on FT1-FT6 and CM1 modules.

Full Source

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

Full Source — M1553_RTMT_Receive.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"

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

/* Function prototypes */
static bool_t Run_M1553_RTMT_Receive(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;

#define SA_DISABLE      3

/* Global Variables */
static int32_t currDataBlock;

/**************************************************************************************************************/
/**
<summary>
The purpose of the M1553_RTMT_Receive is to illustrate the methods to call in the naibrd library to configure
the 1553 channel as a combined Remote Terminal (RT) and Bus Monitor (MT), legalize Subaddress 2 for Tx, Rx and Broadcast
messages, disable Subaddress 3 monitoring on the Bus Monitor, and set up the RT to receive data using double buffers
and transmit data from two alternating Tx buffers (active and inactive). If the RT and/or MT receives an Rx message,
the received data will be displayed. If the RT receives a Tx message, the data in the active Tx buffer will be
sent to the bus and the message information will be displayed. If the MT detects the Tx message, the message
information will be displayed. 1553 messages for Subaddress 3 will not get monitored. While the RT is running,
Tx buffer data will be updated periodically by incrementing all 32 data words of Tx data. 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_MtMessageMonitoringDisable
 - 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_RtMtStart
 - naibrd_1553_RtMtStop
 - naibrd_1553_RtTxDataBlockSwap
 - naibrd_1553_RtMessageGetFromStackRaw
 - naibrd_1553_RtMessageDecodeRaw
 - naibrd_1553_MtMessageGetFromStackRaw
 - naibrd_1553_MtMessageDecodeRaw
 - 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_RTMT_Receive(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_RTMT_Receive(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_RTMT_Receive(int32_t cardIndex, int32_t module, uint32_t modid)
{
   /* Variables */
   bool_t bQuit = FALSE;
   int32_t rtmtchan;
   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, &rtmtchan, &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, rtmtchan, &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, rtmtchan, 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_RTANDMT,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);

   /* Disable Monitoring for SA 3 Message Types (In default power on state, all messages are monitored) */
   swResult = naibrd_1553_MtMessageMonitoringDisable(DevNum, NAI_1553_RT_ADDR_ALL, NAI_1553_MT_FILTER_ALL, 1 << SA_DISABLE);
   if(swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_Initialize  %d", swResult);
      return bQuit;
   }

   /* 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, 0, 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, NAI_1553_RT_DATABLOCK_SINGLE_32, 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, NAI_1553_RT_DATABLOCK_SINGLE_32, 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 (modid != NAI_MODULE_ID_FTK)
      {
         /* 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')
               {
                  /* The RT address relatch feature is only supported on FT[1-6] and CM1 modules */
                  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);
         }

         /* Start RT */
         swResult = naibrd_1553_RtMtStart(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_RtMtStop(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;
   naiDecodedMessageStructure DecodedMsgStruct;
   uint16_t wsBuffer[72] = { 0x0000 };
   int32_t count = 0;
   int32_t mtcount = 0;

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

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

         period = time(NULL) + 1;
      }

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

         if ((DecodedMsgStruct.wCommandWord1 & 0x0400) != 0x0400)   /* If this is a Rx message */
         {
            printf("RT: Rx Msg Received\n");
            printf("\n\nDecoded Message:\n\n");
            printf("Block Status - 0x%04X\n", DecodedMsgStruct.wBlockStatus);
            printf("Time Tag - 0x%04X\n", DecodedMsgStruct.wTimeTag);
            printf("Command Word - 0x%04X\n", DecodedMsgStruct.wCommandWord1);
            printf("Data Word Count - 0x%04X\n", DecodedMsgStruct.wDataWordCount);
            printf("Data:");
            for (i = 0; i < DecodedMsgStruct.wDataWordCount; i++)
            {
               if (i % 8 == 0)
               {
                  printf("\n");
               }
               printf("0x%04X ", DecodedMsgStruct.waData[i]);
            }
            printf("count: %d\n", count++);
            printf("\n\n");
         }
         else
         {
            printf("RT: Tx Msg Received\n");
            printf("\n\nDecoded Message:\n\n");
            printf("Block Status - 0x%04X\n", DecodedMsgStruct.wBlockStatus);
            printf("Time Tag - 0x%04X\n", DecodedMsgStruct.wTimeTag);
            printf("Command Word - 0x%04X\n", DecodedMsgStruct.wCommandWord1);
            printf("Data Word Count - 0x%04X\n", DecodedMsgStruct.wDataWordCount);
            printf("count: %d\n", count++);
            printf("\n\n");
         }
      }

      /************************* MT POLL *************************/
      /* If the stack pointer has updated (new data arrived), read one message at a time */
      swResult = naibrd_1553_MtMessageGetFromStackRaw(DevNum, wsBuffer, NAI_1553_MAX_MESSAGE_SIZE_MT, NAI_1553_MT_STACK_ACTIVE);
      if (swResult < 0)
      {
         printf("Error: naibrd_1553_MtMessageGetFromStackRaw %d\n\n", swResult);
         return 0;
      }
      else if (swResult > 0)
      {
         /* Decode Raw Message */
         swResult = naibrd_1553_MtMessageDecodeRaw(DevNum, wsBuffer, &DecodedMsgStruct);
         if (swResult < 0)
         {
            printf("Error: naibrd_1553_MtMessageDecodeRaw %d\n\n", swResult);
            return 0;
         }

         if ((DecodedMsgStruct.wCommandWord1 & 0x0400) != 0x0400)   /* If this is a Rx message */
         {
            printf("MT: Rx Msg Monitored\n");
            printf("\n\nDecoded Message:\n\n");
            printf("Block Status - 0x%04X\n", DecodedMsgStruct.wBlockStatus);
            printf("Time Tag - 0x%04X\n", DecodedMsgStruct.wTimeTag);
            printf("Command Word - 0x%04X\n", DecodedMsgStruct.wCommandWord1);
            printf("Data Word Count - 0x%04X\n", DecodedMsgStruct.wDataWordCount);
            printf("Data:");
            for (i = 0; i < DecodedMsgStruct.wDataWordCount; i++)
            {
               if (i % 8 == 0)
               {
                  printf("\n");
               }
               printf("0x%04X ", DecodedMsgStruct.waData[i]);
            }
            printf("count: %d\n", mtcount++);
            printf("\n\n");
         }
         else
         {
            printf("MT: Tx Msg Monitored\n");
            printf("\n\nDecoded Message:\n\n");
            printf("Block Status - 0x%04X\n", DecodedMsgStruct.wBlockStatus);
            printf("Time Tag - 0x%04X\n", DecodedMsgStruct.wTimeTag);
            printf("Command Word - 0x%04X\n", DecodedMsgStruct.wCommandWord1);
            printf("Data Word Count - 0x%04X\n", DecodedMsgStruct.wDataWordCount);
            printf("count: %d\n", mtcount++);
            printf("\n\n");
         }
      }

      nai_msDelay(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 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