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

M1553 BC Interrupt

M1553 BC Interrupt

Explanation
*About the Code*

This C code is a sample application provided by North Atlantic Industries (NAI) for interacting with their embedded function modules, specifically the 1553 Bus Controller (BC). The code is structured to demonstrate how to set up, configure, run, and handle interrupts for a 1553 BC using the NAI library. Below is a detailed walkthrough of the code to help understand its structure and functionality.

*Headers and Libraries*

- **Standard Headers**:
  - `<stdio.h>`: Standard I/O operations.
  - `<stdlib.h>`: Standard library functions.
  - `<string.h>`: String manipulation functions.
  - `<time.h>`: Time-related functions.

- **VxWorks Specific Header** (conditional inclusion):
  - `taskLib.h`: Task related library for VxWorks OS.

- **NAI Sample Program Headers**:
  - `"include/naiapp_boardaccess_menu.h"`
  - `"include/naiapp_boardaccess_query.h"`
  - `"include/naiapp_boardaccess_access.h"`
  - `"include/naiapp_boardaccess_display.h"`
  - `"include/naiapp_boardaccess_utils.h"`

- **NAI 1553 Specific Headers**:
  - `"nai_1553_utils.h"`
  - `"BC/nai_1553_bc_utils.h"`

- **NAI Board Headers**:
  - `"nai.h"`
  - `"naibrd.h"`
  - `"functions/naibrd_1553.h"`

*Definitions*

- **Interrupt and Message Constants**:
  - `INTERRUPT_VECTOR_ADDEND`: Offset for the interrupt vector.
  - `INTERRUPT_TYPE_MASK`: Mask for BC end of message interrupt.
  - `CONFIG_FILE`: Default configuration file.

- **Message IDs**: `MSG1`, `MSG2`, `MSG3`, `NUM_MSGS`.
- **Opcodes**: `OP1` to `OP6`.
- **Frame Constants**: `MNR1`, `MNR2`, `MNR3`, `MJR`.
- **Data Block Numbers**: `DBLK1`, `DBLK2`, `DBLK3`.

- **Default Settings**: `DEF_M1553_CARD_INDEX`, `DEF_M1553_MODULE`, `DEF_M1553_CHANNEL`, `DEF_M1553_DEVNUM`.
- **RT Address/Subaddresses**: `RT_ADDRESS`, `RT_SUBADDRESS1`, `RT_SUBADDRESS2`, `RT_SUBADDRESS3`.
- **Word Counts**: `WORDCOUNT1`, `WORDCOUNT2`, `WORDCOUNT3`.

*Global Variables*

- `irqFlag`: Flag for interrupt detection.
- `irqCount`: Counter for the number of interrupts.
- `receivedVector`: Stores the received interrupt vector.

*Main Function and Overview*

*`main` or `M1553_BC_Interrupt`*

The main function begins by displaying a board menu loaded from `CONFIG_FILE`. It then enters a loop where it prompts the user to select card and module indices before calling `Run_M1553_BC_Interrupt`. If the user chooses to quit, the loop terminates.

*`Run_M1553_BC_Interrupt`*

This function checks whether the selected module supports 1553 functionality (`IsFTx1553`). If supported, it queries the user for the channel number and calls `RunBCInterrupt`.

*`RunBCInterrupt`*

This function initializes and configures the 1553 BC, sets up interrupts, and manages the BC schedule with several minor and major frames. It writes data blocks, creates messages and commands, and sets up the BC frame schedule. The BC sends messages at specific rates using a sequence of minor frames to achieve the desired periodicity:

- Minor Frame 1: Messages 1, 2, 3 (every 250 ms)
- Minor Frame 3: Message 1 (every 250 ms)
- Minor Frame 2: Messages 1, 2 (every 250 ms)

The frames are arranged to meet the specified rates: `Minor Frame 1 | Minor Frame 3 | Minor Frame 2 | Minor Frame 3`.

*Interrupt Handling*

