SUM1553 Remote Terminal Ping-Pong Sample Application (SSK 1.x)
Overview
The SUM1553 RT Ping-Pong sample application configures an NAI Summit-based MIL-STD-1553 channel as a Remote Terminal (RT) — an addressed device that responds to a Bus Controller. It shows the RT side of the transfers driven by the SUM1553 BC Scheduler sample: receiving BC→RT messages and supplying the data an RT→BC message transmits, using ping-pong buffering so the host can service one buffer while the 1553 core uses the other.
Unlike the Bus Controller, an RT doesn’t drive a command list. Instead you configure its identity and behavior once — address, active buses, which subaddresses are legal, and the buffering scheme — then enable it and let the core respond to the BC automatically. The host’s job is to service the buffers: read data the BC has delivered, and refresh the data the RT will transmit.
Once running, the menu lets you press Enter to list the BC→RT messages received on each subaddress, U to update the RT→BC transmit data, or Q to quit. Pair it with the BC Scheduler sample (or SUM1553_BC_RTtoRT) supplying the BC side.
Note
This guide assumes the core SUM1553 lifecycle (reset →
IsResetting→SetMode→EnableExecution) introduced in the SUM1553 BC RT-to-RT guide. It focuses on the RT-specific configuration and buffer servicing.
Prerequisites
Before running this sample, make sure you have:
- An NAI board with a Summit-capable FT 1553 module (FTA–FTF, FTJ–FTK).
- A Bus Controller on the same bus addressing this RT (e.g. the companion SUM1553 BC Scheduler sample).
- SSK 1.x installed on your development host, with the sample applications built.
How to Run
Launch the SUM1553_RT_PingPong executable from your build output directory. On startup the application looks for a configuration file (default_SUM1553_RTPP.txt). On the first run this file will not exist — the application presents an interactive board menu where you configure a board connection, card index, and module slot. After selecting the module you choose the RT channel and its RT address; the RT then responds to the bus until you quit.
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 the standard SSK 1.x startup flow and hands a valid module to Run_SUM1553_RT_PingPong().
Important
Common connection errors you may encounter at this stage:
- No board found / connection timeout — verify the board is powered and connected; check
default_SUM1553_RTPP.txtor reconfigure in the board menu.- “Module selected does not support Summit 1553 Functionality” — the selected module is not a Summit (FT) 1553 module; choose an FT module.
Configuring the Channel as a Remote Terminal
Run_SUM1553_RT_PingPong() selects the channel and RT address with the shared Get1553RTCfg() helper, resets the channel, waits for the reset to finish, then configures the RT:
naibrd_SUM1553_SetMode(cardIndex, module, rtchan, NAI_SUM1553_OPSTATUS_RT_MODE); /* RT mode */
naibrd_SUM1553_RT_SetBusEnable(cardIndex, module, rtchan, 1, 1); /* enable bus A and B */
naibrd_SUM1553_RT_SetAddress(cardIndex, module, rtchan, rtaddr); /* set RT address */
naibrd_SUM1553_RT_ConfigureForPingPong(cardIndex, module, rtchan); /* ping-pong descriptor table */
naibrd_SUM1553_RT_SetPingPongEnable(cardIndex, module, rtchan, 1); /* enable ping-pong */
naibrd_SUM1553_RT_Legalize(cardIndex, module, rtchan, NAI_SUM1553_SAMCTYPE_SA | NAI_SUM1553_SAMCTYPE_RX, 0xFFFFFFFF, 1); /* legalize all Rx SAs */
naibrd_SUM1553_RT_Legalize(cardIndex, module, rtchan, NAI_SUM1553_SAMCTYPE_SA | NAI_SUM1553_SAMCTYPE_TX, 0xFFFFFFFF, 1); /* legalize all Tx SAs */
naibrd_SUM1553_Proc_SetCtrl(cardIndex, module, rtchan, 0); /* disable processor control */nai_status_t naibrd_SUM1553_SetMode(...)—NAI_SUM1553_OPSTATUS_RT_MODEputs the channel in Remote Terminal mode.nai_status_t naibrd_SUM1553_RT_SetBusEnable(int32_t cardIndex, int32_t module, int32_t channel, bool_t aenable, bool_t benable)— enables the RT to respond on bus A and/or bus B (a 1553 bus is dual-redundant).nai_status_t naibrd_SUM1553_RT_SetAddress(int32_t cardIndex, int32_t module, int32_t channel, uint8_t address)— sets the RT address (0–30) the terminal answers to.nai_status_t naibrd_SUM1553_RT_ConfigureForPingPong(int32_t cardIndex, int32_t module, int32_t channel)— initializes the RT descriptor table for ping-pong (double) buffering.nai_status_t naibrd_SUM1553_RT_SetPingPongEnable(int32_t cardIndex, int32_t module, int32_t channel, bool_t enabled)— turns ping-pong buffering on or off.nai_status_t naibrd_SUM1553_RT_Legalize(int32_t cardIndex, int32_t module, int32_t channel, nai_sum1553_samctype_t samctype, uint32_t samcmask, bool_t legal)— marks subaddresses (or mode codes) legal or illegal. Thesamctypeselects the descriptor set — hereSAMCTYPE_SA | SAMCTYPE_RXfor receive subaddresses andSAMCTYPE_SA | SAMCTYPE_TXfor transmit — andsamcmaskis a 32-bit mask of which ones (0xFFFFFFFF= all 32). An RT rejects commands to illegal subaddresses.nai_status_t naibrd_SUM1553_Proc_SetCtrl(int32_t cardIndex, int32_t module, int32_t channel, nai_sum1553_procctrl_t mask)— configures the processor-control interface;0disables it (that feature is exercised by the SUM1553 RT ProcCtrl sample instead).
With configuration done, the RT is enabled with naibrd_SUM1553_EnableExecution(... 1) and begins responding to the bus.
What Ping-Pong Buffering Is
Each subaddress has two data buffers. While the 1553 core is reading from or writing to one buffer to service a bus message, the host accesses the other — so a host read never tears against an in-flight bus transfer, and vice versa. naibrd_SUM1553_RT_ConfigureForPingPong() sets up the descriptor table for this, and naibrd_SUM1553_RT_SetPingPongEnable() turns it on.
The trade-off is that updating transmit data safely requires a short handshake with the core (see Supplying RT→BC Transmit Data).
Receiving BC→RT Messages
Pressing Enter calls Retrieve_SUM1553_BCRTMessages(), which walks all 32 receive subaddresses, checks each one’s control word for the Block Accessed (BAC) bit — set when a new message has landed — and reads and clears any that have new data:
for (sa = 0; sa < 32; sa++)
{
naibrd_SUM1553_RT_GetControlWord(cardIndex, module, rtchan, NAI_SUM1553_SAMCTYPE_SA | NAI_SUM1553_SAMCTYPE_RX, sa, &ctrl);
if (ctrl & NAI_SUM1553_RT_CTL_BAC) /* new data on this subaddress */
{
naibrd_SUM1553_RT_ReadRxDataBlock(cardIndex, module, rtchan, TRUE, sa, &rxwordcnt, ×tamp, rxdatablock);
naibrd_SUM1553_RT_ClearBlockAccess(cardIndex, module, rtchan, NAI_SUM1553_SAMCTYPE_SA | NAI_SUM1553_SAMCTYPE_RX, sa);
/* print subaddress, timestamp, and the received words */
}
}nai_status_t naibrd_SUM1553_RT_GetControlWord(int32_t cardIndex, int32_t module, int32_t channel, nai_sum1553_samctype_t samctype, uint16_t samc, uint16_t* outctrl)— reads a subaddress descriptor’s control word.NAI_SUM1553_RT_CTL_BAC— the Block Accessed bit in that control word; the core sets it when a message has been received into the buffer.nai_status_t naibrd_SUM1553_RT_ReadRxDataBlock(int32_t cardIndex, int32_t module, int32_t channel, bool_t sadatablock, uint16_t addr, uint16_t* outwordcnt, uint16_t* outtimestamp, uint16_t outdatablock[32])— reads the received words for a subaddress, along with the word count and a bus time tag.sadatablock = TRUEselects the subaddress data block (rather than a mode-code block);addris the subaddress.nai_status_t naibrd_SUM1553_RT_ClearBlockAccess(int32_t cardIndex, int32_t module, int32_t channel, nai_sum1553_samctype_t samctype, uint16_t samc)— clears the BAC bit so the next message on that subaddress is detected as new.
Supplying RT→BC Transmit Data
Pressing U calls Update_SUM1553_RTSAXmitData(), which refreshes the data the RT transmits when the BC issues an RT→BC (transmit) command for the subaddress. Because ping-pong is active, the update follows a safe servicing sequence: disable ping-pong, confirm it is disabled, load the new transmit block, then re-enable:
if (bPingPongEnabled)
{
naibrd_SUM1553_RT_SetPingPongEnable(cardIndex, module, rtchan, 0);
/* Wait until ping-pong is actually disabled before touching the buffer */
while (naibrd_SUM1553_RT_GetPingPongEnabled(cardIndex, module, rtchan, &enabled) == NAI_SUCCESS && enabled != 0);
}
naibrd_SUM1553_RT_LoadTxDataBlock(cardIndex, module, rtchan, TRUE, sa, txdatablock);
if (bPingPongEnabled)
naibrd_SUM1553_RT_SetPingPongEnable(cardIndex, module, rtchan, 1);nai_status_t naibrd_SUM1553_RT_LoadTxDataBlock(int32_t cardIndex, int32_t module, int32_t channel, bool_t sadatablock, uint16_t addr, const uint16_t datablock[32])— loads the 32 transmit words for a subaddress.sadatablock = TRUEselects the subaddress data block;addris the subaddress.nai_status_t naibrd_SUM1553_RT_GetPingPongEnabled(int32_t cardIndex, int32_t module, int32_t channel, bool_t* outenabled)— reports whether ping-pong is currently active, used to confirm the disable took effect before the buffer is touched.
Important
Don’t write a transmit buffer while ping-pong is enabled — you could modify the buffer the core is about to transmit from. Always disable ping-pong, confirm it via
naibrd_SUM1553_RT_GetPingPongEnabled(), service the buffer, then re-enable. The sample’s initial data load (before the RT is enabled) skips this handshake because nothing is running yet.
Troubleshooting Reference
This table summarizes common errors and symptoms covered above. Consult your module’s manual for hardware-specific diagnostics.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
| No board found or connection timeout | Board not powered, incorrect or missing config file, network issue | Verify hardware; check default_SUM1553_RTPP.txt or reconfigure in the board menu. |
| ”Module selected does not support Summit 1553 Functionality” | Selected module is not a Summit (FT) 1553 module | Choose an FT 1553 module (FTA–FTF, FTJ–FTK). |
| RT never responds to the BC | RT address mismatch, buses not enabled, or subaddress not legalized | Confirm the RT address matches the BC’s command, enable bus A/B, and legalize the Rx/Tx subaddresses. |
| No BC→RT messages listed | No BC transmitting, or BAC not being checked/cleared | Run a BC (e.g. the BC Scheduler); the retrieve loop only prints subaddresses whose BAC bit is set. |
| Transmit data appears corrupted or stale | Buffer written while ping-pong enabled | Use the disable → verify → load → re-enable sequence before updating a transmit block. |
| Same message reported repeatedly | Block Accessed bit not cleared | Call naibrd_SUM1553_RT_ClearBlockAccess() after reading each subaddress. |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — SUM1553_RT_PingPong.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
/* Common Sample Program include files */
#include "include/naiapp_boardaccess_menu.h"
#include "include/naiapp_boardaccess_query.h"
#include "include/naiapp_boardaccess_access.h"
#include "include/naiapp_boardaccess_display.h"
#include "include/naiapp_boardaccess_utils.h"
/* Common 1553 Sample Program include files */
#include "nai_1553_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_sum1553.h"
static const int8_t *CONFIG_FILE = (int8_t *)"default_SUM1553_RTPP.txt";
/* Function prototypes */
static bool_t Run_SUM1553_RT_PingPong(int32_t cardIndex, int32_t module, uint32_t modid);
static void Retrieve_SUM1553_BCRTMessages(int32_t cardIndex, int32_t module, int32_t rtchan);
static void Update_SUM1553_RTSAXmitData(int32_t cardIndex, int32_t module, int32_t rtchan, uint8_t increment, bool_t PingPongEnabled);
static const int32_t DEF_RT_CHANNEL = 1;
static const uint8_t DEF_RT_ADDRESS = 1;
static const uint8_t DEF_RT_SUBADDR = 2;
static uint16_t datablock[32][32];
/**************************************************************************************************************/
/**
<summary>
The purpose of the SUM1553_RT_PingPong is to illustrate the methods to call in the naibrd library to configure
the 1553 channel as a Remote Terminal and receiving BC-RT messages and sending responses to RT-BC messages.
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
Note, the SUM1553_RT_PingPong can run in conjunction with the SUM1553_BC_Scheduler applications to illustrate
BC and RT operations together with the NAI 1553 module.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t SUM1553_RT_PingPong(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_SUM1553_RT_PingPong(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;
}
/**************************************************************************************************************/
/**
<summary>
Run_SUM1553_RT_PingPong queries the user for the module and channel to configure as the Remote Terminal (RT).
After getting the module/channel selection, methods in the naibrd library are invoked to setup this channel
as a RT configured to run with Buffer Ping Pong.
Once the RT is configured and running, the user can:
1) Type the Enter key to view the BC-RT messages that are received from all subaddresses.
2) Type 'U' to change the data in the RT-BC message.
3) Type 'Q' to quit stop the RT execution and exit the routine.
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_SUM1553_RT_PingPong(int32_t cardIndex, int32_t module, uint32_t modid)
{
bool_t bQuit;
bool_t bContinue = TRUE;
bool_t resetting = TRUE;
int32_t rtchan = 1;
uint8_t rtaddr = 1;
uint8_t increment = 0;
int32_t i, j;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
bQuit = Get1553RTCfg(modid, DEF_RT_CHANNEL, DEF_RT_ADDRESS, &rtchan, &rtaddr);
if (!bQuit)
{
/* Reset RT channel */
check_status(naibrd_SUM1553_Reset(cardIndex,module,rtchan));
/* Wait for channels to reset */
while(check_status(naibrd_SUM1553_IsResetting(cardIndex,module,rtchan,&resetting)) == NAI_SUCCESS && resetting);
/* Configure RT */
check_status(naibrd_SUM1553_SetMode(cardIndex,module,rtchan,NAI_SUM1553_OPSTATUS_RT_MODE)); /* Set to RT mode */
check_status(naibrd_SUM1553_RT_SetBusEnable(cardIndex,module,rtchan,1,1)); /* Enable bus A and bus B */
check_status(naibrd_SUM1553_RT_SetAddress(cardIndex,module,rtchan,rtaddr)); /* Set RT address */
check_status(naibrd_SUM1553_RT_ConfigureForPingPong(cardIndex,module,rtchan)); /* Set up descriptor table with ping pong buffers */
check_status(naibrd_SUM1553_RT_SetPingPongEnable(cardIndex,module,rtchan,1)); /* Enable ping pong */
check_status(naibrd_SUM1553_RT_Legalize(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_SA|NAI_SUM1553_SAMCTYPE_RX,0xFFFFFFFF,1)); /* Legalize the subaddresses we want for rx */
check_status(naibrd_SUM1553_RT_Legalize(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_SA|NAI_SUM1553_SAMCTYPE_TX,0xFFFFFFFF,1)); /* Legalize the subaddresses we want for tx*/
/* Disable processor control */
check_status(naibrd_SUM1553_Proc_SetCtrl(cardIndex,module,rtchan,0));
/* Load the subaddress transmit data */
Update_SUM1553_RTSAXmitData(cardIndex,module,rtchan,0, FALSE);
for (i = 0; i < 32; i++)
for (j = 0; j < 32; j++)
datablock[i][j] = 0;
/* Run the RT */
check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,rtchan,1));
}
if (bQuit)
bContinue = FALSE;
while (bContinue)
{
printf("\nType Enter key BC-RT to view BC-RT message or U to update the subaddress transmit data or %c to quit: ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (toupper(inputBuffer[0]) == 'U')
{
increment++;
Update_SUM1553_RTSAXmitData(cardIndex,module,rtchan,increment, TRUE);
}
else
{
Retrieve_SUM1553_BCRTMessages(cardIndex, module, rtchan);
}
}
else
bContinue = FALSE;
}
/* Disable the RT */
check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,rtchan,0));
return bQuit;
}
/**************************************************************************************************************/
/**
<summary>
Retrieve_SUM1553_BCRTMessages reads the Control Word for the BC-RT (i.e. Receive) Subaddress. If the Block
Accessed (BAC) bit is set, indicating a new message, the Data block associated with the BC-RT message is
read and displayed.
</summary>
*/
/**************************************************************************************************************/
static void Retrieve_SUM1553_BCRTMessages(int32_t cardIndex, int32_t module, int32_t rtchan)
{
uint16_t ctrl;
uint16_t rxdatablock[32], rxwordcnt;
uint16_t timestamp;
uint8_t sa;
int32_t i;
for (sa = 0; sa < 32; sa++)
{
check_status(naibrd_SUM1553_RT_GetControlWord(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_SA|NAI_SUM1553_SAMCTYPE_RX,sa,&ctrl));
if (ctrl & NAI_SUM1553_RT_CTL_BAC) /* new data */
{
check_status(naibrd_SUM1553_RT_ReadRxDataBlock(cardIndex,module,rtchan,TRUE,sa,&rxwordcnt,×tamp,rxdatablock));
check_status(naibrd_SUM1553_RT_ClearBlockAccess(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_SA|NAI_SUM1553_SAMCTYPE_RX,sa));
if (rxwordcnt == 0)
rxwordcnt = 32;
printf("SA %d ", sa);
printf("TimeTag: %04X ", timestamp);
printf("Data: ");
for (i = 0; i < rxwordcnt; i++)
{
if (i != 0)
printf(",");
printf ("%04X", rxdatablock[i]);
}
printf("\n");
}
}
}
/**************************************************************************************************************/
/**
<summary>
Update_SUM1553_RTSAXmitData changes the data that is sent in response to the RT-BC messages sent to the
"DEF_RT_SUBADDR" Subaddress.
Note: To properly implement buffer servicing while the core is using the ping pong buffering scheme, the
host or subsystem needs to do the following:
- Disable the ping pong mode by setting PPEN (Ping Pong Enable) (Core Register 0, bit 2) to 0.
- Verify that ping pong mode has been disabled by querying bit MSGTO (Message Timeout) (Core Register 0, bit 9)
is set to 0.
- Service the secondary buffer
- Re-enable ping pong mode (setting PPEN) to 1.
- Verify that ping pong mode has been enabled by querying MSGTO to be set to 1.
</summary>
*/
/**************************************************************************************************************/
static void Update_SUM1553_RTSAXmitData(int32_t cardIndex, int32_t module, int32_t rtchan, uint8_t increment, bool_t bPingPongEnabled)
{
uint16_t sa = DEF_RT_SUBADDR;
uint16_t txdatablock[32];
uint8_t msb, lsb;
int32_t i;
bool_t enabled;
msb = (uint8_t)(sa << 4) + (increment & 0x0F); /* upper byte (subaddress=upper 4 bits | increment=lower 4 bits)) */
lsb = 0;
for (i = 0; i < 32; i++)
{
txdatablock[i] = (msb << 8) | (uint8_t)(lsb + i); /* incremental data */
}
/* Update the data */
if (bPingPongEnabled)
{
naibrd_SUM1553_RT_SetPingPongEnable(cardIndex, module, rtchan, 0);
/* Wait for ping pong to be disabled */
while(check_status(naibrd_SUM1553_RT_GetPingPongEnabled(cardIndex,module,rtchan,&enabled)) == NAI_SUCCESS && (enabled != 0));
}
check_status(naibrd_SUM1553_RT_LoadTxDataBlock(cardIndex,module,rtchan,TRUE, sa,txdatablock));
if (bPingPongEnabled)
{
naibrd_SUM1553_RT_SetPingPongEnable(cardIndex, module, rtchan, 1);
}
}