SUM1553 Bus Controller Scheduler Sample Application (SSK 1.x)
Overview
The SUM1553 BC Scheduler sample application configures an NAI Summit-based MIL-STD-1553 channel as a Bus Controller (BC) and runs a cyclic schedule of messages — a repeating minor frame that mixes BC-to-RT and RT-to-BC transfers. Where the SUM1553 BC RT-to-RT sample sends one message on demand, this sample builds a self-looping command list that the BC executes continuously, and lets you read back what a Remote Terminal returns and change the transmit data on the fly.
The schedule this sample builds is:
- Load minor-frame timer to 100 ms — paces the loop.
- BC→RT, 32 words to RT address 1, subaddress 2 (the BC transmits data to the RT).
- RT→BC, 32 words from RT address 1, subaddress 2 (the RT transmits data back to the BC).
- BC→RT, 16 words to RT address 1, subaddress 3 (a second BC-to-RT message).
- Go to the first block — loops the schedule forever.
The direction of each message is set by the transmit/receive (T/R) bit in its command word: a receive command (tx = 0) makes the RT the receiver, so the BC transmits to it (BC→RT); a transmit command (tx = 1) makes the RT the transmitter, so it sends data to the BC (RT→BC).
Once running, the menu lets you press Enter to read the RT→BC response, U to update the data the BC transmits, or Q to quit. Like the other BC samples, it can run against the companion SUM1553 RT PingPong or SUM1553 RT ProcCtrl apps supplying the RT side.
Note
This guide assumes the BC fundamentals from the SUM1553 BC RT-to-RT guide — the reset/mode lifecycle, command blocks and data blocks, and the
NAI_SUM1553_BC_CTRL_WORD()/NAI_SUM1553_COMMAND_WORD()macros. It focuses on what scheduling adds.
Prerequisites
Before running this sample, make sure you have:
- An NAI board with a Summit-capable FT 1553 module (FTA–FTF, FTJ–FTK).
- A Remote Terminal on the bus at the targeted address (RT 1), e.g. one of the companion SUM1553 RT sample apps.
- SSK 1.x installed on your development host, with the sample applications built.
How to Run
Launch the SUM1553_BC_Scheduler executable from your build output directory. On startup the application looks for a configuration file (default_SUM1553_BCSched.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 BC channel; the schedule then runs continuously 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_BC_Scheduler().
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_BCSched.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 BC and Building the Schedule
As in the RT-to-RT sample, Run_SUM1553_BC_Scheduler() selects the channel with Get1553BCCfg(), resets it and waits for naibrd_SUM1553_IsResetting() to clear, then sets Bus Controller mode with naibrd_SUM1553_SetMode(... NAI_SUM1553_OPSTATUS_BC_MODE). It then loads the schedule as a sequence of command blocks.
The Message Schedule
Pacing the Loop — Minor-Frame Timer
The first block loads the minor-frame timer, which sets how long each pass through the schedule takes (here 100 ms). The timer value is passed in the timerus argument, in microseconds:
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_LOAD_MINOR_FRAME_TIMER, 1, 1, 0, 0);
naibrd_SUM1553_BC_LoadCmdBlock(cardIndex, module, bcchan, ncmd++, ctrl, 0, 0, 0, 0, /*timerus*/ 100000);NAI_SUM1553_OPCODE_LOAD_MINOR_FRAME_TIMER— the block’s opcode; the BC loads its minor-frame timer from thetimerusfield (100000 µs = 100 ms) rather than sending a bus message.
BC→RT and RT→BC Messages
Each transfer is a command block whose command word’s T/R bit sets the direction. A BC→RT message uses a receive command (tx = 0) and points at a data block the BC transmits:
/* BC -> RT, 32 words to subaddress 2 */
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT, 1, 1, 0, 0);
cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr, 0, rtsubaddr, 32); /* tx = 0 -> RT receives */
naibrd_SUM1553_BC_LoadCmdBlock(cardIndex, module, bcchan, ncmd++, ctrl, cmd1, 0, BLOCKA, 0, 0);
for (i = 0; i < 32; i++) datablock[BLOCKA][i] = (uint16_t)(0xA000 + i);
naibrd_SUM1553_BC_LoadDataBlock(cardIndex, module, bcchan, BLOCKA, datablock[BLOCKA]);An RT→BC message uses a transmit command (tx = 1); the RT sources the data, and the BC captures it into the block’s data block for later read-back:
/* RT -> BC, 32 words from subaddress 2 */
cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr, 1, rtsubaddr, 32); /* tx = 1 -> RT transmits */
naibrd_SUM1553_BC_LoadCmdBlock(cardIndex, module, bcchan, ncmd++, ctrl, cmd1, 0, BLOCKB, 0, 0);The sample uses three data blocks: BLOCKA for the first BC→RT message, BLOCKB for the RT→BC read-back, and BLOCKC for the second (16-word) BC→RT message.
Looping the Schedule
A final GOTO block branches back to the first command block, so the BC repeats the frame indefinitely:
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_GOTO, 0, 0, 0, 0);
naibrd_SUM1553_BC_LoadCmdBlock(cardIndex, module, bcchan, ncmd++, ctrl, 0, 0, 0, 0, 0);NAI_SUM1553_OPCODE_GOTO— branches execution back to the start of the list (instead ofENDOFLIST, which would stop the BC after one pass). This is what turns the list into a repeating schedule.
The BC is then pointed at the first block and started:
naibrd_SUM1553_BC_SetCmdBlockPtr(cardIndex, module, bcchan, FIRST_CMD);
naibrd_SUM1553_EnableExecution(cardIndex, module, bcchan, 1);Reading Back the RT Response
Pressing Enter calls Retrieve_SUM1553_RTBCMessages(), which reads the RT→BC command block (BLOCKB), checks the BAME (Block Access Message Error) bit in the read-back control word, and — if clear — reads the data the RT transmitted:
naibrd_SUM1553_BC_ReadCmdBlock(cardIndex, module, bcchan, BLOCKB,
&ctrl, &cmd1, &cmd2, /*datablock*/ NULL,
&status1, &status2, &branchblock, &timerus);
if ((ctrl & NAI_SUM1553_BC_CNTL_BAME) == 0) /* no block-access message error */
{
naibrd_SUM1553_BC_ReadDataBlock(cardIndex, module, bcchan, BLOCKB, rxdatablock);
/* print status1, status2, and the 32 received words */
}nai_status_t naibrd_SUM1553_BC_ReadCmdBlock(int32_t cardIndex, int32_t module, int32_t channel, uint32_t blockIndex, uint16_t* outctrl, uint16_t* outcmd1, uint16_t* outcmd2, uint16_t* outdatablock, uint16_t* outstatus1, uint16_t* outstatus2, uint16_t* outbranchblock, uint32_t* outtimerus)— reads a command block back, including the control word the engine updates after execution and the two RT status words. Theoutdatablockpointer may beNULLwhen you only need the status.nai_status_t naibrd_SUM1553_BC_ReadDataBlock(int32_t cardIndex, int32_t module, int32_t channel, uint32_t blockIndex, uint16_t outdatablock[32])— reads the 32 data words captured for that block.NAI_SUM1553_BC_CNTL_BAME— the Block Access Message Error bit in the control word; the engine sets it if the message did not complete successfully. Check it before trusting the read-back data.
Updating Transmit Data Live
Pressing U calls Update_SUM1553_BCSAData(), which rewrites the data blocks for the two BC→RT messages (BLOCKA and BLOCKC) with a new incrementing pattern while the schedule keeps running:
for (i = 0; i < wordcnt; i++)
datablock[BLOCKA][i] = (msb << 8) | (uint8_t)(lsb + i);
naibrd_SUM1553_BC_LoadDataBlock(cardIndex, module, bcchan, BLOCKA, datablock[BLOCKA]);Because the schedule runs continuously, reloading a data block with naibrd_SUM1553_BC_LoadDataBlock() changes what the next pass transmits — no need to stop and restart the BC. The RT receiving those messages will see the updated data on the following frame.
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_BCSched.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→BC read-back prints nothing | BAME bit set — the message did not complete (no RT responding) | Bring up an RT at the targeted address/subaddress (e.g. a companion RT sample) before reading. |
| Response data never changes after pressing U | Reading the wrong block, or RT not echoing the updated data | The update rewrites BC→RT blocks (A/C); the RT→BC read-back (B) reflects what the RT chooses to transmit. |
| Schedule runs once and stops | List terminated with end-of-list instead of GOTO | Use NAI_SUM1553_OPCODE_GOTO to loop the schedule; ENDOFLIST halts after one pass. |
| Frame timing off | Minor-frame timer not loaded, or set too short for the message set | Load NAI_SUM1553_OPCODE_LOAD_MINOR_FRAME_TIMER with a timerus long enough for all messages in the frame. |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — SUM1553_BC_Scheduler.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_BCSched.txt";
/* Function prototypes */
static bool_t Run_SUM1553_BC_Scheduler(int32_t cardIndex, int32_t module, uint32_t modid);
static void Retrieve_SUM1553_RTBCMessages(int32_t cardIndex, int32_t module, int32_t bcchan);
static void Update_SUM1553_BCSAData(int32_t cardIndex, int32_t module, int32_t bcchan, uint8_t increment);
static const int32_t DEF_BC_CHANNEL = 2;
static const uint8_t DEF_RT_ADDR = 1;
static const uint8_t DEF_RT_SUBADDR = 2;
static const uint16_t RTBC_WORDCNT = 32;
static const uint16_t BLOCKA = 0;
static const uint16_t BLOCKB = 1;
static const uint16_t BLOCKC = 2;
static uint16_t datablock[3][32];
/**************************************************************************************************************/
/**
<summary>
The purpose of the SUM1553_BC_Scheduler is to illustrate the methods to call in the naibrd library to configure
the 1553 channel as a Bus Controller and send and receive BC-RT and RT-BC scheduled 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_BC_Scheduler can run in conjunction with the SUM1553_RT_PingPong or SUM1553_RT_ProcCtrl
applications to illustrate BC and RT operations together with the NAI 1553 module.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t SUM1553_BC_Scheduler(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_BC_Scheduler(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_BC_Scheduler queries the user for the module and channel to configure as the Bus Controller (BC).
After getting the module/channel selection, methods in the naibrd library are invoked to setup this channel
as a BC with the following scheduled predefined 1553 messages:
1) BC-RT message with 32 words of data to the "DEF_RT_ADDR" RT Address and "DEF_RT_SUBADDR" Subaddress
2) RT-BC message for 32 words of data to the "DEF_RT_ADDR" RT Address and "DEF_RT_SUBADDR" Subaddress
1) BC-RT message with 16 words of data to the "DEF_RT_ADDR" RT Address and "DEF_RT_SUBADDR+1" Subaddress
Once the BC is configured and running, the user can:
1) Type the Enter key to view the RT-BC response.
1) Type 'U' to change the data in the BC-RT message.
3) Type 'Q' to quit stop the BC execution and exit the routine.
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_SUM1553_BC_Scheduler(int32_t cardIndex, int32_t module, uint32_t modid)
{
bool_t bQuit;
bool_t bContinue = TRUE;
int32_t bcchan = 2;
const uint16_t FIRST_CMD = 0;
bool_t resetting;
uint32_t ncmd = 0;
int32_t wordcnt = 32;
uint8_t rtaddr = DEF_RT_ADDR;
uint8_t rtsubaddr = DEF_RT_SUBADDR;
uint16_t ctrl;
uint16_t cmd1, cmd2;
uint16_t datablocknum;
uint16_t branchblock;
uint32_t timerus;
uint8_t increment = 0;
int32_t i;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
bQuit = Get1553BCCfg(modid, DEF_BC_CHANNEL, &bcchan);
if (!bQuit)
{
/* Reset the channel */
check_status(naibrd_SUM1553_Reset(cardIndex,module,bcchan));
/* Wait for channels to reset */
while(check_status(naibrd_SUM1553_IsResetting(cardIndex,module,bcchan,&resetting)) == NAI_SUCCESS && resetting);
/* Setup the BC */
check_status(naibrd_SUM1553_SetMode(cardIndex,module,bcchan,NAI_SUM1553_OPSTATUS_BC_MODE)); /* Configure as BC */
/* Load commands */
ncmd = FIRST_CMD;
/* Load Minor Frame Timers to 100000 us (100 ms) */
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_LOAD_MINOR_FRAME_TIMER,1,1,0,0);
cmd1 = 0;
cmd2 = 0;
datablocknum = 0;
branchblock = 0;
timerus = 100000;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
/* BCRT Message with 32 words to RT SubAddress */
wordcnt = 32;
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT,1,1,0,0);
cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr,0,rtsubaddr,wordcnt);
cmd2 = 0;
datablocknum = BLOCKA;
branchblock = 0;
timerus = 0;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
for (i = 0; i < wordcnt; i++)
datablock[BLOCKA][i] = (uint16_t)(0xA000 + i);
check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKA,datablock[BLOCKA]));
/* RTBC Message with 32 words to RT SubAddress */
wordcnt = RTBC_WORDCNT;
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT,1,1,0,0);
cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr,1,rtsubaddr,wordcnt);
cmd2 = 0;
datablocknum = BLOCKB;
branchblock = 0;
timerus = 0;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
/* Writing to the BLOCKB datablock is not necessary. We initialize so we know that getting the RT transmit messages */
for (i = 0; i < wordcnt; i++)
{
datablock[BLOCKB][i] = (uint16_t)(0xB000 + i);
}
check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKB,datablock[BLOCKB]));
/* BCRT Message with 16 words to RT SubAddress */
wordcnt = 16;
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT,1,1,0,0);
cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr,0,rtsubaddr+1,wordcnt);
cmd2 = 0;
datablocknum = BLOCKC;
branchblock = 0;
timerus = 0;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
for (i = 0; i < wordcnt; i++)
datablock[BLOCKC][i] = (uint16_t)(0xC000 + i);
check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKC,datablock[BLOCKC]));
/* Branch back to beginning of schedule */
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_GOTO,0,0,0,0);
cmd1 = 0;
cmd2 = 0;
datablocknum = 0;
branchblock = 0;
timerus = 0;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
/* Start with the first command */
check_status(naibrd_SUM1553_BC_SetCmdBlockPtr(cardIndex,module,bcchan,FIRST_CMD));
/* Run the BC */
check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,bcchan,1));
while (bContinue)
{
printf("\nType Enter key for RT-BC 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_BCSAData(cardIndex,module,bcchan,increment);
}
else
{
Retrieve_SUM1553_RTBCMessages(cardIndex, module, bcchan);
}
}
else
bContinue = FALSE;
}
/* Disable the BC */
check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,bcchan,0));
}
return bQuit;
}
/**************************************************************************************************************/
/**
<summary>
Retrieve_SUM1553_RTBCMessages reads the Command Block associated with the RT-BC message sent to the "DEF_RT_ADDR"
RT Address and "DEF_RT_SUBADDR" Subaddress. If the BAME (Block Access Message Error) bit is clear, indicating
no error, the Data block associated with the RT-BC message for RT Address and Subaddress is read.
</summary>
*/
/**************************************************************************************************************/
static void Retrieve_SUM1553_RTBCMessages(int32_t cardIndex, int32_t module, int32_t bcchan)
{
uint16_t ctrl;
uint16_t cmd1, cmd2;
uint16_t status1, status2;
uint16_t branchblock;
uint32_t timerus;
uint16_t *dataptr = NULL;
uint16_t rxdatablock[32];
uint16_t rxwordcnt = RTBC_WORDCNT;
int32_t i;
check_status(naibrd_SUM1553_BC_ReadCmdBlock(cardIndex,module,bcchan,BLOCKB,&ctrl,&cmd1,&cmd2,dataptr,&status1,&status2,&branchblock,&timerus));
if ((ctrl & NAI_SUM1553_BC_CNTL_BAME) == 0)
{
/* Read the data from the RT */
naibrd_SUM1553_BC_ReadDataBlock(cardIndex,module,bcchan,BLOCKB,rxdatablock);
printf ("Status1=%04X Status2=%04X WordCnt = %d: Data=", status1, status2, rxwordcnt);
for (i=0; i < rxwordcnt; i++)
{
if (i != 0)
printf (",");
printf ("%04X", rxdatablock[i]);
}
printf("\n");
}
}
/**************************************************************************************************************/
/**
<summary>
Update_SUM1553_BCSAData changes the data that is sent in the BC-RT messages sent to the "DEF_RT_ADDR"
RT Address and "DEF_RT_SUBADDR" and "DEF_RT_SUBADDR+1" Subaddresses.
</summary>
*/
/**************************************************************************************************************/
static void Update_SUM1553_BCSAData(int32_t cardIndex, int32_t module, int32_t bcchan, uint8_t increment)
{
int32_t wordcnt = 32;
uint8_t msb, lsb;
int32_t i;
msb = (uint8_t)(0xA0 | (increment & 0x0F)); /* upper byte (subaddress=upper 4 bits | increment=lower 4 bits)) */
lsb = 0;
for (i = 0; i < wordcnt; i++)
{
datablock[BLOCKA][i] = (msb << 8) | (uint8_t)(lsb + i); /* incremental data */
}
check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKA,datablock[BLOCKA]));
msb = (uint8_t)(0xC0 | (increment & 0x0F)); /* upper byte (subaddress=upper 4 bits | increment=lower 4 bits)) */
lsb = 0;
for (i = 0; i < wordcnt; i++)
{
datablock[BLOCKC][i] = (msb << 8) | (uint8_t)(lsb + i); /* incremental data */
}
check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKC,datablock[BLOCKC]));
}