- **Interrupt Setup**:
  - `naibrd_1553_SetIrqConfig`: Configures the interrupt.
  - `naibrd_InstallISR`: Hooks the ISR.
  - `naibrd_1553_SetInterruptSteering`: Configures interrupt steering.
  - `naibrd_1553_SetIntVector`: Associates a unique interrupt vector.

- **ISR (`myIsr`)**: Sets a global flag and increments the interrupt counter upon an interrupt.

*Data Handling*

The application periodically checks the global interrupt flag in a loop. Upon an interrupt, it identifies the device and checks which message was sent using the `naibrd_1553_BcMessageGetByIdDecoded` function.

*Functions Used*

Some key functions from the NAI library used in this code include:

- **Device Configuration**:
  - `ConfigDevice`
  - `DisplayDeviceCfg`
  - `GetBoardSNModCfg`
  - `CheckModule`

- **1553 BC Configuration and Control**:
  - `naibrd_1553_Open`
  - `naibrd_1553_WriteAuxReg`
  - `naibrd_1553_Initialize`
  - `naibrd_1553_SetIrqConfig`
  - `naibrd_InstallISR`
  - `naibrd_1553_SetInterruptSteering`
  - `naibrd_1553_SetIntVector`
  - `naibrd_1553_GetIntStatus`
  - `naibrd_1553_ClearIntLatch`
  - `naibrd_1553_BcDataBlockCreate`
  - `naibrd_1553_BcMessageCreateBcToRt`
  - `naibrd_1553_BcMessageCreateRtToBc`
  - `naibrd_1553_BcCommandCreate`
  - `naibrd_1553_BcFrameCreate`
  - `naibrd_1553_BcDataBlockWrite`
  - `naibrd_1553_SetIrqManipulate`
  - `naibrd_1553_BcStart`
  - `naibrd_1553_BcStop`
  - `naibrd_1553_Free`

*Conclusions*

This sample application provides a comprehensive demonstration of setting up, running, and handling interrupts for a 1553 Bus Controller using the NAI library. It illustrates how to manage different message rates, configure interrupts, and handle BC schedules effectively.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#if defined (__VXWORKS__)
 #include "taskLib.h"
#endif
/* Common Sample Program include files */
#include "include/naiapp_boardaccess_menu.h"
#include "include/naiapp_boardaccess_query.h"
#include "include/naiapp_boardaccess_access.h"
#include "include/naiapp_boardaccess_display.h"
#include "include/naiapp_boardaccess_utils.h"

/* Common 1553 Sample Program include files */
#include "nai_1553_utils.h"
#include "BC/nai_1553_bc_utils.h"

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_1553.h"

#define INTERRUPT_VECTOR_ADDEND     0xA0
#define INTERRUPT_TYPE_MASK         NAI_1553_INT_REG1_MASK_BC_END_OF_MESSAGE	   /* NAI_1553_INT_REG1_MASK_TIME_TAG_ROLLOVER */	   /* NAI_1553_INT_REG1_MASK_BC_END_OF_MESSAGE */

static const int8_t *CONFIG_FILE = (int8_t *)"default_1553BC_Interrupt.txt";

