M1760 RT Interrupt
Edit this on GitLab
M1760 RT Interrupt Sample Application (SSK 1.x)
Overview
The M1760 RT Interrupt sample application demonstrates how to configure a MIL-STD-1553 channel as a Remote Terminal (RT) with interrupt-driven message notification on MIL-STD-1760 modules using the NAI Software Support Kit (SSK 1.x). Instead of polling the RT message stack in a tight loop, this sample configures the hardware to generate an interrupt when the RT is accessed on the bus. The application installs an Interrupt Service Routine (ISR) that sets a flag, and the main loop processes messages only when that flag is raised. This event-driven approach reduces CPU utilization compared to continuous polling.
|
Note
|
This sample is only supported on FTJ and FTK modules. For interrupt-driven RT operation on FT1-FT9 modules, use the M1553_RT_Interrupt sample instead. The 1760 interrupt API (naibrd_1760_SetIrqManipulate(), naibrd_1760_GetIntStatus()) differs from the standard 1553 interrupt API. Ethernet communication is not supported with this application — it requires onboard or PCIe interrupt steering.
|
The key interrupt API calls demonstrated are:
-
naibrd_1553_SetIrqConfig()— configures interrupt mode (pulse) and auto-clear behavior. -
naibrd_InstallISR()— hooks the user ISR to the interrupt source. -
naibrd_1553_SetInterruptSteering()— routes interrupts to the appropriate processor (onboard ARM, PCIe host, etc.). -
naibrd_1553_SetIntVector()— assigns the interrupt vector for this channel. -
naibrd_1760_SetIrqManipulate()— enables or disables specific 1760 interrupt sources (hardware, BC, RT, MT). -
naibrd_1760_GetIntStatus()— reads and clears the interrupt status registers. -
naibrd_1553_ClearIntLatch()— clears the interrupt latch bit to allow the next interrupt.
For detailed register maps and module-specific behavior, refer to the FTJ-FTK Manual.
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with an FTJ or FTK module installed.
-
SSK 1.x installed on your development host.
-
The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.
-
Onboard or PCIe access to the board. Ethernet connections do not support the interrupt mechanism used by this sample.
How to Run
Launch the M1760_RT_Interrupt executable from your build output directory. On startup the application looks for a configuration file (default_1760_RTInterrupt.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, the application walks you through RT-specific settings (channel, RT address, subaddress, Rx buffer type) and then enters a timed loop where it waits for interrupts and processes received messages.
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 or 1760. |
The main() function follows a standard SSK 1.x startup flow:
-
Call
naiapp_RunBoardMenu()to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_1760_RTInterrupt.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear. -
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_GetModuleID()so downstream code can adapt to the specific module variant. -
If a valid module is found, call
Run_M1760_RT_Interrupt()to begin RT and interrupt configuration.
#if defined (__VXWORKS__)
int32_t M1760_RT_Interrupt(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_M1760_RT_Interrupt(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;
}
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
The entry point is main() on most platforms, or M1760_RT_Interrupt() on VxWorks. Both resolve to the same logic.
Run_M1760_RT_Interrupt() is organized into three clearly separated phases:
-
1553 Device Setup — open and initialize the device, configure the RT address.
-
Interrupt Setup — configure interrupt mode, install ISR, set steering and vector, clear status registers.
-
1553 Buffer Setup and Run — create Rx/Tx data blocks, map to subaddresses, start the RT, and enter the interrupt-driven processing loop.
User Input Sequence
After the board connection is established, the application collects configuration through a series of prompts:
-
RT channel and address —
Get1553RTCfg()asks for the 1553 channel (default: 3) and RT address (default: 1). -
Subaddress —
Get1553Address()asks for the subaddress to legalize for Tx and Rx (default: 2). -
Logical device number —
Get1553LogicalDevNum()assigns a logical device handle (default: 3). -
RT address source —
Get1553RTAddressSource()asks whether to set the RT address via software or read from external pins. -
Rx buffer type —
Get1553RxBufferType()selects single, double, or circular buffering for Rx messages (default: double buffer). -
Monitoring duration — how many seconds to wait for interrupts (default: 5 seconds).
Device Initialization
Opening and Initializing
swResult = naibrd_1553_Open(cardIndex, module, rtchan, DevNum);
swResult = naibrd_1553_Initialize(DevNum, NAI_1553_ACCESS_CARD, NAI_1553_MODE_RT, 0, 0, 0);
The device is initialized in standard RT mode (NAI_1553_MODE_RT). The interrupt capability is configured separately through the interrupt setup APIs — it does not require a special mode flag.
RT Address Configuration
The sample supports both software and external RT addressing, using the same auxiliary register pattern as other RT samples:
if (bSoftwareRTAddr)
{
swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0018);
swResult = naibrd_1553_RtSetAddress(DevNum, rtaddr);
}
else
{
swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0008);
}
For software addressing, 0x0018 enables both RTAD_SW_EN and RT_ADR_LAT. For external addressing, 0x0008 sets the latch only.
|
Important
|
Common initialization issues you may encounter:
|
Interrupt Configuration
The interrupt setup is the distinguishing feature of this sample. It configures the hardware to generate an interrupt when the RT’s subaddress is accessed, routes that interrupt to the processor, and installs a handler to respond to it.
IRQ Mode and Auto-Clear
swResult = naibrd_1553_SetIrqConfig(DevNum, NAI_1553_IRQ_MODE_PULSE, NAI_1553_IRQ_AUTO_CLEAR);
-
NAI_1553_IRQ_MODE_PULSE— the interrupt output pulses when triggered rather than holding at a level. Pulse mode is typically preferred because it does not require the ISR to explicitly deassert the interrupt line. -
NAI_1553_IRQ_AUTO_CLEAR— reading the interrupt status registers automatically clears them, simplifying the ISR.
Installing the ISR
swResult = naibrd_InstallISR(cardIndex, NAIBRD_IRQ_ID_ON_BOARD_0, (nai_isr_t)myIsr, NULL);
This hooks myIsr as the interrupt handler. The second parameter specifies the interrupt routing:
-
NAIBRD_IRQ_ID_ON_BOARD_0— for onboard ARM processors. -
NAIBRD_IRQ_ID_DONT_CARE— for external host connections (PCIe, etc.).
Choose the ID that matches your hardware configuration.
Interrupt Steering
swResult = naibrd_1553_SetInterruptSteering(DevNum, NAIBRD_INT_STEERING_ON_BOARD_0);
Steering directs the interrupt signal to the correct processor. The available steering constants are:
-
NAIBRD_INT_STEERING_ON_BOARD_0— route to the onboard ARM processor. -
NAIBRD_INT_STEERING_PCIE_APP— route to the PCIe host (use for PPC1 or external host systems). -
NAIBRD_INT_STEERING_CPCI_APP— route to a CompactPCI host.
The steering must match the naibrd_InstallISR() ID and the physical connection to your board.
Interrupt Vector
swResult = naibrd_1553_SetIntVector(DevNum, INTERRUPT_VECTOR_ADDEND + rtchan);
The vector is set to 0xA0 + channel number. The ISR receives this vector when the interrupt fires, allowing you to identify which channel triggered the interrupt when multiple channels are active.
Clearing Initial State
Before enabling interrupts, the application reads and clears the status registers to prevent a stale interrupt from triggering immediately:
swResult = naibrd_1760_GetIntStatus(deviceNumber, &hwstatus, &bcstatus, &rtstatus, &mtstatus);
swResult = naibrd_1553_ClearIntLatch(DevNum);
Enabling RT Interrupts
Before each monitoring cycle, the application enables the "Interrupt When Accessed" (IWA) mask for the RT:
swResult = naibrd_1760_SetIrqManipulate(DevNum, 0x1, INTERRUPT_TYPE_MASK_HW, INTERRUPT_TYPE_MASK_BC, INTERRUPT_TYPE_MASK_RT, INTERRUPT_TYPE_MASK_MT, NULL);
The first parameter (0x1) enables interrupts. The mask parameters control which interrupt sources are active:
-
INTERRUPT_TYPE_MASK_HW(0) — no hardware interrupts enabled. -
INTERRUPT_TYPE_MASK_BC(0) — no BC interrupts enabled. -
INTERRUPT_TYPE_MASK_RT(NAI_1760_RT_INTERRUPT_MASK_IWA1) — "Interrupt When Accessed" on RT channel 1. -
INTERRUPT_TYPE_MASK_MT(0) — no MT interrupts enabled.
After each monitoring cycle, interrupts are disabled by passing 0x0 as the enable parameter and 0xFFFF for all masks:
swResult = naibrd_1760_SetIrqManipulate(DevNum, 0x0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, NULL);
|
Important
|
Common interrupt configuration issues you may encounter:
|
Data Block Setup
The RT data block configuration follows the same pattern as other RT samples. The sample creates one Rx data block and two Tx data blocks (for ping-pong buffering), mapped to the user-specified subaddress.
The Rx block mapping uses NAI_1553_RT_DATABLOCK_IRQ_END_OF_MESSAGE instead of 0 for the IRQ parameter, which enables end-of-message interrupts at the subaddress level:
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_RX, sa, NAI_1553_RT_MESSAGE_TYPE_RX, NAI_1553_RT_DATABLOCK_IRQ_END_OF_MESSAGE, 1);
This tells the hardware to generate an interrupt each time a complete Rx message is received on this subaddress.
ISR and Message Processing
The ISR
The ISR (myIsr) is kept minimal to avoid spending time in the interrupt context. It stores the interrupt vector, sets a global flag, and increments a counter:
static void myIsr(void* param, uint32_t vector)
{
receivedVector = vector;
irqFlag = 1;
irqCount++;
}
On VxWorks, the ISR also retrieves the vector from the platform-specific API and clears the interrupt at the hardware level. All message processing is done in the main loop, not in the ISR.
Interrupt-Driven Message Processing
The ProcessMessages() function polls irqFlag in a loop. When an interrupt is received, it:
-
Resets
irqFlagto 0. -
Displays the received interrupt vector.
-
Reads and clears the interrupt status registers with
naibrd_1760_GetIntStatus(). -
Identifies the interrupt source (IWA, Time Tag Match, or other).
-
Clears the interrupt latch with
naibrd_1553_ClearIntLatch(). -
Retrieves and decodes the message from the RT stack.
if (irqFlag)
{
irqFlag = 0;
printf("\nReceived Vector: 0x%08X", receivedVector);
swResult = naibrd_1760_GetIntStatus(deviceNumber, &hwstatus, &bcstatus, &rtstatus, &mtstatus);
if (rtstatus & NAI_1760_RT_INTERRUPT_MASK_IWA1)
{
printf("\nInterrupt When Accessed. IrqCount = %d\n", irqCount);
}
swResult = naibrd_1553_ClearIntLatch(deviceNumber);
swResult = naibrd_1553_RtMessageGetFromStackRaw(deviceNumber, wsBuffer, NAI_1553_MAX_MESSAGE_SIZE_RT);
if (swResult > 0)
{
swResult = naibrd_1553_RtMessageDecodeRaw(deviceNumber, wsBuffer, &DecodedMsgStruct);
/* ... display decoded message ... */
}
}
The clear-latch step is essential — without it, the next interrupt will not be generated because the latch remains asserted.
|
Important
|
Common message processing issues you may encounter:
|
Cleanup
After the monitoring loop ends, the application disables interrupts, uninstalls the ISR, and frees the device:
swResult = naibrd_1760_SetIrqManipulate(DevNum, 0x0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, NULL);
swResult = naibrd_UninstallISR(cardIndex);
swResult = naibrd_1553_Free(DevNum);
Always uninstall the ISR before freeing the device. If the ISR remains installed while the device is freed, a subsequent interrupt could call into freed resources.
Troubleshooting Reference
This table summarizes common errors and symptoms covered in the sections above. For detailed context on each entry, refer to the relevant section. Consult the FTJ-FTK Manual for hardware-specific diagnostic procedures.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
No board found or connection timeout |
Board not powered, missing configuration file, network issue |
Verify hardware and configuration. If file doesn’t exist, configure and save from board menu. |
Device open or initialization failure |
Wrong card/module/channel, or device already in use |
Verify parameters. Close other applications using this channel. |
No interrupts received |
Wrong interrupt steering, Ethernet connection, or interrupts not enabled |
Verify steering matches connection type. Ensure |
Only one interrupt received |
Interrupt latch not cleared after processing |
Call |
Stale interrupt on startup |
Status registers not cleared before enabling interrupts |
Read |
Unexpected interrupt vector |
Vector not set correctly or multiple channels generating interrupts |
Verify |
Interrupt fires but no RT message available |
Interrupt source is not an RT access (e.g., time tag match or hardware interrupt) |
Check |
ISR crash after device free |
ISR still installed when device was freed |
Always call |
Wrong module type for this sample |
Using FT1-FT9 instead of FTJ/FTK |
Use M1553_RT_Interrupt for non-1760 modules. This sample uses |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — M1760_RT_Interrupt.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.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"
/* Common 1553 Sample Program include files */
#include "nai_1553_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_1553.h"
#include "functions/naibrd_1760.h"
#define INTERRUPT_VECTOR_ADDEND 0xA0
#define INTERRUPT_TYPE_MASK_HW 0 /* NAI_1760_HARDWARE_INTERRUPT_MASK_RT1TTM */
#define INTERRUPT_TYPE_MASK_BC 0
#define INTERRUPT_TYPE_MASK_RT NAI_1760_RT_INTERRUPT_MASK_IWA1
#define INTERRUPT_TYPE_MASK_MT 0
static const int8_t *CONFIG_FILE = (int8_t *)"default_1760_RTInterrupt.txt";
/* Function prototypes */
static bool_t Run_M1760_RT_Interrupt(int32_t cardIndex, int32_t module, uint32_t modid);
static int32_t ProcessMessages(int32_t duration);
static void myIsr(void* param, 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 = 3;
static const int16_t DEF_RT_DEV_NUM = 3;
static const uint8_t DEF_RT_ADDRESS = 1;
static const uint8_t DEF_RT_SUBADDR = 2;
static const uint16_t DEF_RT_RX_BUF_TYPE = NAI_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;
/**************************************************************************************************************/
/**
<summary>
NOTE: This sample code is only intended to be used with FTJ/FTK modules. For FT[1-9] modules, please refer to
the M1553_RT_Interrupt sample code.
The purpose of the M1760_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 "interrupt when accessed" 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_ON_BOARD_0 for ARM1).
Ethernet communication will not work with this application.
The following routines are called to configure and enable interrupts on the 1553 and hook the interrupt service
routine (ISR).
- naibrd_1553_SetIrqConfig
- naibrd_1760_SetIrqManipulate
- naibrd_InstallISR
- naibrd_1553_SetInterruptSteering
- naibrd_1553_SetIntVector
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 M1760_RT_Interrupt(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_M1760_RT_Interrupt(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;
}
static bool_t Run_M1760_RT_Interrupt(int32_t cardIndex, int32_t module, uint32_t modid)
{
/* Variables */
bool_t bQuit = FALSE;
int32_t rtchan;
uint8_t rtaddr;
uint8_t sa = DEF_RT_SUBADDR;
int16_t DevNum = 0;
int32_t swResult;
uint16_t nDataBlockType = 0;
bool_t bContinue = TRUE;
int32_t duration;
bool_t bSoftwareRTAddr;
uint16_t hwstatus, rtstatus, bcstatus, mtstatus;
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;
}
printf("Enter Subaddress\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 # */
swResult = naibrd_1553_Open(cardIndex, module, rtchan, DevNum);
if(swResult)
{
bQuit = TRUE;
printf("Error: naibrd_1553_Open %d", swResult);
return bQuit;
}
/* Initialize Device */
swResult = naibrd_1553_Initialize(DevNum,NAI_1553_ACCESS_CARD,NAI_1553_MODE_RT,0,0,0);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_Initialize %d", swResult);
return bQuit;
}
if (modid == NAI_MODULE_ID_FT8)
{
/* Simplex Enable */
naibrd_1553_WriteAuxReg(DevNum, 0x3, 0x4000);
}
/* Get RT Address Source from user */
bQuit = Get1553RTAddressSource(TRUE, &bSoftwareRTAddr);
if (bQuit)
{
return bQuit;
}
if (bSoftwareRTAddr)
{
/* Set RTAD_SW_EN and RT_ADR_LAT in software */
swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0018);
/* Set RT address */
swResult = naibrd_1553_RtSetAddress(DevNum, rtaddr);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtSetAddress %d", swResult);
return bQuit;
}
}
else
{
/* Unset RTAD_SW_EN and set RT_ADR_LAT in software */
swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0008);
}
/***********************/
/*** INTERRUPT SETUP ***/
/***********************/
/* Reset Interrupt counter */
irqCount = 0;
/* Setup Interrupts in Core with Level Detection and Auto Clear (read clears interrupt statuses) */
swResult = naibrd_1553_SetIrqConfig(DevNum, NAI_1553_IRQ_MODE_PULSE, NAI_1553_IRQ_AUTO_CLEAR);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_SetIrqConfig %d", swResult);
return bQuit;
}
/* Hook the interrupt service routine */
swResult = naibrd_InstallISR(cardIndex, NAIBRD_IRQ_ID_ON_BOARD_0, (nai_isr_t)myIsr, NULL); /* NAIBRD_IRQ_ID_ON_BOARD_0 for Onboard, NAIBRD_IRQ_ID_DONT_CARE for everything else */
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_InstallISR %d", swResult);
return bQuit;
}
/* Set the Interrupt Steering to Onboard */
swResult = naibrd_1553_SetInterruptSteering( DevNum, NAIBRD_INT_STEERING_ON_BOARD_0 ); /* NAIBRD_INT_STEERING_CPCI_APP, NAIBRD_INT_STEERING_PCIE_APP for PCIe, NAIBRD_INT_STEERING_ON_BOARD_0 for Onboard */
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_SetInterruptSteering %d", swResult);
return bQuit;
}
/* Set the Interrupt Vector (The vector is set as channel number plus 0xA0) */
swResult = naibrd_1553_SetIntVector( DevNum, INTERRUPT_VECTOR_ADDEND + rtchan );
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_SetIntVector %d", swResult);
return bQuit;
}
/* Read core status registers to clear statuses */
swResult = naibrd_1760_GetIntStatus(deviceNumber, &hwstatus, &bcstatus, &rtstatus, &mtstatus);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1760_GetIntStatus %d", swResult);
return bQuit;
}
/* Clear Interrupt Latch Bit */
swResult = naibrd_1553_ClearIntLatch(DevNum);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_ClearIntLatch %d", swResult);
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 */
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_RX, nDataBlockType, NULL, 0);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockCreate %d", swResult);
return bQuit;
}
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_RX, sa, NAI_1553_RT_MESSAGE_TYPE_RX, NAI_1553_RT_DATABLOCK_IRQ_END_OF_MESSAGE, 1);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockMapToSubaddress %d", swResult);
return bQuit;
}
/* Create two Tx Buffer data blocks and map the first to the desired subaddress */
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX1, NAI_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockCreate %d", swResult);
return bQuit;
}
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX2, NAI_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockCreate %d", swResult);
return bQuit;
}
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_TX1, sa, NAI_1553_RT_MESSAGE_TYPE_TX, 0, 1);
if(swResult < 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockMapToSubaddress %d", swResult);
return bQuit;
}
currDataBlock = DATA_BLOCK_ID_TX1;
/*******************/
/*** RUN 1553 RT ***/
/*******************/
while (bContinue)
{
printf("\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 */
swResult = naibrd_1760_SetIrqManipulate(DevNum, 0x1, INTERRUPT_TYPE_MASK_HW, INTERRUPT_TYPE_MASK_BC, INTERRUPT_TYPE_MASK_RT, INTERRUPT_TYPE_MASK_MT, NULL);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_SetIrqManipulate %d", swResult);
return bQuit;
}
/* Start RT */
swResult = naibrd_1553_RtStart(DevNum);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtStart %d", swResult);
return bQuit;
}
/* Process New Messages */
ProcessMessages(duration);
/* Stop RT */
swResult = naibrd_1553_RtStop(DevNum);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtStop %d", swResult);
return bQuit;
}
/* Disable Interrupts */
swResult = naibrd_1760_SetIrqManipulate(DevNum, 0x0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, NULL);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_SetIrqManipulate %d", swResult);
return bQuit;
}
}
else
bContinue = FALSE;
}
/* Uninstall ISR */
swResult = naibrd_UninstallISR(cardIndex);
/* Free 1553 Device */
swResult = naibrd_1553_Free(DevNum);
if(swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_Free %d", swResult);
return bQuit;
}
return bQuit;
}
static void myIsr(void* param, uint32_t vector)
{
#if defined (WIN32)
UNREFERENCED_PARAMETER(param);
UNREFERENCED_PARAMETER(vector);
#endif
#if defined (__VXWORKS__)
/* Get the vector that caused the interrupt */
vector = nai_Onboard_GetInterruptVector();
logMsg("\nvector = %d deviceNumber = %d\n", vector, deviceNumber, 2, 3, 4, 5);
/* Clear Interrupt */
nai_Onboard_ClearInterrupt();
#endif
receivedVector = vector;
/* Set the global interrupt flag */
irqFlag = 1;
irqCount++;
}
static int ProcessMessages(int32_t duration)
{
time_t end;
uint32_t swResult;
int32_t i;
naiDecodedMessageStructure DecodedMsgStruct;
uint16_t wsBuffer[72] = { 0x0000 };
int32_t count = 0;
uint16_t hwstatus, rtstatus, bcstatus, mtstatus;
end = time(NULL) + duration;
/* 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 (time(NULL) < end)
{
if (irqFlag)
{
irqFlag = 0;
/* Display the Interrupt Vector */
printf("\nReceived Vector: 0x%08X", receivedVector);
/* Read to clear status registers */
swResult = naibrd_1760_GetIntStatus(deviceNumber, &hwstatus, &bcstatus, &rtstatus, &mtstatus);
if (swResult != NAI_SUCCESS)
{
printf("\nERROR: naibrd_1760_GetIntStatus - %d\n", swResult);
}
if (rtstatus & NAI_1760_RT_INTERRUPT_MASK_IWA1)
{
printf("\nInterrupt When Accessed. IrqCount = %d\n", irqCount);
}
else if (hwstatus & NAI_1760_HARDWARE_INTERRUPT_MASK_RT1TTM)
{
printf("\nTime Tag Match interrupt. IrqCount = %d\n", irqCount);
}
else
{
printf("\nOther interrupt triggered. hwstatus=0x%04X rtstatus=0x%04X bcstatus=0x%04X mtstatus=0x%04X IrqCount=%d\n", hwstatus, rtstatus, bcstatus, mtstatus, irqCount);
}
/* Clear Latch Bit */
swResult = naibrd_1553_ClearIntLatch(deviceNumber);
if (swResult != NAI_SUCCESS)
{
printf("\nERROR: naibrd_1553_ClearIntLatch - %d\n", swResult);
}
/* Get Data */
/* If the stack pointer has updated (new message arrived), read one message at a time */
swResult = naibrd_1553_RtMessageGetFromStackRaw(deviceNumber, wsBuffer, NAI_1553_MAX_MESSAGE_SIZE_RT);
if (swResult < 0)
{
printf("ERROR: naibrd_1553_RtMessageGetFromStackRaw %d\n\n", swResult);
}
else if (swResult > 0)
{
/* Decode Raw Message */
swResult = naibrd_1553_RtMessageDecodeRaw(deviceNumber, wsBuffer, &DecodedMsgStruct);
if (swResult < 0)
{
printf("ERROR: naibrd_1553_RtMessageDecodeRaw %d\n\n", swResult);
}
if ((DecodedMsgStruct.wCommandWord1 & 0x0400) != 0x0400) /* If this is a Rx message */
{
printf("Rx Msg Received\n");
printf("\n\nDecoded Message:\n\n");
printf("Block Status - 0x%04X\n", DecodedMsgStruct.wBlockStatus);
printf("Time Tag - 0x%04X\n", DecodedMsgStruct.wTimeTag);
printf("Command Word - 0x%04X\n", DecodedMsgStruct.wCommandWord1);
printf("Data Word Count - 0x%04X\n", DecodedMsgStruct.wDataWordCount);
printf("Data:");
for (i = 0; i < DecodedMsgStruct.wDataWordCount; i++)
{
if (i % 8 == 0)
{
printf("\n");
}
printf("0x%04X ", DecodedMsgStruct.waData[i]);
}
printf("count: %d\n", count++);
printf("\n\n");
}
else
{
printf("Tx Msg Received\n");
}
}
}
#if defined (__VXWORKS__)
taskDelay(1);
#endif
}
return 1;
}