Integrator Resources

The official home for NAI Support

Not sure where to start? Try Quick Start Guide or ask a question below!

Toggle Components with Visual Button
JavaScript Form Processing

M1760 RT Interrupt

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:

  1. 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.

  2. Query the user for a card index with naiapp_query_CardIndex().

  3. Query for a module slot with naiapp_query_ModuleNumber().

  4. Retrieve the module ID with naibrd_GetModuleID() so downstream code can adapt to the specific module variant.

  5. 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:

  • No board found — verify that the board is powered on and physically connected. Check that the configuration file lists the correct interface and address.

  • Connection timeout — confirm network settings (for Ethernet connections) or bus configuration (for PCI/PCIe). Firewalls and IP mismatches are frequent causes.

  • Invalid card or module index — indices are zero-based for cards and one-based for modules. Ensure the values you pass match your hardware setup.

  • Module not present at selected slot — the slot you selected does not contain a module. Use the board menu to verify which slots are populated.

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:

  1. 1553 Device Setup — open and initialize the device, configure the RT address.

  2. Interrupt Setup — configure interrupt mode, install ISR, set steering and vector, clear status registers.

  3. 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:

  1. RT channel and address — Get1553RTCfg() asks for the 1553 channel (default: 3) and RT address (default: 1).

  2. Subaddress — Get1553Address() asks for the subaddress to legalize for Tx and Rx (default: 2).

  3. Logical device number — Get1553LogicalDevNum() assigns a logical device handle (default: 3).

  4. RT address source — Get1553RTAddressSource() asks whether to set the RT address via software or read from external pins.

  5. Rx buffer type — Get1553RxBufferType() selects single, double, or circular buffering for Rx messages (default: double buffer).

  6. 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:

  • Device open or init failure — verify card index, module, and channel. Ensure no other process holds this device open.

  • RT address not set — if using software addressing, confirm auxiliary register 0x2 has RTAD_SW_EN set.

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:

  • No interrupts received — verify that interrupt steering matches your physical connection. Onboard applications must use NAIBRD_INT_STEERING_ON_BOARD_0; PCIe host applications must use NAIBRD_INT_STEERING_PCIE_APP. Also confirm that naibrd_1760_SetIrqManipulate() was called with the enable flag set.

  • Ethernet connections do not work — this sample requires onboard or PCIe interrupt routing. Ethernet-connected boards cannot deliver hardware interrupts to the host.

  • Stale interrupt on startup — always read status registers and clear the interrupt latch before enabling interrupts to prevent immediate spurious triggers.

  • Wrong interrupt vector — if you see unexpected vector values in the ISR, verify the vector was set correctly with naibrd_1553_SetIntVector().

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:

  1. Resets irqFlag to 0.

  2. Displays the received interrupt vector.

  3. Reads and clears the interrupt status registers with naibrd_1760_GetIntStatus().

  4. Identifies the interrupt source (IWA, Time Tag Match, or other).

  5. Clears the interrupt latch with naibrd_1553_ClearIntLatch().

  6. 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:

  • Interrupts fire but no messages decoded — the interrupt may have been triggered by something other than an RT access (e.g., time tag match). Check the status register values to identify the actual interrupt source.

  • Interrupt latch not cleared — only one interrupt received — you must call naibrd_1553_ClearIntLatch() after processing each interrupt. Without this, subsequent interrupts are suppressed.

  • High interrupt rate causes message loss — if interrupts arrive faster than the processing loop can handle them, messages may accumulate on the stack. Consider increasing processing priority or using a faster polling interval within the ISR-flagged section.

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 SetIrqManipulate() enable flag is set. Ethernet is not supported.

Only one interrupt received

Interrupt latch not cleared after processing

Call naibrd_1553_ClearIntLatch() after each interrupt.

Stale interrupt on startup

Status registers not cleared before enabling interrupts

Read naibrd_1760_GetIntStatus() and call ClearIntLatch() during initialization.

Unexpected interrupt vector

Vector not set correctly or multiple channels generating interrupts

Verify naibrd_1553_SetIntVector() was called with the correct channel-based vector.

Interrupt fires but no RT message available

Interrupt source is not an RT access (e.g., time tag match or hardware interrupt)

Check rtstatus and hwstatus from naibrd_1760_GetIntStatus() to identify the source.

ISR crash after device free

ISR still installed when device was freed

Always call naibrd_UninstallISR() before naibrd_1553_Free().

Wrong module type for this sample

Using FT1-FT9 instead of FTJ/FTK

Use M1553_RT_Interrupt for non-1760 modules. This sample uses naibrd_1760_* APIs specific to FTJ/FTK.

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;
}

Help Bot

X