M1553 ModeCode TxLastCmdWord
Edit this on GitLab
M1553 ModeCode TxLastCmdWord
Explanation
About This Code
This application is a sample C program provided by North Atlantic Industries (NAI) to demonstrate how to interact with the embedded function modules in their Single Board Computer (SBC) using MIL-STD-1553 communication, specifically for sending messages and mode code transmission.
Libraries Included
-
stdio.h
,stdlib.h
,string.h
,time.h
: Standard C libraries for input/output, memory management, string manipulation, and time functions. -
taskLib.h
: VxWorks-specific library for task handling. -
naiapp_boardaccess_menu.h
,naiapp_boardaccess_query.h
,naiapp_boardaccess_access.h
,naiapp_boardaccess_display.h
,naiapp_boardaccess_utils.h
: NAI application-specific header files for board access functionalities. -
nai_1553_utils.h
,nai_1553_bc_utils.h
: NAI-specific header files for MIL-STD-1553 communication utilities. -
nai.h
,naibrd.h
,functions/naibrd_1553.h
: NAI-specific board and function module header files.
Constants
Configurations and definitions used throughout the program:
-
CONFIG_FILE
: Default configuration file. -
MSG1
,MSG2
,OP1
,OP2
,OP3
,OP4
,MNR1
,MNR2
,MJR
,MJR1
,DBLK1
,DBLK2
: Constants for message, opcode, minor frame, major frame, and data block numbers used in 1553 communication. -
DEF_M1553_CARD_INDEX
,DEF_M1553_MODULE
,DEF_M1553_CHANNEL
,DEF_M1553_DEVNUM
: Default settings for card index, module, channel, and device number. -
RT_ADDRESS
,RT_SUBADDRESS
: Remote Terminal (RT) address and subaddress. -
WORDCOUNT
: Number of words in a 1553 message.
Functions and Their Purpose
-
M1553_ModeCode_TxLastCmdWord
: Main function or entry point. -
Sets up and runs the 1553 communication tests.
-
Initializes the 1553 device.
-
Sends initial and mode code messages.
-
The VxWorks-specific
main
function is directly replaced by this function for VxWorks OS. -
Run_M1553_BC_SendMessage
: Sends a message to initialize the 1553 device as a Bus Controller (BC). -
Uses several API functions to set up and send the message.
-
RunSendMessage
: Sends actual messages from the Bus Controller to Remote Terminal (BC to RT). -
Invoked by
Run_M1553_BC_SendMessage
. -
Demonstrates initializing the 1553 device and sending messages using 1553 library functions.
-
RunSendModeCodeMessage
: Sends mode code messages, specifically "Transmit Last Command Word," and handles the results. -
Initializes 1553 device.
-
Sends mode code messages.
-
Retrieves and displays the status of the messages.
The functions demonstrate the following API functions from the NAI 1553 library:
1553 naibrd Library Functions
-
naibrd_1553_Free
-
naibrd_Close
1553 Communication Setup and Execution
-
naibrd_1553_Open
-
naibrd_1553_Initialize
-
naibrd_1553_BcDataBlockCreate
-
naibrd_1553_BcMessageCreateBcToRt
-
naibrd_1553_BcCommandCreate
-
naibrd_1553_BcFrameCreate
-
naibrd_1553_BcDataBlockWrite
-
naibrd_1553_BcMessageCreateMode
-
naibrd_1553_BcStart
-
naibrd_1553_BcStop
-
naibrd_1553_BcMessageGetByIdDecoded
These functions are used to open, initialize and configure the 1553 device, create data blocks, messages, commands, and frames, write data to the device, start and stop BC, and retrieve message status.
Flow of the Application
-
Initialization and Configuration:
-
The program begins execution from the
M1553_ModeCode_TxLastCmdWord
function, which handles the initial setup. -
It queries the user for board, module, and channel information.
-
-
Running the 1553 Bus Controller:
-
Run_M1553_BC_SendMessage
,RunSendMessage
, andRunSendModeCodeMessage
functions demonstrate the setup and sending of messages through the Bus Controller. -
These functions check the module compatibility, initialize devices, configure data blocks and messages, create commands, and send the messages.
-
-
User Interaction:
-
The program interacts with the user to query configurations and to decide when to quit.
-
-
Results Display:
-
The status of the messages is retrieved and displayed, showing the control word, command word, block status, time tag, word count, RT status word, and data.
-
-
Cleanup:
-
All open cards are closed, and the program terminates.
-
This sample code is an excellent demonstration of setting up and interacting with NAI’s 1553 function modules using their APIs, ensuring a smooth and efficient communication and control setup for embedded systems.
#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_RTReceive.txt";
/* Function prototypes */
static bool_t Run_M1553_BC_SendMessage(int32_t cardIndex, int32_t module, uint32_t modid);
static bool_t RunSendMessage(int32_t cardIndex, int32_t module, int32_t channel, uint32_t modid);
static bool_t RunSendModeCodeMessage(int16_t swDevice, int32_t channel, uint16_t wModeCommand, uint16_t wGapTime);
/* define message constants */
#define MSG1 1
#define MSG2 2
/* define opcodes */
#define OP1 1
#define OP2 2
#define OP3 3
#define OP4 4
/* define frame constants */
#define MNR1 1
#define MNR2 2
#define MJR 3
#define MJR1 4
/* define data block numbers */
#define DBLK1 1
#define DBLK2 2
#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
/**************************************************************************************************************/
/**
<summary>
The purpose of the M1553_ModeCode_TxLastCmdWord is to illustrate the methods to call in the naibrd
library to configure the 1553 channel as a Bus Controller. Then send out a 1553 message, and subsequently the
Mode Code, Transmit Last Command Word, message. The status word expected back from the mode Code message is the
first message's Command Word as the Data.
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
API function in the 1553 naibrd library:
- naibrd_1553_Free
API function in the naibrd library:
- naibrd_Close
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t M1553_ModeCode_TxLastCmdWord(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
int16_t devnum = 0;
uint16_t gapTime = 100;
uint16_t modeTransmitLastCommandWord = 0x12;
uint32_t channel = 1;
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))
{
/* First 1553 message */
stop = Run_M1553_BC_SendMessage(cardIndex, module, moduleID);
/* 1553 Mode Code "Transmit Last Command Word" */
RunSendModeCodeMessage(devnum, channel, modeTransmitLastCommandWord, gapTime);
}
}
}
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_M1553_BC_SendMessage initializes the 1553 device as a bus controller (BC) and sends out a message.
This routine demonstrates the following API functions in the 1553 naibrd library:
naibrd_1553_Open
naibrd_1553_Initialize
naibrd_1553_BcDataBlockCreate
naibrd_1553_BcMessageCreateBcToRt
naibrd_1553_BcCommandCreate
naibrd_1553_BcFrameCreate
naibrd_1553_BcDataBlockWrite
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_M1553_BC_SendMessage(int32_t cardIndex, int32_t module, uint32_t modid)
{
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 = RunSendMessage(cardIndex, module, channel, modid);
}
}
else
{
printf("\nThis module does not support 1553 functionality.\n");
}
return bQuit;
}
static bool_t RunSendMessage(int32_t cardIndex, int32_t module, int32_t channel, uint32_t modid)
{
int32_t i;
bool_t bQuit = FALSE;
uint32_t usBus;
nai_1553_t status;
uint16_t increment = 0;
uint16_t aData[32] = {0};
int16_t aOpCodes[20] = { 0 };
int16_t devnum;
bool_t bcToRtMsg = TRUE;
bool_t bSoftware;
/* Get the Logical Device Number */
bQuit = Get1553LogicalDevNum(DEF_M1553_DEVNUM, &devnum);
if (!bQuit)
{
/* Get Msg Direction */
bQuit = GetMsgDirection(&bcToRtMsg);
if (!bQuit)
{
/* Which bus are we firing on? */
bQuit = GetBus(&usBus);
if (!bQuit)
{
bQuit = Get1553BCSoftwareOverride(TRUE, &bSoftware);
if (!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)
{
/* Override external BC_DISABLE and M1760 (In order to configure as BC, this needs to */
/* be set if BC_DISABLE and M1760 pins are not driven high) */
naibrd_1553_WriteAuxReg(devnum, 0x2, 0xA000);
}
else
{
/* Do not override external BC_DISABLE and M1760 Inputs */
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;
}
/* Create BC Data Block */
status = naibrd_1553_BcDataBlockCreate(devnum, DBLK1, WORDCOUNT, NULL, 0);
if(status != 0)
{
printf("Error: naibrd_1553_BcDataBlockCreate Ch %d, status = %d", channel, status);
return TRUE;
}
if (bcToRtMsg)
{
/* Create BC to RT Message */
status = naibrd_1553_BcMessageCreateBcToRt(devnum, MSG1, DBLK1, RT_ADDRESS, RT_SUBADDRESS, WORDCOUNT, 0, usBus);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageCreateBcToRt status = %d", status);
return TRUE;
}
}
else
{
/* Create RT to BC Message */
status = naibrd_1553_BcMessageCreateRtToBc(devnum, MSG1, DBLK1, RT_ADDRESS, RT_SUBADDRESS, WORDCOUNT, 0, usBus);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageCreateRtToBc status = %d", status);
return TRUE;
}
}
/* Create Execute Message Command */
status = naibrd_1553_BcCommandCreate(devnum, OP1, NAI_1553_OPCODE_EXECUTE_MESSAGE, NAI_1553_OPCODE_COND_ALWAYS, MSG1, 0, 0);
if (status != 0)
{
printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
return TRUE;
}
/* Create Call Subroutine Command */
status = naibrd_1553_BcCommandCreate(devnum, OP2, NAI_1553_OPCODE_CALL_SUBROUTINE, NAI_1553_OPCODE_COND_ALWAYS, MNR1, 0, 0);
if (status != 0)
{
printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
return TRUE;
}
/* Create Minor Frame */
aOpCodes[0] = OP1;
status = naibrd_1553_BcFrameCreate(devnum, MNR1, 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] = OP2;
status = naibrd_1553_BcFrameCreate(devnum,MJR,NAI_1553_BC_FRAME_MAJOR,aOpCodes,1,1000,0);
if (status != 0)
{
printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
return TRUE;
}
/* Load BC data block with incremental data */
for (i = 0; i < WORDCOUNT; i++)
{
aData[i] = increment++;
}
status = naibrd_1553_BcDataBlockWrite(devnum, DBLK1, aData, WORDCOUNT, 0);
if (status != 0)
{
printf("Error: naibrd_1553_BcDataBlockWrite status = %d", status);
return TRUE;
}
}
}
}
}
return bQuit;
}
/**************************************************************************************************************/
/**
<summary>
RunSendModeCodeMessage initializes the 1553 device as a bus controller (BC) and sends out a message.
This routine demonstrates the following API functions in the 1553 naibrd library:
naibrd_1553_BcDataBlockCreate
naibrd_1553_BcMessageCreateMode
naibrd_1553_BcCommandCreate
naibrd_1553_BcFrameCreate
naibrd_1553_BcStart
naibrd_1553_BcStop
naibrd_1553_BcMessageGetByIdDecoded
</summary>
*/
/**************************************************************************************************************/
static bool_t RunSendModeCodeMessage(int16_t swDevice, int32_t channel, uint16_t wModeCommand, uint16_t wGapTime)
{
int32_t i;
naiDecodedMessageStructure DecodedMsgStruct;
nai_1553_t status = 0;
int16_t aOpCodes[20] = { 0 };
nai_1553_t sResult = 0;
sResult = naibrd_1553_BcDataBlockCreate(swDevice, DBLK2, WORDCOUNT, NULL, 0);
if(sResult != 0)
{
printf("Error: naibrd_1553_BcDataBlockCreate Ch %d, status = %d", channel, sResult);
return TRUE;
}
/* Set up "Transmit Last Command Word" Mode code message */
sResult = naibrd_1553_BcMessageCreateMode(swDevice, MSG2, DBLK2, RT_ADDRESS, NAI_1553_CMD_TX, wModeCommand, wGapTime,
NAI_1553_BC_CTRL_BUS_A);
/* Create Execute Message Command */
status = naibrd_1553_BcCommandCreate(swDevice, 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(swDevice, 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] = OP1;
aOpCodes[1] = OP3;
status = naibrd_1553_BcFrameCreate(swDevice, MNR2, NAI_1553_BC_FRAME_MINOR, aOpCodes, 2, 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(swDevice,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(swDevice,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(swDevice);
if (status != 0)
{
printf("Error: naibrd_1553_BcStop status = %d", status);
return TRUE;
}
/* Get Decoded Msg Structure */
status = naibrd_1553_BcMessageGetByIdDecoded(swDevice, MSG1, &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("\n\n");
}
/* Get Decoded Msg Structure */
status = naibrd_1553_BcMessageGetByIdDecoded(swDevice, 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;
}