M1553 ModeCode TxBITWord
Edit this on GitLab
M1553 ModeCode TxBITWord Sample Application (SSK 1.x)
Overview
The M1553 ModeCode TxBITWord sample application demonstrates how to configure a MIL-STD-1553 Bus Controller (BC) and send a "Transmit BIT Word" mode code command (mode code 0x13) to a Remote Terminal (RT) using the NAI Software Support Kit (SSK 1.x). The Transmit BIT Word mode code requests the RT to return its Built-In Test (BIT) status word. The RT responds with a status word and a single data word containing its BIT results, allowing the BC to verify the health of the RT without interrupting normal data transfers.
This is a single-shot sample — it configures the BC, sends the mode code message once, decodes the response, and exits. There is no send loop. This makes it a straightforward reference for any application that needs to issue mode code commands to RTs.
This sample supports the following 1553 module types:
-
FT0 through FTF — 4-channel MIL-STD-1553 modules
-
FTJ / FTK — 2-channel MIL-STD-1760 modules
-
Combination modules CM1, CM5, and CM8
The application detects the installed module variant at runtime. IsFTx1553() identifies FT-series modules (4 channels) and IsFTx1760() identifies FTJ/FTK modules (2 channels), so the correct maximum channel count is set automatically.
For detailed 1553 protocol specifications and mode code definitions, see the FTA-FTF Manual. For FTJ/FTK specifics, see the FTJ-FTK Manual.
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with a 1553 module installed (FT0-FTF, FTJ/FTK, or a combination module with 1553 functionality).
-
An RT at address 1 that supports the Transmit BIT Word mode code (0x13).
-
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_ModeCode_TxBITWord executable from your build output directory. On startup the application looks for a configuration file (default_1553_ModeCode_TransmitBITWord.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 prompts for a channel, logical device number, bus, and software override setting, then sends the mode code message and displays the response.
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_ModeCode_TransmitBITWord.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. -
Query for a channel number within the selected module.
The mode code value 0x13 (Transmit BIT Word) is hardcoded in main() and passed to the run function:
uint16_t modeTransmitBITWord = 0x13;
#if defined (__VXWORKS__)
int32_t M1553_ModeCode_TxBITWord(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
uint16_t modeTransmitBITWord = 0x13;
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_ModeCode_TxBITWord(cardIndex, module, moduleID, modeTransmitBITWord);
}
}
}
printf("\nType Q to quit or Enter key to restart application:\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
naiapp_access_CloseAllOpenCards();
return 0;
}
|
Important
|
Common Connection Errors
|
Program Structure
The application is organized into three functions:
-
main()— standard SSK 1.x startup: board menu, card/module selection, passes the hardcoded mode code value to the run function. -
Run_M1553_ModeCode_TxBITWord()— detects the module type. ForIsFTx1553()modules, allows up to 4 channels. ForIsFTx1760()modules (FTJ/FTK), allows up to 2 channels. Queries for a channel and callsRunSendModeCodeMessage(). -
RunSendModeCodeMessage()— performs the full BC workflow: opens the device, initializes as BC, creates the mode code message, builds the frame hierarchy, executes once, and decodes the response.
static bool_t Run_M1553_ModeCode_TxBITWord(int32_t cardIndex, int32_t module, uint32_t modid, uint16_t wModeCommand)
{
bool_t bQuit = FALSE;
int32_t channel;
int32_t MaxChannel = 4;
if (IsFTx1553(modid))
{
MaxChannel = 4;
bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_M1553_CHANNEL, &channel);
if (!bQuit)
bQuit = RunSendModeCodeMessage(cardIndex, module, channel, modid, wModeCommand);
}
else if (IsFTx1760(modid))
{
MaxChannel = 2;
bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_M1553_CHANNEL, &channel);
if (!bQuit)
bQuit = RunSendModeCodeMessage(cardIndex, module, channel, modid, wModeCommand);
}
else
printf("\nThis module does not support 1553 functionality.\n");
return bQuit;
}
The sample defines these constants:
#define MSG2 1 /* Message ID for the mode code */
#define OP3 1 /* Execute message opcode */
#define OP4 2 /* Call subroutine opcode */
#define MNR2 1 /* Minor frame ID */
#define MJR1 2 /* Major frame ID */
#define DBLK2 1 /* Data block for mode code response */
#define RT_ADDRESS 1 /* Target RT address */
#define WORDCOUNT 11 /* Word count for data block allocation */
Opening and Initializing the 1553 Channel
To configure a channel as a Bus Controller, call naibrd_1553_Open() to associate the hardware channel with a logical device number, then naibrd_1553_Initialize() in NAI_1553_MODE_BC mode.
/* Open 1553 Device */
status = naibrd_1553_Open(cardIndex, module, channel, devnum);
/* Software override for BC_DISABLE and M1760 pins */
if (bSoftware)
{
naibrd_1553_WriteAuxReg(devnum, 0x2, 0xA000);
}
else
{
naibrd_1553_WriteAuxReg(devnum, 0x2, 0x0000);
}
/* Reset Device */
naibrd_1553_WriteAuxReg(devnum, 0x1, 0x1);
Sleep(100);
naibrd_1553_WriteAuxReg(devnum, 0x1, 0x0);
/* Initialize as BC */
status = naibrd_1553_Initialize(devnum, NAI_1553_ACCESS_CARD, NAI_1553_MODE_BC, 0, 0, 0);
The software override (0xA000 written to auxiliary register 0x2) allows the BC to operate even when the external BC_DISABLE and M1760 hardware pins are not driven high. In production, these pins should be properly wired, and the software override should be disabled.
The device reset via auxiliary register 0x1 clears any previous state before initialization. A platform-specific delay (100 ms on Windows, taskDelay(1) on VxWorks, usleep(100000) on Linux) is required between asserting and deasserting the reset.
Mode Code Message Creation
With the BC initialized, create a data block to receive the BIT word response, then create the mode code message:
/* Create data block for mode code response */
status = naibrd_1553_BcDataBlockCreate(devnum, DBLK2, WORDCOUNT, NULL, 0);
/* Create Transmit BIT Word mode code message */
status = naibrd_1553_BcMessageCreateMode(devnum, MSG2, DBLK2, RT_ADDRESS, NAI_1553_CMD_TX, wModeCommand, 100, usBus);
To create a mode code message, call naibrd_1553_BcMessageCreateMode() with these parameters:
-
MSG2(1) — a unique message ID for this mode code. -
DBLK2(1) — the data block ID where the RT’s response data will be stored. -
RT_ADDRESS(1) — the target Remote Terminal address. -
NAI_1553_CMD_TX— specifies this is a transmit mode code. The RT will transmit data back to the BC (the BIT word). -
wModeCommand(0x13) — the specific mode code: Transmit BIT Word. -
100— gap time in 0.1 ms units (10 ms gap before the next message in the frame). -
usBus— bus selection (Bus A or Bus B), chosen interactively by the user.
|
Important
|
Common Errors
|
Building and Executing the Frame Hierarchy
The standard frame hierarchy is built and the BC is started for a single iteration:
/* Create Execute Message opcode */
status = naibrd_1553_BcCommandCreate(devnum, OP3,
NAI_1553_OPCODE_EXECUTE_MESSAGE, NAI_1553_OPCODE_COND_ALWAYS, MSG2, 0, 0);
/* Create Call Subroutine opcode */
status = naibrd_1553_BcCommandCreate(devnum, OP4,
NAI_1553_OPCODE_CALL_SUBROUTINE, NAI_1553_OPCODE_COND_ALWAYS, MNR2, 0, 0);
/* Create Minor Frame containing the mode code message */
aOpCodes[0] = OP3;
status = naibrd_1553_BcFrameCreate(devnum, MNR2, NAI_1553_BC_FRAME_MINOR, aOpCodes, 1, 0, 0);
/* Create Major Frame */
aOpCodes[0] = OP4;
status = naibrd_1553_BcFrameCreate(devnum, MJR1, NAI_1553_BC_FRAME_MAJOR, aOpCodes, 1, 1000, 0);
/* Start BC for one major frame iteration */
status = naibrd_1553_BcStart(devnum, MJR1, 1);
/* Allow time for execution */
nai_msDelay(200);
/* Stop BC */
status = naibrd_1553_BcStop(devnum);
The second parameter to naibrd_1553_BcStart() is the major frame ID, and the third parameter (1) specifies the number of major frame iterations. Since this is a single-shot operation, only one iteration is needed.
Decoding the BIT Word Response
After execution, read the decoded message to extract the BIT word response from the RT:
status = naibrd_1553_BcMessageGetByIdDecoded(devnum, MSG2, &DecodedMsgStruct, 1);
if (status > 0)
{
printf("Control Word: 0x%04X\n", DecodedMsgStruct.wBcControlWord);
printf("Command Word: 0x%04X\n", DecodedMsgStruct.wCommandWord1);
printf("Block Status: 0x%04X\n", DecodedMsgStruct.wBlockStatus);
printf("Time Tag: 0x%04X\n", DecodedMsgStruct.wTimeTag);
printf("Word Count: 0x%04X\n", DecodedMsgStruct.wDataWordCount);
printf("RT Status Word: 0x%04X\n", DecodedMsgStruct.wStatus1);
printf("Data:");
for (i = 0; i < DecodedMsgStruct.wDataWordCount; i++)
{
if (i % 8 == 0)
{
printf("\n");
}
printf("0x%04X ", DecodedMsgStruct.waData[i]);
}
printf("\n\n");
}
A positive return from naibrd_1553_BcMessageGetByIdDecoded() indicates a message was decoded. A negative return indicates an error. Zero means no message was found.
The waData[0] field contains the BIT word returned by the RT. The interpretation of individual bits within the BIT word is RT-specific — consult the RT’s documentation for the meaning of each bit. For a Transmit BIT Word mode code, the RT typically returns a single data word summarizing its self-test results.
Note that this sample does not call naibrd_1553_Free() before returning — the function returns TRUE directly after decoding. In your own application, always call naibrd_1553_Free() to release the device before exiting.
|
Important
|
Common Errors
|
Troubleshooting Reference
|
Note
|
This table summarizes errors covered in preceding sections. Consult the FTA-FTF Manual for hardware-specific diagnostics. For FTJ/FTK modules, see the FTJ-FTK Manual. |
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
|
Channel already open, invalid card/module/channel index |
Verify indices, ensure no other application holds the channel |
|
Device not reset, invalid mode flags |
Ensure device reset sequence completed, verify mode parameter |
Module not recognized as 1553 |
Selected module is not an FT-series, FTJ/FTK, or CM with 1553 |
Verify the module type using the board menu. Both |
Mode code message creation fails |
Invalid RT address, data block not created |
Check RT address range (0-30), create data block before message |
|
Incomplete frame hierarchy, device not initialized as BC |
Verify all opcodes, minor frame, and major frame are created |
No response from RT |
RT not on bus, bus wiring issue, wrong bus (A/B) selected |
Verify RT is at address 1, check cabling, try other bus |
RT does not support mode code |
Mode code 0x13 (Transmit BIT Word) not implemented by the target RT |
Consult the RT documentation. Try a different mode code if BIT Word is not supported. |
BIT word data empty |
RT acknowledged mode code but did not return data |
The RT may not fully implement Transmit BIT Word. Check RT documentation. |
Block status shows errors |
RT not responding, bus contention, timeout |
Check RT status word, verify bus termination, consult module manual |
Software override needed |
BC_DISABLE or M1760 pins not externally driven high |
Enable software override (aux reg 0x2 = 0xA000) for bench testing |
Full Source
Full Source — M1553_ModeCode_TxBITWord.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if defined (__VXWORKS__)
#include "taskLib.h"
#endif
/* 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"
#include "nai_1553_utils.h"
/* Common 1553 Sample Program include files */
#include "nai_1553_utils.h"
#include "BC/nai_1553_bc_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_ModeCode_TransmitBITWord.txt";
/* Function prototypes */
static bool_t Run_M1553_ModeCode_TxBITWord(int32_t cardIndex, int32_t module, uint32_t modid, uint16_t wModeCommand);
static bool_t RunSendModeCodeMessage(int32_t cardIndex, int32_t module, int32_t channel, uint32_t modid, uint16_t wModeCommand);
/* define message constants */
#define MSG2 1
/* define opcodes */
#define OP3 1
#define OP4 2
/* define frame constants */
#define MNR2 1
#define MJR1 2
/* define data block numbers */
#define DBLK2 1
#define DEF_M1553_CARD_INDEX 0
#define DEF_M1553_MODULE 1
#define DEF_M1553_CHANNEL 2
#define DEF_M1553_DEVNUM 0
#define RT_ADDRESS 1
#define RT_SUBADDRESS 2
#define WORDCOUNT 11
#if defined (__VXWORKS__)
int32_t M1553_ModeCode_TxBITWord(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
uint16_t modeTransmitBITWord = 0x13;
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_ModeCode_TxBITWord(cardIndex, module, moduleID, modeTransmitBITWord);
}
}
}
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_ModeCode_TxBITWord(int32_t cardIndex, int32_t module, uint32_t modid, uint16_t wModeCommand)
{
bool_t bQuit = FALSE;
int32_t channel;
int32_t MaxChannel = 4;
if (IsFTx1553(modid))
{
MaxChannel = 4;
bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_M1553_CHANNEL, &channel);
if (!bQuit)
{
bQuit = RunSendModeCodeMessage(cardIndex, module, channel, modid, wModeCommand);
}
}
else if (IsFTx1760(modid))
{
MaxChannel = 2;
bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_M1553_CHANNEL, &channel);
if (!bQuit)
{
bQuit = RunSendModeCodeMessage(cardIndex, module, channel, modid, wModeCommand);
}
}
else
printf("\nThis module does not support 1553 functionality.\n");
return bQuit;
}
static bool_t RunSendModeCodeMessage(int32_t cardIndex, int32_t module, int32_t channel, uint32_t modid, uint16_t wModeCommand)
{
int32_t i;
naiDecodedMessageStructure DecodedMsgStruct;
nai_1553_t status = 0;
int16_t aOpCodes[20] = { 0 };
bool_t bQuit = FALSE;
uint32_t usBus;
int16_t devnum;
bool_t bSoftware;
/* Get the Logical Device Number */
bQuit = Get1553LogicalDevNum(DEF_M1553_DEVNUM, &devnum);
if (bQuit)
{
return bQuit;
}
/* Which bus are we firing on? */
bQuit = GetBus(&usBus);
if (bQuit)
{
return bQuit;
}
bQuit = Get1553BCSoftwareOverride(TRUE, &bSoftware);
if (bQuit)
{
return bQuit;
}
/* Open 1553 Device(s) */
status = naibrd_1553_Open(cardIndex, module, channel, devnum);
if(status != 0)
{
printf("Error: naibrd_1553_Open Ch %d, status = %d", channel, status);
return TRUE;
}
if (bSoftware)
{
naibrd_1553_WriteAuxReg(devnum, 0x2, 0xA000);
}
else
{
naibrd_1553_WriteAuxReg(devnum, 0x2, 0x0000);
}
if (modid == NAI_MODULE_ID_FT8)
{
/* Simplex Enable (for NAI internal testing only, do not enable) */
/*naibrd_1553_WriteAuxReg(devnum, 0x3, 0x4000);
naibrd_1553_WriteAuxReg(devnum, 0xF, 0x0001);*/
}
/* Reset Device */
naibrd_1553_WriteAuxReg(devnum, 0x1, 0x1);
#if defined (__VXWORKS__)
taskDelay(1);
#elif defined (LINUX)
usleep(100000);
#else
Sleep(100);
#endif
naibrd_1553_WriteAuxReg(devnum, 0x1, 0x0);
/* Initialize 1553 Device(s) */
status = naibrd_1553_Initialize(devnum, NAI_1553_ACCESS_CARD,NAI_1553_MODE_BC,0,0,0);
if(status != 0)
{
printf("Error: naibrd_1553_Initialize Ch %d, status = %d", channel, status);
return TRUE;
}
status = naibrd_1553_BcDataBlockCreate(devnum, DBLK2, WORDCOUNT, NULL, 0);
if(status != 0)
{
printf("Error: naibrd_1553_BcDataBlockCreate Ch %d, status = %d", channel, status);
return TRUE;
}
/* Set up Tx Mode code message */
status = naibrd_1553_BcMessageCreateMode(devnum, MSG2, DBLK2, RT_ADDRESS, NAI_1553_CMD_TX, wModeCommand, 100, usBus);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageCreateMode status = %d", status);
return TRUE;
}
/* Create Execute Message Command */
status = naibrd_1553_BcCommandCreate(devnum, OP3, NAI_1553_OPCODE_EXECUTE_MESSAGE, NAI_1553_OPCODE_COND_ALWAYS, MSG2, 0, 0);
if (status != 0)
{
printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
return TRUE;
}
/* Create Call Subroutine Command */
status = naibrd_1553_BcCommandCreate(devnum, OP4, NAI_1553_OPCODE_CALL_SUBROUTINE, NAI_1553_OPCODE_COND_ALWAYS, MNR2, 0, 0);
if (status != 0)
{
printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
return TRUE;
}
/* Create Minor Frame */
aOpCodes[0] = OP3;
status = naibrd_1553_BcFrameCreate(devnum, MNR2, NAI_1553_BC_FRAME_MINOR, aOpCodes, 1, 0, 0);
if (status != 0)
{
printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
return TRUE;
}
/* Create Major Frame */
aOpCodes[0] = OP4;
status = naibrd_1553_BcFrameCreate(devnum,MJR1,NAI_1553_BC_FRAME_MAJOR,aOpCodes,1,1000,0);
if (status != 0)
{
printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
return TRUE;
}
/* Start BC */
status = naibrd_1553_BcStart(devnum,MJR1,1);
if (status != 0)
{
printf("Error: naibrd_1553_BcStart status = %d", status);
return TRUE;
}
/* This delay is necessary to allow the BC to run */
nai_msDelay(200);
/* Stop BC */
status = naibrd_1553_BcStop(devnum);
if (status != 0)
{
printf("Error: naibrd_1553_BcStop status = %d", status);
return TRUE;
}
/* Get Decoded Msg Structure */
status = naibrd_1553_BcMessageGetByIdDecoded(devnum, MSG2, &DecodedMsgStruct, 1);
if (status < 0)
{
printf("Error: naibrd_1553_BcMessageGetByIdDecoded status = %d", status);
return TRUE;
}
else if (status > 0)
{
printf("Control Word: 0x%04X\n", DecodedMsgStruct.wBcControlWord);
printf("Command Word: 0x%04X\n", DecodedMsgStruct.wCommandWord1);
printf("Block Status: 0x%04X\n", DecodedMsgStruct.wBlockStatus);
printf("Time Tag: 0x%04X\n", DecodedMsgStruct.wTimeTag);
printf("Word Count: 0x%04X\n", DecodedMsgStruct.wDataWordCount);
printf("RT Status Word: 0x%04X\n", DecodedMsgStruct.wStatus1);
printf("Data:");
for (i = 0; i < DecodedMsgStruct.wDataWordCount; i++)
{
if (i % 8 == 0)
{
printf("\n");
}
printf("0x%04X ", DecodedMsgStruct.waData[i]);
}
printf("\n\n");
}
return TRUE;
}