M1553 RT Receive FIFO
Edit this on GitLab
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:
-
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. -
Query the user for a card index with
naiapp_query_CardIndex(). -
Query for a module slot with
naiapp_query_ModuleNumber(). -
Retrieve the module ID with
naibrd_GetModuleID()so downstream code can adapt to the specific 1553 variant installed. -
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:
|
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:
-
Get1553RTCfg()— prompts for the 1553 channel number and RT address. -
Get1553Address()— prompts for the subaddress to legalize for Tx, Rx, and broadcast traffic. The default is subaddress 2. -
Get1553LogicalDevNum()— prompts for a logical device number (default: device 1). -
Get1553RTAddressSource()— asks whether to set the RT address in software or use the hardware address pins. -
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
|
|
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
|
|
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
|
|
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
|
|
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 |
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 |
RT address source conflict |
Software address set but hardware pin mode active, or vice versa |
Match |
No messages appearing |
RT not started, subaddress not legalized, FIFO mode not enabled, or BC not sending to this RT/subaddress |
Verify |
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 |
Always |
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 |
|
Always swap after writing to the inactive block. Verify |
Rx data tearing |
Wrong buffer type for message rate — single buffer under load |
Switch to double-buffered ( |
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;
}