M1553 BC Interrupt FIFO
Edit this on GitLab
M1553 BC Interrupt FIFO Sample Application (SSK 2.x)
Overview
The M1553 BC Interrupt FIFO sample application demonstrates how to configure a MIL-STD-1553 channel as a Bus Controller (BC) and use interrupt-driven FIFO message retrieval using the NAI Software Support Kit (SSK 2.x). It covers the complete BC interrupt workflow: initializing the 1553 device, connecting an ISR callback, configuring interrupt steering and vector, setting up a multi-rate message schedule with three minor frames assembled into a major frame, starting the BC, and processing received FIFO messages in the main thread when the ISR signals that new data is available.
This sample supports the following 1553 module types: FTA through FTF, and FTJ through FTK. The interrupt is configured on the Message FIFO Rx Available status, which fires whenever the BC places a completed message into the FIFO. The ISR sets a global flag, and the main loop polls this flag to read and decode FIFO messages.
For the SSK 1.x version, see M1553 BC Interrupt (SSK 1.x).
|
Note
|
This sample requires a direct bus connection (PCIe or onboard ARM). Ethernet communication will not work because interrupts cannot be delivered over Ethernet. This sample is not available on DEOS. |
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with a MIL-STD-1553 module installed (FTA-FTF, FTJ-FTK).
-
SSK 2.x installed on your development host.
-
The sample applications built. Refer to the SSK 2.x Software Development Guide for platform-specific build instructions.
-
A platform that supports hardware interrupts (Petalinux or VxWorks).
-
A 1553 bus with at least one Remote Terminal responding at RT address 1, or a bus simulator.
How to Run
Launch the m1553_bc_interrupt_fifo executable from your build output directory. On startup the application looks for a configuration file (default_1553BC_Interrupt_FIFO.txt). On the first run, this file will not exist — the application will present an interactive board menu. After connecting, select a card, module, channel, logical device number, and bus. The application then configures a BC schedule with three messages at different rates, starts the BC, and runs for approximately 10 seconds while displaying interrupt-triggered FIFO data.
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 2.x startup flow:
-
Call
naiapp_RunBoardMenu()to load a saved configuration file (if one exists) or present the interactive board menu. -
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_GetModuleName().
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t m1553_bc_interrupt_fifo(void)
#else
int32_t main(void)
#endif
{
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
bool_t stop = NAI_FALSE;
uint32_t moduleID = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == (bool_t)NAI_TRUE)
{
while (stop != NAI_TRUE)
{
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
if ((moduleID != 0))
{
Run_m1553_bc_interrupt_fifo(cardIndex, module, moduleID);
}
}
}
}
}
naiapp_access_CloseAllOpenCards();
return 0;
}
Note the SSK 2.x differences from SSK 1.x in this startup sequence:
-
The VxWorks preprocessor guard uses
NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS(SSK 1.x uses__VXWORKS__). -
The module identifier is retrieved with
naibrd_GetModuleName()(SSK 1.x usesnaibrd_GetModuleID()). -
Boolean constants are
NAI_TRUE/NAI_FALSE(SSK 1.x usesTRUE/FALSE). -
Console output uses
naiif_printf()from the platform abstraction layer (SSK 1.x usesprintf()directly).
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Entry Point
On standard platforms (Petalinux) the entry point is main(). On VxWorks the entry point is m1553_bc_interrupt_fifo(). The startup flow validates the module with IsFTx1553(), queries for a channel number and logical device number, then enters RunBCInterruptFIFO() which contains the interrupt setup, schedule configuration, and message processing loop.
Module Validation and Channel Selection
After board connection, Run_m1553_bc_interrupt_fifo() validates the module type using IsFTx1553() and queries for a channel number (up to 4 channels):
if (IsFTx1553(modid))
{
MaxChannel = 4;
bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_M1553_CHANNEL, &channel);
if (!bQuit)
{
bQuit = RunBCInterruptFIFO(cardIndex, module, channel);
}
}
1553 Device Initialization
The core function RunBCInterruptFIFO() begins by opening and initializing the 1553 device in BC mode with FIFO message mode enabled:
status = naibrd_1553_Open(cardIndex, module, channel, devnum);
status = naibrd_1553_Init(devnum, NAIBRD_1553_ACCESS_CARD,
NAIBRD_1553_MODE_BC | NAIBRD_1553_MESSAGE_FIFO_MODE, 0, 0, 0);
-
naibrd_1553_Open()— associates the card, module, and channel with a logical device number. -
naibrd_1553_Init()— initializes the device in BC mode with the message FIFO mode flag set. The FIFO mode enables interrupt-driven message retrieval.
The sample also provides an option to override external BC_DISABLE and M1760 pins via software when the hardware pins are not driven high.
Interrupt Configuration
Connecting the ISR and Setting Steering
/* Reset Interrupt counter */
irqCount = 0;
/* Hook the interrupt service routine */
status = (naibrd_1553_t)naibrd_ConnectISR(cardIndex, (nai_isr_t)myIsr);
/* Set the Interrupt Steering to Onboard */
status = naibrd_1553_SetInterruptSteering(devnum,
NAIBRD_INT_STEERING_ONBOARD_ARM);
-
naibrd_ConnectISR()— registers the ISR callback once per card. -
naibrd_1553_SetInterruptSteering()— routes interrupts to the onboard ARM processor. Change toNAIBRD_INT_STEERING_PCIEfor PPC-based boards.
FIFO Interrupt Enable and Vector
/* Enable interrupt for the message FIFO Rx Available status */
status = naibrd_1553_SetMsgFIFOInterruptEnable(devnum,
INTERRUPT_FIFO_STATUS_TYPE);
/* Set edge triggering for the message FIFO */
status = naibrd_1553_SetMsgFIFOInterruptEdgeLevel(devnum,
INTERRUPT_FIFO_STATUS_TYPE);
/* Assign a unique interrupt vector (0xA0 + channel) */
status = naibrd_1553_SetIntVector(devnum,
INTERRUPT_VECTOR_ADDEND + channel);
/* Clear any pre-existing FIFO status */
status = naibrd_1553_ClearMsgFIFOStatus(devnum,
INTERRUPT_FIFO_STATUS_TYPE);
-
INTERRUPT_FIFO_STATUS_TYPE— set toNAIBRD_1553_STATUS_BIT_MSG_FIFO_RX_AVAIL, which triggers when the FIFO contains at least one message. -
The vector uses
0xA0 + channelso each channel has a unique vector.
BC Schedule Configuration
The sample creates a multi-rate message schedule using three messages, three data blocks, three minor frames, and one major frame:
Message Schedule
-
Message 1 (BC-to-RT): RT Address 1, Subaddress 1, 11 data words — sent every 250 ms (4 Hz)
-
Message 2 (RT-to-BC): RT Address 1, Subaddress 2, 21 data words — sent every 500 ms (2 Hz)
-
Message 3 (BC-to-RT): RT Address 1, Subaddress 8, 30 data words — sent every 1000 ms (1 Hz)
Frame Structure
The periodicity is achieved by chaining minor frames into a major frame:
-
Minor Frame 1 (250 ms): Messages 1, 2, 3
-
Minor Frame 2 (250 ms): Messages 1, 2
-
Minor Frame 3 (250 ms): Message 1 only
The major frame chains: Minor 1 → Minor 3 → Minor 2 → Minor 3, giving a 1-second cycle where Message 1 runs at 4 Hz, Message 2 at 2 Hz, and Message 3 at 1 Hz.
/* Create Major Frame */
aOpCodes[0] = OP4; /* Minor Frame 1 - 3 msgs */
aOpCodes[1] = OP6; /* Minor Frame 3 - 1 msg */
aOpCodes[2] = OP5; /* Minor Frame 2 - 2 msgs */
aOpCodes[3] = OP6; /* Minor Frame 3 - 1 msg */
status = naibrd_1553_BcFrmCreate(devnum, MJR,
NAIBRD_1553_BC_FRAME_MAJOR, aOpCodes, 4, 0, 0);
ISR Callback and Message Processing
ISR Callback
The ISR is minimal — it stores the received vector, sets a global flag, and increments a counter:
static void myIsr(uint32_t vector)
{
receivedVector = vector;
irqFlag = 1;
irqCount++;
}
Main-Thread Message Processing
The main thread polls irqFlag in a timed loop. When the flag is set, it verifies the vector matches the expected value, reads the FIFO count, retrieves FIFO data, and decodes individual messages:
if (irqFlag)
{
irqFlag = 0;
if (receivedVector == (uint32_t)(INTERRUPT_VECTOR_ADDEND + channel))
{
status = naibrd_1553_GetMsgFIFOStatusAll(devnum,
NAIBRD_1553_STATUS_LATCHED, &outFifoStatusWord);
if (outFifoStatusWord & INTERRUPT_FIFO_STATUS_TYPE)
{
status = naibrd_1553_GetMsgFIFOCount(devnum, &fifoCount);
status = naibrd_1553_ReadMsgFIFO(devnum, fifoCount, fifoData);
/* Decode messages from FIFO data */
do
{
status = naibrd_1553_DecodeFIFOMsg(fifoData,
currBlockIndex, &nextBlockIndex, &msgStruct);
/* Display decoded message fields */
currBlockIndex = nextBlockIndex;
} while ((status == NAI_SUCCESS) && (bContinue));
/* Clear latched status to re-arm interrupt */
status = naibrd_1553_ClearMsgFIFOStatus(devnum,
INTERRUPT_FIFO_STATUS_TYPE);
}
}
}
Key points:
-
Vector verification — the ISR stores the vector; the main thread verifies it matches the expected channel-specific vector before processing.
-
FIFO read —
naibrd_1553_ReadMsgFIFO()reads all available FIFO entries in a single call. -
Message decoding —
naibrd_1553_DecodeFIFOMsg()steps through the FIFO data buffer, decoding one message per call using block index tracking. -
Status clear —
naibrd_1553_ClearMsgFIFOStatus()clears the latched FIFO status so subsequent interrupts can fire.
Troubleshooting Reference
This table summarizes common errors and symptoms. Consult the FTA-FTF Manual for hardware-specific diagnostic procedures.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
No board found or connection timeout |
Board not powered, incorrect configuration file, network issue |
Verify hardware is powered and connected. Check that |
Module does not support 1553 |
Selected slot contains a non-1553 module |
Verify the slot contains an FTx-series 1553 module |
|
Device already open, invalid channel or device number |
Ensure the logical device number is unique and the channel is valid (1-4) |
|
Platform does not support interrupts, or ISR already connected |
Verify you are running on Petalinux or VxWorks. Call |
Interrupt never fires |
Steering misconfigured, FIFO interrupt not enabled, or no RT responding on the bus |
Verify steering matches your platform (ARM vs. PCIe). Ensure an RT is responding at address 1. Check that |
FIFO reports zero count after interrupt |
Race condition or FIFO already read |
Ensure |
Messages decode incorrectly |
|
Call |
Ethernet connection does not deliver interrupts |
Interrupts require direct bus connection |
Use PCIe or onboard ARM connection for interrupt-based applications |
FIFO full status |
BC schedule producing messages faster than they are consumed |
Increase polling frequency or reduce message rate |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — m1553_bc_interrupt_fifo.c (SSK 2.x)
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"
/* naibrd include files */
#include "nai_libs/naibrd/include/naibrd.h"
#include "nai_libs/naibrd/include/functions/naibrd_1553.h"
#include "nai_libs/naibrd/include/functions/naibrd_1553_assisted.h"
#include "nai_libs/naibrd/include/functions/naibrd_1553_1760_status.h"
/* naiif include files */
#include "nai_libs/naiif/include/naiif_stdio.h"
/* Common 1553 Sample Program include files */
#include "nai_sample_apps/naiapp_src/board_modules/1553/m1553_common_utils/m1553_common_utils.h"
#include "nai_sample_apps/naiapp_src/board_modules/1553/m1553_common_utils/BC/m1553_bc_common_utils.h"
/* Common Sample Program include files */
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_menu.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_query.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_access.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_display.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_utils.h"
#define INTERRUPT_VECTOR_ADDEND 0xA0
#define INTERRUPT_FIFO_STATUS_TYPE NAIBRD_1553_STATUS_BIT_MSG_FIFO_RX_AVAIL /*NAIBRD_1553_STATUS_BIT_MSG_FIFO_FULL*/
/* NAIBRD_1553_STATUS_BIT_MSG_FIFO_ALMOST_FULL*/
/*NAIBRD_1553_STATUS_BIT_MSG_FIFO_EMPTY*/
static const int8_t *DEF_CONFIG_FILE = (int8_t *)"default_1553BC_Interrupt_FIFO.txt";
/* Function prototypes */
static bool_t Run_m1553_bc_interrupt_fifo(int32_t cardIndex, int32_t module, uint32_t modid);
static bool_t RunBCInterruptFIFO(int32_t cardIndex, int32_t module, int32_t channel);
static void myIsr(uint32_t vector);
/* define message constants */
#define MSG1 1
#define MSG2 2
#define MSG3 3
#define NUM_MSGS 3
/* define opcodes */
#define OP1 1
#define OP2 2
#define OP3 3
#define OP4 4
#define OP5 5
#define OP6 6
/* define frame constants */
#define MNR1 1
#define MNR2 2
#define MNR3 3
#define MJR 4
/* define data block numbers */
#define DBLK1 1
#define DBLK2 2
#define DBLK3 3
#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_SUBADDRESS1 1 /* Subaddress for Message 1 */
#define RT_SUBADDRESS2 2 /* Subaddress for Message 2 */
#define RT_SUBADDRESS3 8 /* Subaddress for Message 3 */
#define WORDCOUNT1 11 /* Data Word count for Message 1 */
#define WORDCOUNT2 21 /* Data Word count for Message 2 */
#define WORDCOUNT3 30 /* Data Word count for Message 3 */
/* Global Variables */
static volatile int32_t irqFlag;
static int32_t irqCount;
static uint32_t receivedVector;
/**************************************************************************************************************/
/** \defgroup M1553_BC_Interrupt_FIFO
\brief This sample application demonstrates how to configure a channel as a Bus Controller and configure basic interrupts.
The purpose of the M1553_BC_Interrupt is to illustrate the methods to call in the naibrd library to configure
the 1553 channel as a Bus Controller and to send various messages at different periodic rates. Specifically,
Message 1 is sent at a rate of 4 Hz (every 250 ms), Message 2 is sent at a rate of 2 Hz (every 500 ms) and
Message 3 is sent at a rate of 1 Hz (every 1000 ms). Three 250 ms minor frames are used to manage the periodicity
of these messages. Minor Frame 1 contains Messages 1, 2 and 3. Minor Frame 2 contains Messages 1 and 2 only. Minor
Frame 3 only contains Message 1. By chaining these frames together in the following order:
Minor Frame 1 | Minor Frame 3 | Minor Frame 2 | Minor Frame 3
Message 1 is sent every 250 ms, Message 2 is sent every 500 ms and Message 3 is sent every 1000 ms.
This application also demonstrates configuration and utilization of interrupts to signal the host processor
whenever a 1553 message is sent out. The interrupt service callback routine sets a global flag to indicate a BC
Rx Avail FIFO Status interrupt has been generated by the BC channel. When this occurs, the while loop in the main thread
retrieves the FIFO data based on the fifo count. (NOTE: interrupt steering should be set in
accordance with the onboard processor type, where steering is set to NAIBRD_INT_STEERING_PCIE for PPC and
NAIBRD_INT_STEERING_ONBOARD_ARM for ARM). Ethernet communication will not work with this application.
The main steps include:
- Querying the user for the card index and module number.
- Configuring the channel for Bus Controller functionality.
- Setting the device's IRQ config, installing the ISR, and setting interrupt steering.
- Setting the interrupt vector to a known value and turning interrupts on.
- Configuring a schedule with three messages sent at different rates.
- Starting the BC to transmit the configured messages.
- Handling the message responses while flagging and displaying the generated interrupts.
*/
/**************************************************************************************************************/
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t m1553_bc_interrupt_fifo(void)
#else
int32_t main(void)
#endif
{
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
bool_t stop = NAI_FALSE;
uint32_t moduleID = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == (bool_t)NAI_TRUE)
{
while (stop != NAI_TRUE)
{
/* Select Card Index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Select Module */
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
if ((moduleID != 0))
{
Run_m1553_bc_interrupt_fifo(cardIndex, module, moduleID);
}
}
}
naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
naiif_printf("\r\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_bc_interrupt_fifo(int32_t cardIndex, int32_t module, uint32_t modid)
{
bool_t bQuit = NAI_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 = RunBCInterruptFIFO(cardIndex, module, channel);
}
}
else
naiif_printf("\r\nThis module does not support 1553 functionality.\r\n");
return bQuit;
}
static bool_t RunBCInterruptFIFO(int32_t cardIndex, int32_t module, int32_t channel)
{
int32_t i;
uint32_t fifoCount = 0;
int32_t currBlockIndex = 0, nextBlockIndex = 0;
uint32_t fifoData[1024];
bool_t FIFOfullStatusBit;
uint32_t outFifoStatusWord = NAI_FALSE;
bool_t bQuit = NAI_FALSE;
uint32_t usBus;
naibrd_1553_t status;
uint16_t increment = 0;
uint16_t aData[32] = { 0 };
int16_t aOpCodes[20] = { 0 };
bool_t bContinue = NAI_TRUE;
int16_t devnum;
naibrd_1553_msgstructFIFO_t msgStruct;
bool_t bSoftware;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
int32_t counter = 1000;
/* Get the Logical Device Number */
bQuit = Get1553LogicalDevNum(DEF_M1553_DEVNUM, &devnum);
if (!bQuit)
{
/* Which bus are we firing on? */
bQuit = GetBus(&usBus);
if (!bQuit)
{
bQuit = Get1553BCSoftwareOverride(NAI_TRUE, &bSoftware);
if (!bQuit)
{
/* Open 1553 Device(s) */
status = naibrd_1553_Open(cardIndex, module, channel, devnum);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_Open Ch %d, status = %d", channel, status);
return NAI_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_WriteAuxRegister(devnum, 0x2, 0xA000);
}
else
{
/* Do not override external BC_DISABLE and M1760 Inputs */
naibrd_1553_WriteAuxRegister(devnum, 0x2, 0x0000);
}
if (!bQuit)
{
/* Reset Device */
naibrd_1553_WriteAuxRegister(devnum, 0x1, 0x1);
#if defined(NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
taskDelay(1);
#elif defined(LINUX)
usleep(100000);
#else
naiif_msDelay(100);
#endif
naibrd_1553_WriteAuxRegister(devnum, 0x1, 0x0);
/* Initialize 1553 Device(s) */
status = naibrd_1553_Init(devnum, NAIBRD_1553_ACCESS_CARD, NAIBRD_1553_MODE_BC | NAIBRD_1553_MESSAGE_FIFO_MODE, 0, 0, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_Init Ch %d, status = %d", channel, status);
return NAI_TRUE;
}
/***********************/
/*** INTERRUPT SETUP ***/
/***********************/
/* Reset Interrupt counter */
irqCount = 0;
/* Hook the interrupt service routine */
status = (naibrd_1553_t)naibrd_ConnectISR(cardIndex, (nai_isr_t)myIsr);
if (status != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_ConnectISR %d", status);
return bQuit;
}
/* Set the Interrupt Steering to Onboard */
status = naibrd_1553_SetInterruptSteering(devnum, /*NAIBRD_INT_STEERING_PCIE*/ NAIBRD_INT_STEERING_ONBOARD_ARM);
if (status != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_SetInterruptSteering %d", status);
return bQuit;
}
/* Set interrupt enable for the message fifo */
status = naibrd_1553_SetMsgFIFOInterruptEnable(devnum, INTERRUPT_FIFO_STATUS_TYPE);
if (status != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_SetMsgFIFOInterruptEnable %d", status);
return bQuit;
}
/* set edge or level interrupt for the message fifo */
status = naibrd_1553_SetMsgFIFOInterruptEdgeLevel(devnum, INTERRUPT_FIFO_STATUS_TYPE);
if (status != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_SetMsgFIFOInterruptEdgeLevel %d", status);
return bQuit;
}
/* Associate the device with a unique interrupt vector (The vector can be any */
/* value between 0x01 and 0xFF). In this case, we use an arbitrary value given */
/* by INTERRUPT_VECTOR_ADDEND plus the BC channel number. If more than one */
/* channel is used in a system, the assigned vector values should be different */
/* across all channels so they are uniquely identified. */
status = naibrd_1553_SetIntVector(devnum, INTERRUPT_VECTOR_ADDEND + channel);
if (status != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_SetIntVector %d", status);
return bQuit;
}
status = naibrd_1553_ClearMsgFIFOStatus(devnum, INTERRUPT_FIFO_STATUS_TYPE);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_ClearMsgFIFOStatus %d", status);
return NAI_TRUE;
}
/*************************/
/*** BC SCHEDULE SETUP ***/
/*************************/
/* Create BC Data Block 1 */
status = naibrd_1553_BcDataBlkCreate(devnum, DBLK1, NAIBRD_1553_BC_DATABLOCK_SIZE_32_SINGLE, NULL, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcDataBlkCreate Ch %d, status = %d", channel, status);
return NAI_TRUE;
}
/* Create BC Data Block 2 */
status = naibrd_1553_BcDataBlkCreate(devnum, DBLK2, NAIBRD_1553_BC_DATABLOCK_SIZE_32_SINGLE, NULL, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcDataBlkCreate Ch %d, status = %d", channel, status);
return NAI_TRUE;
}
/* Create BC Data Block 3 */
status = naibrd_1553_BcDataBlkCreate(devnum, DBLK3, NAIBRD_1553_BC_DATABLOCK_SIZE_32_SINGLE, NULL, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcDataBlkCreate Ch %d, status = %d", channel, status);
return NAI_TRUE;
}
/* Create BC to RT Message 1 */
status = naibrd_1553_BcMsgCreateBcToRt(devnum, MSG1, DBLK1, RT_ADDRESS, RT_SUBADDRESS1, WORDCOUNT1, 0, usBus);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcMsgCreateBcToRt status = %d", status);
return NAI_TRUE;
}
/* Create RT to BC Message 2 */
status = naibrd_1553_BcMsgCreateRtToBc(devnum, MSG2, DBLK2, RT_ADDRESS, RT_SUBADDRESS2, WORDCOUNT2, 0, usBus);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcMsgCreateRtToBc status = %d", status);
return NAI_TRUE;
}
/* Create BC to RT Message 3 */
status = naibrd_1553_BcMsgCreateBcToRt(devnum, MSG3, DBLK3, RT_ADDRESS, RT_SUBADDRESS3, WORDCOUNT3, 0, usBus);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcMsgCreateBcToRt status = %d", status);
return NAI_TRUE;
}
/* Create Execute Message Command 1 */
status = naibrd_1553_BcCmdCreate(devnum, OP1, NAIBRD_1553_OPCODE_EXECUTE_MESSAGE, NAIBRD_1553_OPCODE_COND_ALWAYS, MSG1, 0, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcCmdCreate status = %d", status);
return NAI_TRUE;
}
/* Create Execute Message Command 2 */
status = naibrd_1553_BcCmdCreate(devnum, OP2, NAIBRD_1553_OPCODE_EXECUTE_MESSAGE, NAIBRD_1553_OPCODE_COND_ALWAYS, MSG2, 0, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcCmdCreate status = %d", status);
return NAI_TRUE;
}
/* Create Execute Message Command 3 */
status = naibrd_1553_BcCmdCreate(devnum, OP3, NAIBRD_1553_OPCODE_EXECUTE_MESSAGE, NAIBRD_1553_OPCODE_COND_ALWAYS, MSG3, 0, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcCmdCreate status = %d", status);
return NAI_TRUE;
}
/* Create Minor Frame 1 */
aOpCodes[0] = OP1; /* Execute Message 1 Command */
aOpCodes[1] = OP2; /* Execute Message 2 Command */
aOpCodes[2] = OP3; /* Execute Message 3 Command */
status = naibrd_1553_BcFrmCreate(devnum, MNR1, NAIBRD_1553_BC_FRAME_MINOR, aOpCodes, 3, 2500, 0); /* 2500 for 250 ms minor frame (1 unit is 0.1 ms) */
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcFrmCreate status = %d", status);
return NAI_TRUE;
}
/* Create Minor Frame 2 */
aOpCodes[0] = OP1; /* Execute Message 1 Command */
aOpCodes[1] = OP2; /* Execute Message 2 Command */
status = naibrd_1553_BcFrmCreate(devnum, MNR2, NAIBRD_1553_BC_FRAME_MINOR, aOpCodes, 2, 2500, 0); /* 2500 for 250 ms frame */
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcFrmCreate status = %d", status);
return NAI_TRUE;
}
/* Create Minor Frame 3 */
aOpCodes[0] = OP1; /* Execute Message 1 Command */
status = naibrd_1553_BcFrmCreate(devnum, MNR3, NAIBRD_1553_BC_FRAME_MINOR, aOpCodes, 1, 2500, 0); /* 2500 for 250 ms frame */
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcFrmCreate status = %d", status);
return NAI_TRUE;
}
/* Create Call Subroutine Command 1 */
status = naibrd_1553_BcCmdCreate(devnum, OP4, NAIBRD_1553_OPCODE_CALL_SUBROUTINE, NAIBRD_1553_OPCODE_COND_ALWAYS, MNR1, 0, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcCmdCreate status = %d", status);
return NAI_TRUE;
}
/* Create Call Subroutine Command 2 */
status = naibrd_1553_BcCmdCreate(devnum, OP5, NAIBRD_1553_OPCODE_CALL_SUBROUTINE, NAIBRD_1553_OPCODE_COND_ALWAYS, MNR2, 0, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcCmdCreate status = %d", status);
return NAI_TRUE;
}
/* Create Call Subroutine Command 3 */
status = naibrd_1553_BcCmdCreate(devnum, OP6, NAIBRD_1553_OPCODE_CALL_SUBROUTINE, NAIBRD_1553_OPCODE_COND_ALWAYS, MNR3, 0, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcCmdCreate status = %d", status);
return NAI_TRUE;
}
/* Create Major Frame */
aOpCodes[0] = OP4; /* Minor Frame 1 - 3 msgs*/
aOpCodes[1] = OP6; /* Minor Frame 3 - 1 msg */
aOpCodes[2] = OP5; /* Minor Frame 2 - 2 msgs*/
aOpCodes[3] = OP6; /* Minor Frame 3 - 1 msg*/
/* 7 msgs in total */
status = naibrd_1553_BcFrmCreate(devnum, MJR, NAIBRD_1553_BC_FRAME_MAJOR, aOpCodes, 4, 0, 0); /* If frameTime is set here to a value */
/* other than zero, this value will */
/* override the minor frame times that */
/* were set using the _BcFrmCreate() */
/* function and set all minor frame */
/* times to the same duration. */
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
return NAI_TRUE;
}
while (bContinue)
{
/* Load BC data block with incremental data */
for (i = 0; i < WORDCOUNT1; i++)
{
aData[i] = increment++;
}
status = naibrd_1553_BcDataBlkWrite(devnum, DBLK1, aData, WORDCOUNT1, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcDataBlkWrite status = %d", status);
return NAI_TRUE;
}
/* Load BC data block 3 with 0xBBCC */
for (i = 0; i < WORDCOUNT3; i++)
{
aData[i] = 0xBBCC;
}
status = naibrd_1553_BcDataBlkWrite(devnum, DBLK3, aData, WORDCOUNT3, 0);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcDataBlockWrite status = %d", status);
return NAI_TRUE;
}
status = naibrd_1553_ClearMsgFIFO(devnum);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_ClearMsgFIFO status = %d", status);
return NAI_TRUE;
}
/* Start BC */
status = naibrd_1553_BcStart(devnum, MJR, 1);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcStart status = %d", status);
return NAI_TRUE;
}
counter = 1000;
naiif_printf("BC Running for approximately 10 seconds...\r\n");
/* Run the schedule for approximately 10 seconds */
while (counter > 0)
{
if (irqFlag)
{
irqFlag = 0;
/* Check the Interrupt Vector to identify which device (1553 channel) generated the interrupt */
naiif_printf("\r\nReceived Vector: 0x%08X", receivedVector);
/* If the vector value matches the vector that we assigned to the BC channel... */
if (receivedVector == (uint32_t)(INTERRUPT_VECTOR_ADDEND + channel))
{
status = naibrd_1553_GetMsgFIFOStatusAll(devnum, NAIBRD_1553_STATUS_LATCHED, &outFifoStatusWord); // for rx avail
if (status != 0)
{
naiif_printf("Error: naibrd_1553_GetMsgFIFOStatusAll %d", status);
return NAI_TRUE;
}
if (outFifoStatusWord & INTERRUPT_FIFO_STATUS_TYPE) /* for rx avail */
{
naiif_printf("\r\nBC Rx Available Status interrupt triggered. IrqCount = %d\r\n", irqCount);
status = naibrd_1553_GetMsgFIFOCount(devnum, &fifoCount);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_GetMsgFIFOCount %d", status);
return NAI_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)
{
naiif_printf("Error: naibrd_1553_ReadMsgFIFO %d", status);
return NAI_TRUE;
}
else
{
/* Read Messages */
do
{
status = naibrd_1553_DecodeFIFOMsg(fifoData, currBlockIndex, &nextBlockIndex, &msgStruct);
if (status == 0)
{
naiif_printf("Command Word: 0x%04X\r\n", msgStruct.commandWord1);
naiif_printf("Block Status: 0x%04X\r\n", msgStruct.blockStatus);
naiif_printf("Time Tag: 0x%04X\r\n", msgStruct.timeTag);
naiif_printf("Word Count: 0x%04X\r\n", msgStruct.dataWordCount);
naiif_printf("RT Status Word: 0x%04X\r\n", msgStruct.status1);
if (msgStruct.type == NAIBRD_1553_MESSAGE_RTTOBC)
{
naiif_printf((msgStruct.dataWordCount > 0) ? ("Data:") : (""));
for (i = 0; i < msgStruct.dataWordCount; i++)
{
if (i % 8 == 0)
{
naiif_printf("\r\n");
}
naiif_printf("0x%04X ", msgStruct.data[i]);
}
}
printf("\r\n\r\n");
}
else if (status != NAIBRD_1553_CMD_NO_MSG_TO_DECODE)
{
naiif_printf("Error: naibrd_1553_DecodeFIFOMsg %d", status);
return NAI_TRUE;
}
/*** IMPORTANT !!! ***/
currBlockIndex = nextBlockIndex;
} while ((status == NAI_SUCCESS) && (bContinue));
/* Clear latched interrrupt status condition */
status = naibrd_1553_ClearMsgFIFOStatus(devnum, INTERRUPT_FIFO_STATUS_TYPE);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_ClearMsgFIFOStatus %d", status);
return NAI_TRUE;
}
}
}
}
}
}
else
{
naiif_printf("\r\n0x%08X is NOT my interrupt vector!\r\n", receivedVector);
}
}
naibrd_msDelay(10);
counter--;
}
status = naibrd_1553_GetMsgFIFOFullStatus(devnum, NAIBRD_1553_STATUS_REALTIME, &FIFOfullStatusBit);
if (status == NAI_SUCCESS)
{
naiif_printf("FIFO status: %d", FIFOfullStatusBit);
naiif_printf((FIFOfullStatusBit == NAI_TRUE) ? " Full\r\n" : " Not full\r\n");
}
else
{
naiif_printf("Error: naibrd_1553_GetMsgFIFOFullStatus %d", status);
return NAI_TRUE;
}
/* Stop BC (This call is not necessary here since transmission of the major frame should have completed by now) */
status = naibrd_1553_BcStop(devnum);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_BcStop status = %d", status);
return NAI_TRUE;
}
printf("BC Halted.\n");
naiif_printf("\r\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 = NAI_FALSE;
}
}
}
}
}
}
/* Free 1553 Device */
status = naibrd_1553_Free(devnum);
if (status != 0)
{
naiif_printf("Error: naibrd_1553_Free status = %d", status);
return NAI_TRUE;
}
return bQuit;
}
static void myIsr(uint32_t vector)
{
receivedVector = vector;
/* Set the global interrupt flag */
irqFlag = 1;
irqCount++;
}