M1553 RT Interrupt
Edit this on GitLab
M1553 RT Interrupt Sample Application (SSK 2.x)
Overview
The M1553 RT Interrupt sample application demonstrates how to configure a MIL-STD-1553 channel as a Remote Terminal (RT) with interrupt-driven message handling using the NAI Software Support Kit (SSK 2.x). It covers the complete RT interrupt workflow: initializing the 1553 device in RT mode, configuring RT address and subaddress, setting up Tx and Rx data blocks, connecting an ISR callback, configuring interrupt steering and vector, enabling end-of-message interrupts, starting the RT, and processing incoming messages when the ISR signals new data.
This sample supports the following 1553 module types: FTA through FTF, and FTJ through FTK. The interrupt is configured on the End-of-Message status, which fires whenever the RT completes processing a 1553 transaction. The ISR sets a global flag, and the main loop polls this flag to read interrupt status registers, clear the interrupt latch, and decode received messages from the RT message stack.
For the SSK 1.x version, see M1553 RT 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 a Bus Controller sending messages to the configured RT address and subaddress.
How to Run
Launch the m1553_rt_interrupt executable from your build output directory. On startup the application looks for a configuration file (default_1553_RTInterrupt.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, RT address, subaddress, logical device number, and buffer type. The application then configures the RT with interrupts enabled and runs for a user-specified duration, displaying decoded messages as they arrive via interrupt.
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_rt_interrupt(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_RT_Interrupt(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_rt_interrupt(). The main function handles board connection, then calls Run_M1553_RT_Interrupt() which performs all 1553 device setup, interrupt configuration, buffer creation, and message processing.
Configuration Flow
Run_M1553_RT_Interrupt() queries the user for several RT-specific parameters:
-
Channel and RT address — via
Get1553RTCfg(). -
Subaddress — the subaddress to legalize for Tx and Rx messages.
-
Logical device number — via
Get1553LogicalDevNum(). -
RT address source — software (internal) or hardware (external) via
Get1553RTAddressSource(). -
Rx buffer type — single, double, or circular buffer via
Get1553RxBufferType().
1553 Device Initialization
The 1553 device is opened and initialized in RT mode:
result = naibrd_1553_Open(cardIndex, module, rtchan, DevNum);
result = naibrd_1553_Init(DevNum, NAIBRD_1553_ACCESS_CARD,
NAIBRD_1553_MODE_RT, 0, 0, 0);
RT Address Configuration
The RT address can be sourced from software or hardware. When using software addressing, the sample sets the address source to internal and programs the desired address:
result = naibrd_1553_RtSetAddrSrc(DevNum,
NAIBRD_1553_RT_ADDR_SOURCE_INTERNAL);
result = naibrd_1553_RtSetAddr(DevNum, rtaddr);
Interrupt Configuration
IRQ Configuration and ISR Connection
The interrupt setup begins with configuring the core IRQ mode and connecting the ISR:
/* Setup Interrupts with Level Detection and No Auto Clear */
result = naibrd_1553_SetIrqCfg(DevNum,
NAIBRD_1553_IRQ_MODE_LEVEL, NAIBRD_1553_IRQ_NO_AUTO_CLEAR);
/* Hook the interrupt service routine */
result = naibrd_ConnectISR(cardIndex, (nai_isr_t)myIsr);
/* Set the Interrupt Steering to Onboard ARM */
result = naibrd_1553_SetInterruptSteering(DevNum,
NAIBRD_INT_STEERING_ONBOARD_ARM);
/* Set the Interrupt Vector */
result = naibrd_1553_SetIntVector(DevNum, INTERRUPT_VECTOR);
-
naibrd_1553_SetIrqCfg()— configures level detection with no auto-clear. This means the application must manually read and clear status registers after each interrupt. -
naibrd_ConnectISR()— registers the ISR callback once per card. -
naibrd_1553_SetInterruptSteering()— routes interrupts to the onboard ARM processor. -
naibrd_1553_SetIntVector()— assigns vector0xF1to this device.
Clearing Initial Status
Before starting the RT, clear any pre-existing interrupt status:
/* Read core status registers to clear statuses */
result = naibrd_1553_GetIntStatus(DevNum, &status1, &status2);
/* Clear Interrupt Latch Bit */
result = naibrd_1553_ClearIntLatch(DevNum);
Enabling Interrupts
End-of-message interrupts are enabled just before starting the RT:
result = naibrd_1553_SetIrqEnable(DevNum, 0x1,
INTERRUPT_TYPE_MASK, NULL);
The INTERRUPT_TYPE_MASK is set to NAIBRD_1553_INT_REG1_MASK_END_OF_MSG, which triggers an interrupt each time the RT completes processing a message.
Buffer Configuration
Receive Data Block
A receive data block is created and mapped to the desired subaddress with end-of-message IRQ notification:
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_RX,
nDataBlockType, NULL, 0);
result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_RX, sa,
NAIBRD_1553_RT_MESSAGE_TYPE_RX,
NAIBRD_1553_RT_DATABLOCK_IRQ_END_OF_MESSAGE, 1);
Transmit Data Blocks
Two transmit data blocks are created for ping-pong buffering. The first is mapped to the subaddress:
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_TX1,
NAIBRD_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_TX2,
NAIBRD_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_TX1, sa,
NAIBRD_1553_RT_MESSAGE_TYPE_TX,
NAIBRD_1553_RT_DATABLOCK_IRQ_NONE, 1);
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++;
}
Message Processing Loop
The ProcessMessages() function runs for a user-specified duration, polling the irqFlag. When an interrupt is detected, it reads and clears the interrupt status registers, clears the interrupt latch, then checks if a new message is available on the RT stack:
if (irqFlag)
{
irqFlag = 0;
/* Read to clear status registers */
result = naibrd_1553_GetIntStatus(deviceNumber, &status1, &status2);
if (status1 & NAIBRD_1553_INT_REG1_MASK_END_OF_MSG)
{
naiif_printf("\r\nEnd Of Message interrupt triggered. IrqCount = %d\r\n",
irqCount);
}
/* Clear Latch Bit */
result = naibrd_1553_ClearIntLatch(deviceNumber);
/* Get message from RT stack */
result = naibrd_1553_RtMsgGetFromStackRaw(deviceNumber, wsBuffer,
NAIBRD_1553_MAX_MESSAGE_SIZE_RT);
if (result > 0)
{
result = naibrd_1553_RtMsgDecodeRaw(deviceNumber, wsBuffer,
&DecodedMsgStruct);
/* Display decoded message fields */
}
}
Key points:
-
Status register read —
naibrd_1553_GetIntStatus()reads and clears the interrupt status registers. The function returns two status words;status1is checked againstNAIBRD_1553_INT_REG1_MASK_END_OF_MSG. -
Latch clear —
naibrd_1553_ClearIntLatch()must be called after reading status to allow new interrupts. -
Message retrieval —
naibrd_1553_RtMsgGetFromStackRaw()returns the raw message buffer;naibrd_1553_RtMsgDecodeRaw()decodes it into a structured format.
Cleanup
After the processing loop completes, the sample disables interrupts, disconnects the ISR, and frees the 1553 device:
/* Disable Interrupts */
result = naibrd_1553_SetIrqEnable(DevNum, 0x0, 0xFFFFFFFF, NULL);
/* Uninstall ISR */
result = naibrd_DisconnectISR(cardIndex);
/* Free 1553 Device */
result = naibrd_1553_Free(DevNum);
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 |
RT configured but no interrupts received |
No BC is sending messages to this RT address and subaddress |
Verify a Bus Controller is active and sending to the correct RT address |
End-of-message interrupt fires but no message decoded |
Stack pointer has not advanced, or message was a Tx request |
Check the return value of |
Interrupt fires continuously |
Interrupt latch not cleared after processing |
Ensure |
Ethernet connection does not deliver interrupts |
Interrupts require direct bus connection |
Use PCIe or onboard ARM connection for interrupt-based applications |
RT address mismatch |
Software vs. hardware RT address source not configured correctly |
Verify RT address source matches your hardware setup. Use software addressing if external pins are not wired. |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — m1553_rt_interrupt.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"
/* naiif include files */
#include "nai_libs/naiif/include/naiif.h"
#include "nai_libs/naiif/include/naiif_stdio.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"
/* Common 1553 Sample Program include files */
#include "nai_sample_apps/naiapp_src/board_modules/1553/m1553_common_utils/m1553_common_utils.h"
#define INTERRUPT_VECTOR 0xF1
#define INTERRUPT_TYPE_MASK NAIBRD_1553_INT_REG1_MASK_END_OF_MSG /* NAIBRD_1553_INT_STS_REG1_MASK_TIME_TAG_ROLLOVER */ /* NAIBRD_1553_INT_STS_REG1_MASK_END_OF_MESSAGE */
#define INT_FILTER_VALUE 0x30
static const int8_t *DEF_CONFIG_FILE = (int8_t *)"default_1553_RTInterrupt.txt";
/* Function prototypes */
static bool_t Run_M1553_RT_Interrupt(int32_t cardIndex, int32_t module, uint32_t modid);
static int32_t ProcessMessages(int32_t duration);
static void myIsr(uint32_t vector);
static const uint16_t DATA_BLOCK_ID_TX1 = 1;
static const uint16_t DATA_BLOCK_ID_TX2 = 2;
static const uint16_t DATA_BLOCK_ID_RX = 3;
static const int32_t DEF_RT_CHANNEL = 1;
static const int16_t DEF_RT_DEV_NUM = 1;
static const naibrd_1553_rt_address_t DEF_RT_ADDRESS = 1;
static const naibrd_1553_rt_subaddress_t DEF_RT_SUBADDR = 2;
static const naibrd_1553_rt_dataBlockType_t DEF_RT_RX_BUF_TYPE = NAIBRD_1553_RT_DATABLOCK_DOUBLE;
/* Global Variables */
static int32_t currDataBlock;
static int16_t deviceNumber;
static volatile int32_t irqFlag;
static int32_t irqCount;
static uint32_t receivedVector;
/**************************************************************************************************************/
/** \defgroup M1553_RT_Interrupt
\brief This sample application demonstrates how to configure a channel as a Remote Terminal and configure basic interrupts.
The purpose of the M1553_RT_Interrupt is to illustrate the methods to call in the naibrd library to configure
the 1553 channel as a Remote Terminal, legalize the user specified subaddress for both Tx and Rx, and set it up
with interrupts enabled such that when an end of message interrupt is triggered, the received 1553 message is
displayed in the console. (NOTE: interrupt steering should be set in accordance with the onboard processor type,
where steering is set to NAIBRD_INT_STEERING_PCIE_APP for PPC1 and NAIBRD_INT_STEERING_ONBOARD_ARM for ARM1).
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 Remote Terminal 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.
- Starting the RT and processing incoming messages, while handling the generated interrupts.
*/
/**************************************************************************************************************/
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t m1553_rt_interrupt(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_RT_Interrupt(cardIndex, module, moduleID);
}
}
}
naiif_printf("\r\n\r\nType Q to quit or Enter key to restart application:\r\n\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_RT_Interrupt(int32_t cardIndex, int32_t module, uint32_t modid)
{
/* Variables */
bool_t bQuit = NAI_FALSE;
int32_t rtchan;
naibrd_1553_rt_address_t rtaddr;
naibrd_1553_rt_subaddress_t sa = DEF_RT_SUBADDR;
int16_t DevNum = 0;
int32_t result;
naibrd_1553_rt_dataBlockType_t nDataBlockType = 0;
bool_t bContinue = NAI_TRUE;
int32_t duration;
uint16_t status1, status2;
bool_t bSoftwareRTAddr;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
/*************************/
/*** 1553 DEVICE SETUP ***/
/*************************/
/* Get Card, Module, Channel Numbers and Open a Handle */
bQuit = Get1553RTCfg(modid, DEF_RT_CHANNEL, DEF_RT_ADDRESS, &rtchan, &rtaddr);
if (bQuit)
{
return bQuit;
}
naiif_printf("Enter Subaddress\r\n");
bQuit = Get1553Address(31, DEF_RT_SUBADDR, &sa);
/* Get Logical Device # */
bQuit = Get1553LogicalDevNum(DEF_RT_DEV_NUM, &DevNum);
if (bQuit)
{
return bQuit;
}
deviceNumber = DevNum;
irqFlag = 0;
/* Associate Card, Module and Channel Numbers with the Logical Device # */
result = naibrd_1553_Open(cardIndex, module, rtchan, DevNum);
if (result)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_Open %d", result);
return bQuit;
}
/* Initialize Device */
result = naibrd_1553_Init(DevNum, NAIBRD_1553_ACCESS_CARD, NAIBRD_1553_MODE_RT, 0, 0, 0);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_Initialize %d", result);
return bQuit;
}
if (modid == NAIBRD_MODULE_ID_FT8)
{
/* Simplex Enable */
naibrd_1553_WriteAuxRegister(DevNum, NAIBRD_1553_AUX_ADDRESS_SIMPLEX, 0x4000);
}
/* Get RT Address Source from user */
bQuit = Get1553RTAddressSource(NAI_TRUE, &bSoftwareRTAddr);
if (bQuit)
{
return bQuit;
}
if (bSoftwareRTAddr)
{
/* Set RTAD_SW_EN and RT_ADR_LAT in software */
result = naibrd_1553_WriteAuxRegister(DevNum, NAIBRD_1553_AUX_ADDRESS_MISC_BITS, 0x0018);
result = naibrd_1553_RtSetAddrSrc(DevNum, NAIBRD_1553_RT_ADDR_SOURCE_INTERNAL);
/* Set RT address */
result = naibrd_1553_RtSetAddr(DevNum, rtaddr);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_RtSetAddr %d", result);
return bQuit;
}
}
else
{
/* Unset RTAD_SW_EN and set RT_ADR_LAT in software */
result = naibrd_1553_WriteAuxRegister(DevNum, NAIBRD_1553_AUX_ADDRESS_MISC_BITS, 0x0008);
result = naibrd_1553_RtSetAddrSrc(DevNum, NAIBRD_1553_RT_ADDR_SOURCE_EXTERNAL);
}
/***********************/
/*** INTERRUPT SETUP ***/
/***********************/
/* Reset Interrupt counter */
irqCount = 0;
/* Setup Interrupts in Core with Level Detection and Auto Clear (read clears interrupt statuses) */
result = naibrd_1553_SetIrqCfg(DevNum, NAIBRD_1553_IRQ_MODE_LEVEL, NAIBRD_1553_IRQ_NO_AUTO_CLEAR);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_SetIrqConfig %d", result);
return bQuit;
}
/* Hook the interrupt service routine */
result = naibrd_ConnectISR(cardIndex, (nai_isr_t)myIsr);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_ConnectISR %d", result);
return bQuit;
}
/* Set the Interrupt Steering to Onboard */
result = naibrd_1553_SetInterruptSteering(DevNum, /*NAIBRD_INT_STEERING_PCIE*/ NAIBRD_INT_STEERING_ONBOARD_ARM);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_SetInterruptSteering %d", result);
return bQuit;
}
/* Set the Interrupt Vector */
result = naibrd_1553_SetIntVector(DevNum, INTERRUPT_VECTOR);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_SetIntVector %d", result);
return bQuit;
}
/* Read core status registers to clear statuses */
result = naibrd_1553_GetIntStatus(DevNum, &status1, &status2);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_GetIntStatus %d", result);
return bQuit;
}
/* Clear Interrupt Latch Bit */
result = naibrd_1553_ClearIntLatch(DevNum);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_ClearIntLatch %d", result);
return bQuit;
}
/*************************/
/*** 1553 BUFFER SETUP ***/
/*************************/
/* Select Single Buffer, Double Buffer or Circular Buffer for Rx Messages */
bQuit = Get1553RxBufferType(DEF_RT_RX_BUF_TYPE, &nDataBlockType);
if (bQuit)
{
return bQuit;
}
/* Create a Rx Buffer data block and map to the desired subaddress */
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_RX, nDataBlockType, NULL, 0);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_RtDataBlockCreate %d", result);
return bQuit;
}
result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_RX, sa, NAIBRD_1553_RT_MESSAGE_TYPE_RX, NAIBRD_1553_RT_DATABLOCK_IRQ_END_OF_MESSAGE, 1);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_RtDataBlockMapToSubaddress %d", result);
return bQuit;
}
/* Create two Tx Buffer data blocks and map the first to the desired subaddress */
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_TX1, NAIBRD_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_RtDataBlockCreate %d", result);
return bQuit;
}
result = naibrd_1553_RtDataBlkCreate(DevNum, DATA_BLOCK_ID_TX2, NAIBRD_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_RtDataBlockCreate %d", result);
return bQuit;
}
result = naibrd_1553_RtDataBlkMapToSA(DevNum, DATA_BLOCK_ID_TX1, sa, NAIBRD_1553_RT_MESSAGE_TYPE_TX, NAIBRD_1553_RT_DATABLOCK_IRQ_NONE, 1);
if (result < 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_RtDataBlockMapToSubaddress %d", result);
return bQuit;
}
currDataBlock = DATA_BLOCK_ID_TX1;
/*******************/
/*** RUN 1553 RT ***/
/*******************/
while (bContinue)
{
naiif_printf("\r\nType duration (in seconds) to run RT or %c to quit (default: 5) : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
duration = 5;
if (inputResponseCnt > 0)
{
duration = (int)atol((const char*)inputBuffer);
}
/* Enable Subadddress EOM Interrupts (NULL is passed in for the ISR function pointer. The ISR */
/* was hooked in with naibrd_ConnectISR) */
result = naibrd_1553_SetIrqEnable(DevNum, 0x1, INTERRUPT_TYPE_MASK, NULL);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_SetIrqManipulate %d", result);
return bQuit;
}
/* Start RT */
result = naibrd_1553_RtStart(DevNum);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_RtStart %d", result);
return bQuit;
}
/* Process New Messages */
ProcessMessages(duration);
/* Stop RT */
result = naibrd_1553_RtStop(DevNum);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_RtStop %d", result);
return bQuit;
}
/* Disable Interrupts */
result = naibrd_1553_SetIrqEnable(DevNum, 0x0, 0xFFFFFFFF, NULL);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_SetIrqManipulate %d", result);
return bQuit;
}
}
else
bContinue = NAI_FALSE;
}
/* Uninstall ISR */
result = naibrd_DisconnectISR(cardIndex);
/* Free 1553 Device */
result = naibrd_1553_Free(DevNum);
if (result != 0)
{
bQuit = NAI_TRUE;
naiif_printf("Error: naibrd_1553_Free %d", result);
return bQuit;
}
return bQuit;
}
static void myIsr(uint32_t vector)
{
receivedVector = vector;
/* Set the global interrupt flag */
irqFlag = 1;
irqCount++;
}
static int32_t ProcessMessages(int32_t duration)
{
int32_t counter_mS = 0, end_mS = 0;
uint32_t result;
int32_t i;
naibrd_1553_msgstruct_t DecodedMsgStruct;
uint16_t wsBuffer[72] = { 0x0000 };
int32_t count = 0;
uint16_t status1, status2;
end_mS = duration * 1000; /* in milliseconds */
/* While looping for the user specified duration of time, poll on the global irqFlag and if it is set (interrupt received), */
/* reset the flag, clear the interrupt status registers, clear interrupt latch bit and process new 1553 message, if any. */
while (counter_mS < end_mS)
{
if (irqFlag)
{
irqFlag = 0;
/* Display the Interrupt Vector */
naiif_printf("\r\nReceived Vector: 0x%08X", receivedVector);
/* Read to clear status registers */
result = naibrd_1553_GetIntStatus(deviceNumber, &status1, &status2);
if (result != NAI_SUCCESS)
{
naiif_printf("\r\nERROR: naibrd_1553_GetIntStatus - %d\r\n", result);
}
if (status1 & NAIBRD_1553_INT_REG1_MASK_END_OF_MSG)
{
naiif_printf("\r\nEnd Of Message interrupt triggered. IrqCount = %d\r\n", irqCount);
}
else if (status1 & NAIBRD_1553_INT_STS_REG1_MASK_TIME_TAG_ROLLOVER)
{
naiif_printf("\r\nTime Tag Rollover interrupt triggered. IrqCount = %d\r\n", irqCount);
}
else
{
naiif_printf("\r\nOther interrupt triggered. status1=0x%04X status2=0x%04X IrqCount=%d\r\n", status1, status2, irqCount);
}
/* Clear Latch Bit */
result = naibrd_1553_ClearIntLatch(deviceNumber);
if (result != NAI_SUCCESS)
{
naiif_printf("\r\nERROR: naibrd_1553_ClearIntLatch - %d\r\n", result);
}
/* Get Data */
/* If the stack pointer has updated (new message arrived), read one message at a time */
result = naibrd_1553_RtMsgGetFromStackRaw(deviceNumber, wsBuffer, NAIBRD_1553_MAX_MESSAGE_SIZE_RT);
if (result < 0)
{
naiif_printf("ERROR: naibrd_1553_RtMessageGetFromStackRaw %d\r\n\r\n", result);
}
else if (result > 0)
{
/* Decode Raw Message */
result = naibrd_1553_RtMsgDecodeRaw(deviceNumber, wsBuffer, &DecodedMsgStruct);
if (result < 0)
{
naiif_printf("ERROR: naibrd_1553_RtMessageDecodeRaw %d\r\n\r\n", result);
}
if ((DecodedMsgStruct.commandWord1 & 0x0400) != 0x0400) /* If this is a Rx message */
{
naiif_printf("Rx Msg Received\r\n");
naiif_printf("\r\n\r\nDecoded Message:\r\n\r\n");
naiif_printf("Block Status - 0x%04X\r\n", DecodedMsgStruct.blockStatus);
naiif_printf("Time Tag - 0x%04X\r\n", DecodedMsgStruct.timeTag);
naiif_printf("Command Word - 0x%04X\r\n", DecodedMsgStruct.commandWord1);
naiif_printf("Data Word Count - 0x%04X\r\n", DecodedMsgStruct.dataWordCount);
naiif_printf("Data:");
for (i = 0; i < DecodedMsgStruct.dataWordCount; i++)
{
if (i % 8 == 0)
{
naiif_printf("\r\n");
}
naiif_printf("0x%04X ", DecodedMsgStruct.data[i]);
}
naiif_printf("count: %d\r\n", count++);
naiif_printf("\r\n\r\n");
}
else
{
naiif_printf("Tx Msg Received\r\n");
}
}
}
naibrd_msDelay(10);
counter_mS += 10;
}
return 1;
}