nai 1553 bc utils
Edit this on GitLab
nai 1553 bc utils
Explanation
About
This C code sample demonstrates how to interact with North Atlantic Industries (NAI) embedded function modules using the company’s Software Support Kit (SSK). The example focuses on sending and managing 1553 Bus Controller (BC) messages. The code is modular and includes multiple functions and utility definitions to streamline the communication process. Below, we provide a walkthrough of the code components and their functions.
Included Libraries and Headers
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
These are standard C libraries for input/output operations, character type handling, general utilities, and string manipulations respectively.
#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_bc_utils.h"
#include "nai_1553_utils.h"
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_1553.h"
These are NAI-specific headers, likely part of the SSK, which include functions and utilities to handle board access and 1553 protocol operations.
Definitions and Enumerations
#define DBLK1 1
#define MSG1 1
#define OP1 1
#define OP2 2
#define MNR1 1
#define MJR 2
These are constants used as identifiers for different blocks, messages, and operations within the code.
enum M1553SendMsgMenu_commands
{
BC_QUICK_MESSAGE,
BC_CREATE_MESSAGE,
BC_SEND_FRAME,
BC_SENDMSGCMD_COUNT
};
This enumeration defines commands for the 1553 Send Message Menu.
Mode Codes
const M1553ModeCodes_t validTxModeCodeCommands[TXMODECODE_NUM_OF_VALIDCOMMANDS] = { /* Mode Codes for Transmission */ };
const M1553ModeCodes_t validRxModeCodeCommands[RXMODECODE_NUM_OF_VALIDCOMMANDS] = { /* Mode Codes for Reception */ };
These arrays store valid mode code commands for transmission and reception.
Command Structure Definition
static nai_1553_cmdtbl_type M1553_SendMsgMenuCmds[] = {
{"BCQUICK", "BC Send a Message Now", BC_QUICK_MESSAGE, BC_QuickMessage}
};
This defines available commands and their descriptions.
Main Functions
BC_SendMessages(int16_t devnum)
-
Displays a menu for BC messages.
-
Handles user input for selecting and executing commands.
BC_QuickMessage(int16_t devnum)
-
Prompts the user for data entry related to the message being sent.
-
Handles data block creation and message transmission.
-
Starts and manages the BC operations and handles potential errors gracefully.
-
Deletes created data blocks and commands after the operation.
Utility Functions
GetBus(uint32_t
usBus)*
-
Prompts the user to select the bus (A or B) for message transmission.
GetMsgDirection(bool_t
bcToRt), GetMsgTypeAndCheckForQuit(M1553MsgType_t* msgType)
, AskAndCheckForValidModeCodeAndCheckForQuit(M1553MsgDirectionForModeCode_t modeCodeDirection, M1553ModeCodes_t* modeCodeCommand, bool_t* isValidModeCodeCommand)
*
-
Prompts the user for message direction, type, and mode code commands, respectively.
Workflow Summary
-
Menu Display: Presents the user with BC commands.
-
User Input Handling: Waits for user input to execute corresponding functions.
-
Message Sending: Prompts additional data entries as needed.
-
Data Block and Message Management: Creates, writes, and deletes data blocks and messages.
-
Error Handling: Provides feedback to the user if any operation fails.
-
Cleanup: Ensures that all resources are properly deleted after use.
Conclusion
This code sample is a structured approach to managing 1553 communication using NAI’s embedded modules. The functions are designed to prompt user interaction, execute commands, and handle operations cleanly, facilitating efficient and error-free BC message transmission.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.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"
#include "nai_1553_bc_utils.h"
#include "nai_1553_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_1553.h"
#define DBLK1 1
#define MSG1 1
#define OP1 1
#define OP2 2
#define MNR1 1
#define MJR 2
enum M1553SendMsgMenu_commands
{
BC_QUICK_MESSAGE,
BC_CREATE_MESSAGE,
BC_SEND_FRAME,
BC_SENDMSGCMD_COUNT
};
const M1553ModeCodes_t validTxModeCodeCommands[TXMODECODE_NUM_OF_VALIDCOMMANDS] = { DynamicBusControl_0x00, Syncronize_0x01, TransmitStatusWord_0x02,
InitiateSelfTest_0x03, TransmitterShutdown_0x04, OverrideTransmitterShutdown_0x05, InhibitTerminalFlag_0x06,
OverrideInhibitTerminalFlag_0x07, ResetRemoteTerminal_0x08, TransmitVectorWord_0x10, TransmitLastCommandWord_0x12,
TransmitBITWord_0x13 };
const M1553ModeCodes_t validRxModeCodeCommands[RXMODECODE_NUM_OF_VALIDCOMMANDS] = { SyncronizeWdata_0x11, SelectedTransmitterShutDown_0x14,
Ovveride_SelectedTransmitter_Shoutdown_0x15 };
static nai_1553_cmdtbl_type M1553_SendMsgMenuCmds[] = {
{"BCQUICK ", "BC Send a Message Now ", BC_QUICK_MESSAGE, BC_QuickMessage }
};
bool_t BC_SendMessages(int16_t devnum)
{
bool_t bQuit = FALSE;
bool_t bContinue = TRUE, bCmdFound;
int32_t cmd;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
while (bContinue)
{
/* Display BC Menu Options */
Load1553MenuCommands(BC_SENDMSGCMD_COUNT, M1553_SendMsgMenuCmds);
Display1553MenuCommands((int8_t *)"************************\n * *\n * BC Messages Menu *\n * *\n ************************");
printf("\nType Menu command or %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
bCmdFound = Get1553CmdNum(inputResponseCnt, inputBuffer, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case BC_QUICK_MESSAGE:
case BC_CREATE_MESSAGE:
case BC_SEND_FRAME:
M1553_SendMsgMenuCmds[cmd].func(devnum);
break;
default:
printf("Invalid command entered");
break;
}
}
}
}
else
bContinue = FALSE;
}
return bQuit;
}
bool_t BC_QuickMessage(int16_t devnum)
{
bool_t bQuit = FALSE;
bool_t bTxMsg = FALSE;
uint32_t usBus;
int32_t nRTaddress, nSubaddress, nWordCount;
nai_1553_t status;
int32_t i;
uint16_t wapBuffer[32];
int16_t aOpCodes[20] = { 0 };
naiDecodedMessageStructure DecodedMsgStruct;
/* Ask user what bus we are sending on */
bQuit = GetBus(&usBus);
if (!bQuit)
{
/* Ask user what the RT address is */
bQuit = GetRTAddress(&nRTaddress);
if (!bQuit)
{
/* Ask user if it is Tx or Rx message */
bQuit = GetTxRx(&bTxMsg);
if (!bQuit)
{
/* Ask user what subaddress the message is sent to */
bQuit = GetSubaddress(&nSubaddress);
if (!bQuit)
{
/* Ask user what the data word count is */
bQuit = GetWordCount(&nWordCount);
if (!bQuit)
{
/*** Send a message ***/
/* Create BC Data Block */
status = naibrd_1553_BcDataBlockCreate(devnum, DBLK1, 32, NULL, 0);
if(status != 0)
{
printf("Error: naibrd_1553_BcDataBlockCreate Status = %d", status);
return bQuit;
}
/* Load data block with incremental data */
for (i = 0; i < 32; i++)
{
wapBuffer[i] = (uint16_t)i;
}
status = naibrd_1553_BcDataBlockWrite(devnum, DBLK1, wapBuffer, 32, 0);
if (status != 0)
{
printf("Error: naibrd_1553_BcDataBlockWrite status = %d", status);
return bQuit;
}
if (bTxMsg)
{
/* Create RT to BC message */
status = naibrd_1553_BcMessageCreateRtToBc(devnum, MSG1, DBLK1, (uint16_t)nRTaddress, (uint16_t)nSubaddress, 32, 0, usBus);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageCreateRtToBc status = %d", status);
return bQuit;
}
}
else
{
/* Create BC to RT message */
status = naibrd_1553_BcMessageCreateBcToRt(devnum, MSG1, DBLK1, (uint16_t)nRTaddress, (uint16_t)nSubaddress, 32, 0, usBus);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageCreateBcToRt status = %d", status);
return bQuit;
}
}
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 bQuit;
}
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 bQuit;
}
/* 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 bQuit;
}
/* 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 bQuit;
}
/* Start BC */
status = naibrd_1553_BcStart(devnum,MJR,1);
if (status != 0)
{
printf("Error: naibrd_1553_BcStart status = %d", status);
return bQuit;
}
#if defined (__VXWORKS__)
taskDelay(sysClkRateGet() * 1);
#elif defined (LINUX)
usleep(1000*1000);
#else
Sleep(1 * 1000);
#endif
/* Read Status Response */
status = naibrd_1553_BcMessageGetByIdDecoded(devnum,MSG1,&DecodedMsgStruct,1);
if (status < 0)
{
printf("Error: naibrd_1553_BcMessageGetByIdDecoded status = %d", status);
return bQuit;
}
printf("\nStatus: 0x%04X\n", DecodedMsgStruct.wStatus1);
/* Read Data Block, if Tx message was sent */
if (bTxMsg)
{
status = naibrd_1553_BcDataBlockRead(devnum,DBLK1,wapBuffer,32,0);
if (status != 0)
{
printf("Error: naibrd_1553_BcDataBlockRead status = %d", status);
return bQuit;
}
printf("\nData:\n");
for (i = 0; i < DecodedMsgStruct.wDataWordCount; i++)
{
printf("0x%04X ", DecodedMsgStruct.waData[i]);
}
printf("\n\n");
}
/* Stop BC */
status = naibrd_1553_BcStop(devnum);
if (status != 0)
{
printf("Error: naibrd_1553_BcStop status = %d", status);
return bQuit;
}
/* Delete Major Frame */
status = naibrd_1553_BcFrameDelete(devnum,MJR);
if (status != 0)
{
printf("Error: naibrd_1553_BcFrameDelete MJR status = %d", status);
return bQuit;
}
/* Delete Minor Frame */
aOpCodes[0] = OP1;
status = naibrd_1553_BcFrameDelete(devnum, MNR1);
if (status != 0)
{
printf("Error: naibrd_1553_BcFrameDelete MNR1 status = %d", status);
return bQuit;
}
status = naibrd_1553_BcCommandDelete(devnum, OP2);
if (status != 0)
{
printf("Error: naibrd_1553_BcCommandDelete OP2 status = %d", status);
return bQuit;
}
status = naibrd_1553_BcCommandDelete(devnum, OP1);
if (status != 0)
{
printf("Error: naibrd_1553_BcCommandDelete OP1 status = %d", status);
return bQuit;
}
status = naibrd_1553_BcMessageDelete(devnum, MSG1);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageDelete status = %d", status);
return bQuit;
}
/* Delete BC Data Block */
status = naibrd_1553_BcDataBlockDelete(devnum, DBLK1);
if(status != 0)
{
printf("Error: naibrd_1553_BcDataBlockDelete Status = %d", status);
return bQuit;
}
}
}
}
}
}
return bQuit;
}
bool_t GetBus(uint32_t* usBus)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
while (bContinue)
{
printf("\nWhich bus are we firing on (A or B) [default = A]? ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
*usBus = NAI_1553_BC_CTRL_BUS_A;
if (inputResponseCnt == 0)
{
*usBus = NAI_1553_BC_CTRL_BUS_A;
bContinue = FALSE;
}
if (inputResponseCnt > 0)
{
if (toupper(inputBuffer[0]) == 'B')
{
*usBus = NAI_1553_BC_CTRL_BUS_B;
bContinue = FALSE;
}
else if (toupper(inputBuffer[0]) == 'A')
{
*usBus = NAI_1553_BC_CTRL_BUS_A;
bContinue = FALSE;
}
else
{
printf("\nInvalid command entered.\n\n");
}
}
}
else
bContinue = FALSE;
}
return bQuit;
}
bool_t GetMsgDirection(bool_t* bcToRt)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
while (bContinue)
{
printf("\nIs the message BC to RT (n is RT to BC) [default = y]? ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
*bcToRt = TRUE;
if (inputResponseCnt == 0)
{
*bcToRt = TRUE;
bContinue = FALSE;
}
else if (inputResponseCnt > 0)
{
if (toupper(inputBuffer[0]) == 'Y')
{
*bcToRt = TRUE;
bContinue = FALSE;
}
else if (toupper(inputBuffer[0]) == 'N')
{
*bcToRt = FALSE;
bContinue = FALSE;
}
else
{
printf("\nInvalid command entered.\n\n");
}
}
}
else
bContinue = FALSE;
}
return bQuit;
}
bool_t GetMsgTypeAndCheckForQuit(M1553MsgType_t* msgType)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
while (bContinue)
{
printf("\nChoose message type:\n");
printf("press 1 for BC to RT\n");
printf("press 2 for RT to BC\n");
printf("press 3 for RT to RT\n");
printf("press 4 for Tx Mode Code\n");
printf("press 5 for Rx Mode Code\n");
printf("[default = 1] ?\n");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt == 0)
{
*msgType = M1553_MSGTYPE_BCTORT;
bContinue = FALSE;
}
else if (inputResponseCnt > 0)
{
if ((atoi((char *)inputBuffer) < 1) || (atoi((char *)inputBuffer) > 5))
{
printf("\nInvalid command entered.\n\n");
}
else if (inputBuffer[0] == '1')
{
*msgType = M1553_MSGTYPE_BCTORT;
bContinue = FALSE;
}
else if (inputBuffer[0] == '2')
{
*msgType = M1553_MSGTYPE_RTTOBC;
bContinue = FALSE;
}
else if (inputBuffer[0] == '3')
{
*msgType = M1553_MSGTYPE_RTTORT;
bContinue = FALSE;
}
else if (inputBuffer[0] == '4')
{
*msgType = M1553_MSGTYPE_MODECODE_TX;
bContinue = FALSE;
}
else if (inputBuffer[0] == '5')
{
*msgType = M1553_MSGTYPE_MODECODE_RX;
bContinue = FALSE;
}
else
{
printf("\nInvalid command entered.\n\n");
}
}
}
else
bContinue = FALSE;
}
return bQuit;
}
bool_t AskAndCheckForValidModeCodeAndCheckForQuit(M1553MsgDirectionForModeCode_t modeCodeDirection, M1553ModeCodes_t* modeCodeCommand, bool_t* isValidModeCodeCommand)
{
uint8_t i;
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
*isValidModeCodeCommand = FALSE;
while (!(*isValidModeCodeCommand))
{
printf("\nPlease choose the desired Mode Code number in decimal:\n(0 - 8, 16, 18 - 19 for Tx) or (17, 20 - 21 for Rx)\n");
(modeCodeDirection == M1553_MSGTYPE_MODECODE_DIRECTION_TX) ? (printf("[default] = %d\n", DynamicBusControl_0x00)) : (printf("[default] = %d\n", SyncronizeWdata_0x11));
printf("\nOr type Q to quit\n");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt)
{
*modeCodeCommand = (M1553ModeCodes_t)atoi((char *)inputBuffer);
/* Check user input for a valid integer. This is needed because atoi will return 0 for a non-integer, and 0 is a valid mode code */
for (i = 0; i < inputResponseCnt; i++)
{
if (inputBuffer[i] != ' ')
{
if (isdigit(inputBuffer[i]) == 0)
{
*isValidModeCodeCommand = FALSE;
printf((modeCodeDirection == M1553_MSGTYPE_MODECODE_DIRECTION_TX) ? ("\n\nInvalid Tx Mode Code Command\n\n") :
("\n\nInvalid Rx Mode Code Command\n\n"));
break;
}
else
*isValidModeCodeCommand = TRUE;
}
else
*isValidModeCodeCommand = TRUE;
}
if (*isValidModeCodeCommand)
{
if (((atoi((char *)inputBuffer) < (int)DynamicBusControl_0x00) || (atoi((char *)inputBuffer) > (int)ResetRemoteTerminal_0x08)) &&
((atoi((char *)inputBuffer) < (int)TransmitVectorWord_0x10) || (atoi((char *)inputBuffer) > (int)Ovveride_SelectedTransmitter_Shoutdown_0x15)))
*isValidModeCodeCommand = FALSE;
else if (modeCodeDirection == (uint16_t)M1553_MSGTYPE_MODECODE_DIRECTION_TX)
{
for (i = 0; i < TXMODECODE_NUM_OF_VALIDCOMMANDS; i++)
{
if (*modeCodeCommand == validTxModeCodeCommands[i])
{
*isValidModeCodeCommand = TRUE;
break;
}
else
*isValidModeCodeCommand = FALSE;
}
}
else if (modeCodeDirection == M1553_MSGTYPE_MODECODE_DIRECTION_RX)
{
for (i = 0; i < RXMODECODE_NUM_OF_VALIDCOMMANDS; i++)
{
if (*modeCodeCommand == (uint16_t)validRxModeCodeCommands[i])
{
*isValidModeCodeCommand = TRUE;
break;
}
else
*isValidModeCodeCommand = FALSE;
}
}
else
{
*isValidModeCodeCommand = FALSE;
break;
}
if (*isValidModeCodeCommand)
break;
else
printf((modeCodeDirection == M1553_MSGTYPE_MODECODE_DIRECTION_TX) ? ("\n\nInvalid Tx Mode Code Command\n\n") :
("\n\nInvalid Rx Mode Code Command\n\n"));
}
}
else
{
if (modeCodeDirection == (uint16_t)M1553_MSGTYPE_MODECODE_DIRECTION_TX)
{
*modeCodeCommand = DynamicBusControl_0x00;
*isValidModeCodeCommand = TRUE;
break;
}
else
{
*modeCodeCommand = SyncronizeWdata_0x11;
*isValidModeCodeCommand = TRUE;
break;
}
}
}
else
{
break;
}
}
return bQuit;
}