/* Function prototypes */
static bool_t Run_M1553_BC_Interrupt(int32_t cardIndex, int32_t module, uint32_t modid);
static bool_t RunBCInterrupt(int32_t cardIndex, int32_t module, int32_t channel);
static void myIsr(void* param, 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;

/**************************************************************************************************************/
/**
<summary>
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
end-of-message interrupt has been generated by the BC channel. When this occurs, the while loop in the main thread
checks each 1553 message in the schedule to see if it was sent out. (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_1553_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 M1553_BC_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_M1553_BC_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_M1553_BC_Interrupt(int32_t cardIndex, int32_t module, uint32_t modid)
{
   bool_t bQuit = FALSE;
   int32_t channel;
   int32_t MaxChannel = 4;

   if (IsFTx1553(modid))
   {
      MaxChannel = 4;
      bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_M1553_CHANNEL, &channel);
      if (!bQuit)
      {
         bQuit = RunBCInterrupt(cardIndex, module, channel);
      }
   }
   else
      printf("\nThis module does not support 1553 functionality.\n");

   return bQuit;
}

static bool_t RunBCInterrupt(int32_t cardIndex, int32_t module, int32_t channel)
{
   int32_t i;
   bool_t bQuit = FALSE;
   uint32_t usBus;
   nai_1553_t status;
   uint16_t increment = 0;
   uint16_t aData[32] = {0};
   int16_t aOpCodes[20] = { 0 };
   bool_t bContinue = TRUE;
   int16_t devnum;
   naiDecodedMessageStructure DecodedMsgStruct;
   bool_t bSoftware;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   uint16_t intStatus1, intStatus2;
   int32_t counter = 1000;
   int16_t msgList[NUM_MSGS] = {MSG1, MSG2, MSG3};
   int32_t msgIdx;

   /* 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(TRUE, &bSoftware);
         if (!bQuit)
         {
            /* Open 1553 Device(s) */
            status = naibrd_1553_Open(cardIndex, module, channel, devnum);
            if(status != 0)
            {
               printf("Error: naibrd_1553_Open Ch %d, status = %d", channel, status);
               return TRUE;
            }

            if (bSoftware)
            {
               /* Override external BC_DISABLE and M1760 (In order to configure as BC, this needs to */
               /* be set if BC_DISABLE and M1760 pins are not driven high) */
               naibrd_1553_WriteAuxReg(devnum, 0x2, 0xA000);
            }
            else
            {
               /* Do not override external BC_DISABLE and M1760 Inputs */
               naibrd_1553_WriteAuxReg(devnum, 0x2, 0);
            }

            /* Reset Device */
            naibrd_1553_WriteAuxReg(devnum, 0x1, 1);
            nai_msDelay(1);
            naibrd_1553_WriteAuxReg(devnum, 0x1, 0);

            /* Initialize 1553 Device(s) */
            status = naibrd_1553_Initialize(devnum, NAI_1553_ACCESS_CARD,NAI_1553_MODE_BC,0,0,0);
            if(status != 0)
            {
               printf("Error: naibrd_1553_Initialize Ch %d, status = %d", channel, status);
               return TRUE;
            }

            /***********************/
            /*** INTERRUPT SETUP ***/
            /***********************/
            /* Reset Interrupt counter */
            irqCount = 0;

            /* Setup Interrupts in Core with Level Detection and Auto Clear (read clears interrupt statuses) */
            status = naibrd_1553_SetIrqConfig(devnum, NAI_1553_IRQ_MODE_LEVEL, NAI_1553_IRQ_AUTO_CLEAR);
            if(status != 0)
            {
               bQuit = TRUE;
               printf("Error: naibrd_1553_SetIrqConfig  %d", status);
               return bQuit;
            }

            /* Hook the interrupt service routine */
            status = naibrd_InstallISR(cardIndex, NAIBRD_IRQ_ID_DONT_CARE, (nai_isr_t)myIsr, NULL); /* NAIBRD_IRQ_ID_ON_BOARD_0 for Onboard, NAIBRD_IRQ_ID_DONT_CARE for everything else */
            if(status != 0)
            {
               bQuit = TRUE;
               printf("Error: naibrd_InstallISR  %d", status);
               return bQuit;
            }

            /* Set the Interrupt Steering to Onboard */
            status = naibrd_1553_SetInterruptSteering( devnum, NAIBRD_INT_STEERING_CPCI_APP );	/* NAIBRD_INT_STEERING_CPCI_APP, NAIBRD_INT_STEERING_PCIE_APP for PCIe, NAIBRD_INT_STEERING_ON_BOARD_0 for Onboard */
            if(status != 0)
            {
               bQuit = TRUE;
               printf("Error: naibrd_1553_SetInterruptSteering  %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 = TRUE;
               printf("Error: naibrd_1553_SetIntVector  %d", status);
               return bQuit;
            }

            /* Read core status registers to clear statuses */
            status = naibrd_1553_GetIntStatus(devnum, &intStatus1, &intStatus2);
            if(status != 0)
            {
               bQuit = TRUE;
               printf("Error: naibrd_1553_GetIntStatus  %d", status);
               return bQuit;
            }

            /* Clear Interrupt Latch Bit */
            status = naibrd_1553_ClearIntLatch(devnum);
            if(status != 0)
            {
               bQuit = TRUE;
               printf("Error: naibrd_1553_ClearIntLatch  %d", status);
               return bQuit;
            }

            /*************************/
            /*** BC SCHEDULE SETUP ***/
            /*************************/
            /* Create BC Data Block 1 */
            status = naibrd_1553_BcDataBlockCreate(devnum, DBLK1, NAI_1553_BC_DATABLOCK_SINGLE, NULL, 0);
            if(status != 0)
            {
               printf("Error: naibrd_1553_BcDataBlockCreate Ch %d, status = %d", channel, status);
               return TRUE;
            }

            /* Create BC Data Block 2 */
            status = naibrd_1553_BcDataBlockCreate(devnum, DBLK2, NAI_1553_BC_DATABLOCK_SINGLE, NULL, 0);
            if(status != 0)
            {
               printf("Error: naibrd_1553_BcDataBlockCreate Ch %d, status = %d", channel, status);
               return TRUE;
            }

            /* Create BC Data Block 3 */
            status = naibrd_1553_BcDataBlockCreate(devnum, DBLK3, NAI_1553_BC_DATABLOCK_SINGLE, NULL, 0);
            if(status != 0)
            {
               printf("Error: naibrd_1553_BcDataBlockCreate Ch %d, status = %d", channel, status);
               return TRUE;
            }

            /* Create BC to RT Message 1 */
            status = naibrd_1553_BcMessageCreateBcToRt(devnum, MSG1, DBLK1, RT_ADDRESS, RT_SUBADDRESS1, WORDCOUNT1, 0, usBus | NAI_1553_BC_CTRL_END_OF_MESSAGE_INTERRUPT_ENABLED);
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcMessageCreateBcToRt status = %d", status);
               return TRUE;
            }

            /* Create RT to BC Message 2 */
            status = naibrd_1553_BcMessageCreateRtToBc(devnum, MSG2, DBLK2, RT_ADDRESS, RT_SUBADDRESS2, WORDCOUNT2, 0, usBus | NAI_1553_BC_CTRL_END_OF_MESSAGE_INTERRUPT_ENABLED);
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcMessageCreateRtToBc status = %d", status);
               return TRUE;
            }

            /* Create BC to RT Message 3 */
            status = naibrd_1553_BcMessageCreateBcToRt(devnum, MSG3, DBLK3, RT_ADDRESS, RT_SUBADDRESS3, WORDCOUNT3, 0, usBus | NAI_1553_BC_CTRL_END_OF_MESSAGE_INTERRUPT_ENABLED);
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcMessageCreateBcToRt status = %d", status);
               return TRUE;
            }

            /* Create Execute Message Command 1 */
            status = naibrd_1553_BcCommandCreate(devnum, OP1, NAI_1553_OPCODE_EXECUTE_MESSAGE, NAI_1553_OPCODE_COND_ALWAYS, MSG1, 0, 0);
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
               return TRUE;
            }

            /* Create Execute Message Command 2 */
            status = naibrd_1553_BcCommandCreate(devnum, OP2, NAI_1553_OPCODE_EXECUTE_MESSAGE, NAI_1553_OPCODE_COND_ALWAYS, MSG2, 0, 0);
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
               return TRUE;
            }

            /* Create Execute Message Command 3 */
            status = naibrd_1553_BcCommandCreate(devnum, OP3, NAI_1553_OPCODE_EXECUTE_MESSAGE, NAI_1553_OPCODE_COND_ALWAYS, MSG3, 0, 0);
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
               return 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_BcFrameCreate(devnum, MNR1, NAI_1553_BC_FRAME_MINOR, aOpCodes, 3, 2500, 0);     /* 2500 for 250 ms minor frame (1 unit is 0.1 ms) */
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
               return TRUE;
            }

            /* Create Minor Frame 2 */
            aOpCodes[0] = OP1;      /* Execute Message 1 Command */
            aOpCodes[1] = OP2;      /* Execute Message 2 Command */
            status = naibrd_1553_BcFrameCreate(devnum, MNR2, NAI_1553_BC_FRAME_MINOR, aOpCodes, 2, 2500, 0);     /* 2500 for 250 ms frame */
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
               return TRUE;
            }

            /* Create Minor Frame 3 */
            aOpCodes[0] = OP1;      /* Execute Message 1 Command */
            status = naibrd_1553_BcFrameCreate(devnum, MNR3, NAI_1553_BC_FRAME_MINOR, aOpCodes, 1, 2500, 0);     /* 2500 for 250 ms frame */
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
               return TRUE;
            }

            /* Create Call Subroutine Command 1 */
            status = naibrd_1553_BcCommandCreate(devnum, OP4, NAI_1553_OPCODE_CALL_SUBROUTINE, NAI_1553_OPCODE_COND_ALWAYS, MNR1, 0, 0);
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
               return TRUE;
            }

            /* Create Call Subroutine Command 2 */
            status = naibrd_1553_BcCommandCreate(devnum, OP5, NAI_1553_OPCODE_CALL_SUBROUTINE, NAI_1553_OPCODE_COND_ALWAYS, MNR2, 0, 0);
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
               return TRUE;
            }

            /* Create Call Subroutine Command 3 */
            status = naibrd_1553_BcCommandCreate(devnum, OP6, NAI_1553_OPCODE_CALL_SUBROUTINE, NAI_1553_OPCODE_COND_ALWAYS, MNR3, 0, 0);
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
               return TRUE;
            }

            /* Create Major Frame */
            aOpCodes[0] = OP4;   /* Minor Frame 1 */
            aOpCodes[1] = OP6;   /* Minor Frame 3 */
            aOpCodes[2] = OP5;   /* Minor Frame 2 */
            aOpCodes[3] = OP6;   /* Minor Frame 3 */
            status = naibrd_1553_BcFrameCreate(devnum,MJR,NAI_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 _BcFrameCreate() */
                                                                                                   /* function and set all minor frame    */
                                                                                                   /* times to the same duration.         */
            if (status != 0)
            {
               printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
               return TRUE;
            }

            while (bContinue)
            {
               /* Load BC data block 1 with incremental data */
               for (i = 0; i < WORDCOUNT1; i++)
               {
                  aData[i] = increment++;
               }
               status = naibrd_1553_BcDataBlockWrite(devnum, DBLK1, aData, WORDCOUNT1, 0);
               if (status != 0)
               {
                  printf("Error: naibrd_1553_BcDataBlockWrite status = %d", status);
                  return TRUE;
               }

               /* Load BC data block 3 with 0xBBCC */
               for (i = 0; i < WORDCOUNT3; i++)
               {
                  aData[i] = 0xBBCC;
               }
               status = naibrd_1553_BcDataBlockWrite(devnum, DBLK3, aData, WORDCOUNT3, 0);
               if (status != 0)
               {
                  printf("Error: naibrd_1553_BcDataBlockWrite status = %d", status);
                  return TRUE;
               }

               /* Enable BC EOM Interrupts (myIsr is only used here for compatibility with DDC, it is not used in the function) */
               status = naibrd_1553_SetIrqManipulate(devnum, 0x1, INTERRUPT_TYPE_MASK, myIsr);
               if(status != 0)
               {
                  printf("Error: naibrd_1553_SetIrqManipulate  %d", status);
                  return TRUE;
               }

               /* Start BC */
               status = naibrd_1553_BcStart(devnum,MJR,NAI_1553_BC_FRAME_RUN_FOREVER);
               if (status != 0)
               {
                  printf("Error: naibrd_1553_BcStart status = %d", status);
                  return TRUE;
               }

               counter = 1000;

               printf("BC Running for approximately 10 seconds...\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 */
                     printf("\nReceived Vector: 0x%08X", receivedVector);

                     /* If the vector value matches the vector that we assigned to the BC channel... */
                     if (receivedVector == (INTERRUPT_VECTOR_ADDEND + channel))
                     {
                        /* Read to clear status registers */
                        status = naibrd_1553_GetIntStatus(devnum, &intStatus1, &intStatus2);
                        if (status != NAI_SUCCESS)
                        {
                           printf("\nERROR: naibrd_1553_GetIntStatus - %d\n", status);
                        }

                        /* Clear Latch Bit */
                        status = naibrd_1553_ClearIntLatch(devnum);
                        if (status != NAI_SUCCESS)
                        {
                           printf("\nERROR: naibrd_1553_ClearIntLatch - %d\n", status);
                        }

                        /* If BC End of Message Interrupt triggered... */
                        if (intStatus1 & NAI_1553_INT_STS_REG1_MASK_BC_CONTROL_WORD_END_OF_MESSAGE)
                        {
                           printf("\nBC End Of Message (EOM) interrupt triggered. IrqCount = %d\n", irqCount);

                           /* The BC schedule contains three messages (MSG1, MSG2, MSG3). Check which message(s) have been sent (EOM). */
                           for (msgIdx = 0; msgIdx < NUM_MSGS; msgIdx++)
                           {
                              /* Call this function to check message complete on each message (MSG1, MSG2, MSG3). */
                              status = naibrd_1553_BcMessageGetByIdDecoded(devnum, msgList[msgIdx], &DecodedMsgStruct, 1);
                              if (status == 1)
                              {
                                 /* Message complete. Display Message information, including 1553 data. */
                                 printf("Control Word: 0x%04X\n", DecodedMsgStruct.wBcControlWord);
                                 printf("Command Word: 0x%04X\n", DecodedMsgStruct.wCommandWord1);
                                 printf("Block Status: 0x%04X\n", DecodedMsgStruct.wBlockStatus);
                                 printf("Time Tag: 0x%04X\n", DecodedMsgStruct.wTimeTag);
                                 printf("Word Count: 0x%04X\n", DecodedMsgStruct.wDataWordCount);
                                 printf("RT Status Word: 0x%04X\n", DecodedMsgStruct.wStatus1);
                                 printf("Data:");
                                 for (i = 0; i < DecodedMsgStruct.wDataWordCount; i++)
                                 {
                                    if (i % 8 == 0)
                                    {
                                       printf("\n");
                                    }
                                    printf("0x%04X ", DecodedMsgStruct.waData[i]);
                                 }
                                 printf("\n\n");
                              }
                           }
                        }
                        /* If interrupt was NOT BC End of Message Interrupt... */
                        else
                        {
                           printf("\nOther interrupt triggered. status1=0x%04X status2=0x%04X IrqCount=%d\n", intStatus1, intStatus2, irqCount);
                        }
                     }
                     else
                     {
                        printf("\n0x%08X is NOT my interrupt vector!\n", receivedVector);
                     }
                  }

                  nai_msDelay(10);
                  counter--;
               }

               /* 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)
               {
                  printf("Error: naibrd_1553_BcStop status = %d", status);
                  return TRUE;
               }

               printf("BC Halted.\n");

               printf("\nPress any key to run the BC schedule again or Q to quit.");
               bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               if (bQuit)
               {
                  bContinue = FALSE;
               }
            }
         }
      }
   }

   /* Free 1553 Device */
   status = naibrd_1553_Free(devnum);
   if (status != 0)
   {
      printf("Error: naibrd_1553_Free status = %d", status);
      return TRUE;
   }

   return bQuit;
}

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\n", vector, 1, 2, 3, 4, 5);
   /* Clear Interrupt */
   nai_Onboard_ClearInterrupt();
#endif

   receivedVector = vector;

   /* Set the global interrupt flag */
   irqFlag = 1;
   irqCount++;
}

Help Bot

X