M1553 BC SendMessage FIFO
Edit this on GitLab
M1553 BC SendMessage FIFO
Explanation
Code Explanation for North Atlantic Industries Sample Application in C
This C code is designed to interact with North Atlantic Industries' embedded function modules, specifically aiming to configure a 1553 channel as a Bus Controller (BC) and send a 1553 message decoded using FIFO mode. Below is a detailed explanation of the application’s structure, its functions, and key components.
Header Files
-
Standard Libraries:
These libraries provide basic functionalities like input/output operations, memory management, string handling, and time functionalities.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h>
-
Conditional Library:
c #if defined (VXWORKS) #include "taskLib.h" #endif
taskLib.h
is included if the VxWorks OS is being used. This library provides task control functionalities. -
NAI Specific Libraries: These libraries are specific to North Atlantic Industries' hardware and provide functions for board access, display, utilities, and 1553 protocol operations: ```c #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" #include "BC/nai_1553_bc_utils.h"
#include "nai.h" #include "naibrd.h" #include "functions/naibrd_1553.h" #include "functions/naibrd_1553_assisted.h" ```
Constant Definitions
-
Configuration File: Specifies the default configuration file for the 1553 BC operation.
c static const int8_t *CONFIG_FILE = (int8_t *)"default_1553BC_SendMessage_FIFO.txt";
-
Function Prototypes:
c static bool_t Run_M1553_BC_SendMessage_FIFO(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);
-
Message and Opcode Constants: These are placeholders for defining specific messages, opcodes, frames, and data block numbers used in the 1553 protocol operation.
c #define MSG1 1 #define OP1 1 #define OP2 2 #define MNR1 1 #define MJR 2 #define DBLK1 1 #define DBLK2 2
-
Default Configuration Values: These define default values for card, module, channel, device number, etc. ```c #define DEF_M1553_CARD_INDEX 0 #define DEF_M1553_MODULE 1 #define DEF_M1553_CHANNEL 1 #define DEF_M1553_DEVNUM 1
#define RT_ADDRESS 1 #define RT_SUBADDRESS 2
#define RT_ADDRESS_2 2
#define WORDCOUNT 32 ```
Main Function
Based on the operating system, the entry point function is either main
or M1553_BC_SendMessage_FIFO
:
#if defined (__VXWORKS__)
int32_t M1553_BC_SendMessage_FIFO(void)
#else
int32_t main(void)
#endif
This function initiates the 1553 BC message sending process. It interacts with the user to query card and module indices, configure the 1553 device, and handle user commands.
Key Steps in Main Function:
-
Run Board Menu:
This function likely sets up the initial configuration for the board based on the provided config file.c if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
-
Query User for Card and Module Indices:
c stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex); stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
-
Run Message Send Operation:
c Run_M1553_BC_SendMessage_FIFO(cardIndex, module, moduleID);
-
Check User Input for Quitting:
c printf("\nType Q to quit or Enter key to restart application:\n"); stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
-
Close Open Cards:
c naiapp_access_CloseAllOpenCards();
Run_M1553_BC_SendMessage_FIFO Function
This function initializes the 1553 device as a bus controller in FIFO mode and sends a message:
static bool_t Run_M1553_BC_SendMessage_FIFO(int32_t cardIndex, int32_t module, uint32_t modid)
{
...
}
Key actions include:
1. Check if Module Supports 1553:
c
if (IsFTx1553(modid))
-
Query User for Channel:
c bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_M1553_CHANNEL, &channel);
-
Run Message Sending Process:
c bQuit = RunSendMessage(cardIndex, module, channel, modid);
RunSendMessage Function
This function handles the detailed process of sending the 1553 message:
static bool_t RunSendMessage(int32_t cardIndex, int32_t module, int32_t channel, uint32_t modid)
{
...
}
Key actions include:
1. Get Logical Device Number and Message Type:
c
bQuit = Get1553LogicalDevNum(DEF_M1553_DEVNUM, &devnum);
bQuit = GetMsgTypeAndCheckForQuit(&msgType);
-
Open and Initialize 1553 Device:
c status = naibrd_1553_Open(cardIndex, module, channel, devnum); status = naibrd_1553_Initialize(devnum, NAI_1553_ACCESS_CARD, NAI_1553_MODE_BC | NAI_1553_MESSAGE_FIFO_MODE, 0, 0, 0);
-
Create and Send Message:
c status = naibrd_1553_BcMessageCreateBcToRt(devnum, MSG1, DBLK1, RT_ADDRESS, RT_SUBADDRESS, WORDCOUNT, 1, usBus);
-
Start and Stop BC, Decode Messages:
c status = naibrd_1553_BcStart(devnum, MJR, 1); status = naibrd_1553_ReadMsgFIFO(devnum, fifoCount, fifoData); status = naibrd_1553_DecodeFIFOMsg(fifoData, currBlockIndex, &nextBlockIndex, &msgStruct);
-
Close and Free 1553 Device:
c status = naibrd_1553_Free(devnum);
Summary
The provided C code is a comprehensive application that sets up and uses NAI’s 1553 Bus Controller functionalities with FIFO mode to send and receive messages. It leverages multiple NAI-specific libraries and functions to handle the configuration, user interaction, and message processing.
#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"
/* 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"
#include "functions/naibrd_1553_assisted.h"
static const int8_t *CONFIG_FILE = (int8_t *)"default_1553BC_SendMessage_FIFO.txt";
/* Function prototypes */
static bool_t Run_M1553_BC_SendMessage_FIFO(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);
/* define message constants */
#define MSG1 1
/* define opcodes */
#define OP1 1
#define OP2 2
/* define frame constants */
#define MNR1 1
#define MJR 2
/* 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 1
#define DEF_M1553_DEVNUM 1
#define RT_ADDRESS 1
#define RT_SUBADDRESS 2
#define RT_ADDRESS_2 2
#define WORDCOUNT 32
/**************************************************************************************************************/
/**
<summary>
The purpose of the M1553_BC_SendMessage_FIFO is to illustrate the methods to call in the naibrd library to configure
the 1553 channel as a Bus Controller and to send a 1553 message. The message will be decoded using FIFO mode.
Note: FIFO mode is available for the FTA, FTB, FTC, FTD, and FTF only.
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
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t M1553_BC_SendMessage_FIFO(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_M1553_BC_SendMessage_FIFO(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_M1553_BC_SendMessage_FIFO initializes the 1553 device as a bus controller (BC),
FIFO mode NAI_1553_MESSAGE_FIFO_MODE, 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_BcConfigureMessageGapTimerEnable
naibrd_1553_BcDataBlockCreate
naibrd_1553_BcMessageCreateBcToRt
naibrd_1553_BcMessageCreateRtToBc
naibrd_1553_BcMessageCreateMode
naibrd_1553_BcMessageCreateRtToRt
naibrd_1553_BcCommandCreate
naibrd_1553_BcFrameCreate
naibrd_1553_BcDataBlockWrite
naibrd_1553_ClearMsgFIFO
naibrd_1553_BcStart
naibrd_1553_BcStop
naibrd_1553_GetMsgFIFOCount
naibrd_1553_ReadMsgFIFO
naibrd_1553_DecodeFIFOMsg
naibrd_1553_GetMsgFIFOFullStatus
naibrd_1553_Free
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_M1553_BC_SendMessage_FIFO(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 };
bool_t bContinue = TRUE;
int16_t devnum;
bool_t isValidModeCode;
M1553MsgType_t msgType;
naiDecodedMessageStructureFIFO msgStruct;
bool_t bSoftware;
M1553ModeCodes_t modeCommand = (M1553ModeCodes_t)0;
uint32_t fifoCount = 0;
uint32_t fifoData[1024];
int32_t currBlockIndex = 0, nextBlockIndex = 0;
bool_t FIFIOfullStatusBit;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
/* Get the Logical Device Number */
bQuit = Get1553LogicalDevNum(DEF_M1553_DEVNUM, &devnum);
if (!bQuit)
{
/* Get Msg Direction */
bQuit = GetMsgTypeAndCheckForQuit(&msgType);
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 ((msgType == M1553_MSGTYPE_MODECODE_TX) || (msgType == M1553_MSGTYPE_MODECODE_RX))
{
do
{
bQuit = AskAndCheckForValidModeCodeAndCheckForQuit((msgType == M1553_MSGTYPE_MODECODE_TX) ?
M1553_MSGTYPE_MODECODE_DIRECTION_TX : M1553_MSGTYPE_MODECODE_DIRECTION_RX, &modeCommand, &isValidModeCode);
} while ((!bQuit) && (!isValidModeCode));
}
if (!bQuit)
{
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 | NAI_1553_MESSAGE_FIFO_MODE, 0, 0, 0);
if (status != 0)
{
printf("Error: naibrd_1553_Initialize Ch %d, status = %d", channel, status);
return TRUE;
}
/* Enable Gap Timer */
status = naibrd_1553_BcConfigureMessageGapTimerEnable(devnum, TRUE);
if (status != 0)
{
printf("Error: naibrd_1553_BcConfigureMessageGapTimerEnable Ch %d, status = %d", channel, status);
return TRUE;
}
if ((msgType != M1553_MSGTYPE_MODECODE_TX) || (msgType != M1553_MSGTYPE_MODECODE_RX))
{
/* 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;
}
}
else if ((msgType == M1553_MSGTYPE_MODECODE_TX) || (msgType == M1553_MSGTYPE_MODECODE_RX))
{
status = naibrd_1553_BcDataBlockCreate(devnum, DBLK2, modeCommand, NULL, 0);
if (status != 0)
{
printf("Error: naibrd_1553_BcDataBlockCreate Ch %d, status = %d", channel, status);
return TRUE;
}
}
if (msgType == M1553_MSGTYPE_RTTOBC)
{
/* Create RT to BC Message */
status = naibrd_1553_BcMessageCreateRtToBc(devnum, MSG1, DBLK1, RT_ADDRESS, RT_SUBADDRESS, WORDCOUNT, 1, usBus);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageCreateRtToBc status = %d", status);
return TRUE;
}
}
else if (msgType == M1553_MSGTYPE_BCTORT)
{
/* Create BC to RT Message */
status = naibrd_1553_BcMessageCreateBcToRt(devnum, MSG1, DBLK1, RT_ADDRESS, RT_SUBADDRESS, WORDCOUNT, 1, usBus);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageCreateBcToRt status = %d", status);
return TRUE;
}
}
else if ((msgType == M1553_MSGTYPE_MODECODE_TX) || (msgType == M1553_MSGTYPE_MODECODE_RX))
{
/* Create Mode Code Tx Message */
status = naibrd_1553_BcMessageCreateMode(devnum, MSG1, DBLK1, RT_ADDRESS, (msgType == M1553_MSGTYPE_MODECODE_TX) ?
NAI_1553_CMD_TX : NAI_1553_CMD_RX, modeCommand, 0, usBus);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageCreateMode status = %d", status);
return TRUE;
}
}
else if (msgType == M1553_MSGTYPE_RTTORT)
{
/* Create RT to RT Message */
status = naibrd_1553_BcMessageCreateRtToRt(devnum, MSG1, DBLK1, RT_ADDRESS_2, RT_SUBADDRESS, WORDCOUNT, RT_ADDRESS, RT_SUBADDRESS, 0, usBus);
if (status != 0)
{
printf("Error: naibrd_1553_BcMessageCreateRtToRt 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;
}
while (bContinue)
{
/* 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;
}
status = naibrd_1553_ClearMsgFIFO(devnum);
if (status != 0)
{
printf("Error: naibrd_1553_ClearMsgFIFO status = %d", status);
return TRUE;
}
/* Start BC */
status = naibrd_1553_BcStart(devnum, MJR, 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;
}
status = naibrd_1553_GetMsgFIFOCount(devnum, &fifoCount);
if (status != 0)
{
printf("Error: naibrd_1553_GetMsgFIFOCount %d", status);
return TRUE;
}
else
{
if (fifoCount > 0)
{
currBlockIndex = 0;
/* This is necessary because otherwise, fifoData array gets used over and over without getting zero'ed out. */
/* When the array gets decoded, old data may get decoded unintentionally */
memset(fifoData, 0, sizeof(fifoData));
/* Read Message FIFO */
status = naibrd_1553_ReadMsgFIFO(devnum, fifoCount, fifoData);
if (status != 0)
{
printf("Error: naibrd_1553_ReadMsgFIFO %d", status);
return TRUE;
}
else
{
/* Read Messages */
do
{
status = naibrd_1553_DecodeFIFOMsg(fifoData, currBlockIndex, &nextBlockIndex, &msgStruct);
if (status == 0)
{
printf("Command Word: 0x%04X\n", msgStruct.wCommandWord1);
if(msgStruct.bIsCommandWord2Relevant)
printf("Command Word 2: 0x%04X\n", msgStruct.wCommandWord2);
printf("Block Status: 0x%04X\n", msgStruct.wBlockStatus);
printf("Time Tag: 0x%04X\n", msgStruct.wTimeTag);
printf("Word Count: 0x%04X\n", msgStruct.wDataWordCount);
printf("RT Status Word: 0x%04X\n", msgStruct.wStatus1);
if (msgStruct.bIsStatus2Relevant)
printf("RT Status Word 2: 0x%04X\n", msgStruct.wStatus2);
if ((msgType == M1553_MSGTYPE_RTTOBC) || (msgType == M1553_MSGTYPE_MODECODE_TX))
{
printf((msgStruct.wDataWordCount > 0) ? ("Data:") : (""));
for (i = 0; i < msgStruct.wDataWordCount; i++)
{
if (i % 8 == 0)
{
printf("\n");
}
printf("0x%04X ", msgStruct.waData[i]);
}
}
printf("\n\n");
}
else if(status != NAI_1553_CMD_NO_MSG_TO_DECODE)
{
printf("Error: naibrd_1553_DecodeFIFOMsg %d", status);
return TRUE;
}
/*** IMPORTANT !!! ***/
currBlockIndex = nextBlockIndex;
nai_msDelay(1);
} while ((status == NAI_SUCCESS) && (bContinue));
}
status = naibrd_1553_GetMsgFIFOFullStatus(devnum, NAI_1553_STATUS_REALTIME, &FIFIOfullStatusBit);
if (status == NAI_SUCCESS)
{
printf("FIFO status: %d", FIFIOfullStatusBit);
printf((FIFIOfullStatusBit == TRUE) ? " Full\r\n" : " Not full\r\n");
}
else
{
printf("Error: naibrd_1553_GetMsgFIFOFullStatus %d", status);
return TRUE;
}
}
printf("\nPress any key to send another message or Q to quit.");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (bQuit)
{
bContinue = FALSE;
}
}
}
}
}
}
}
}
/* Free 1553 Device */
status = naibrd_1553_Free(devnum);
if (status != 0)
{
printf("Error: naibrd_1553_Free status = %d", status);
return TRUE;
}
return bQuit;
}