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

SUM1553 BC Scheduler

SUM1553 BC Scheduler Sample Application (SSK 1.x)

Overview

The SUM1553 BC Scheduler sample application demonstrates how to configure a SUMMIT 1553 channel as a Bus Controller (BC) and run a continuous multi-message schedule using the NAI Software Support Kit (SSK 1.x). The SUMMIT 1553 core (Actel Core1553BRM) executes the schedule autonomously in hardware — your application loads the command and data blocks, starts the scheduler, and then interacts with it at its own pace.

The default schedule defines three messages per 100 ms minor frame cycle:

  1. BC-to-RT send — 32 words of data to RT address 1, subaddress 2 (Block A).

  2. RT-to-BC receive — 32 words of data from RT address 1, subaddress 2 (Block B).

  3. BC-to-RT send — 16 words of data to RT address 1, subaddress 3 (Block C).

After starting the scheduler, the BC loops through these messages indefinitely. Data blocks can be updated while the scheduler is running — the hardware picks up the new data on the next cycle.

Important

This sample uses the naibrd_SUM1553_* API for SUMMIT 1553 modules (N7, N8, NA, NB, NC). If you are using FTx modules (FT0—​FTF, FTJ, FTK), see the M1553 BC sample guides which use the naibrd_1553_* API. The two APIs target different hardware cores and are not interchangeable.

Supported Modules

This sample supports SUMMIT 1553 module types: N7, N8, NA, NB, and NC. The helper function IsSUMMIT1553(modid) is used at runtime to confirm that the selected module slot contains a supported SUMMIT 1553 device. Each SUMMIT 1553 module provides up to 2 channels.

Note
The SUM1553 BC Scheduler can run in conjunction with the SUM1553_RT_PingPong or SUM1553_RT_ProcCtrl companion samples to exercise BC and RT operations together on the same 1553 bus.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a SUMMIT 1553 module installed (N7, N8, NA, NB, or NC).

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

How to Run

Launch the SUM1553_BC_Scheduler executable from your build output directory. On startup the application looks for a configuration file (default_SUM1553_BCSched.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, you select a BC channel and the scheduler begins executing.

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 SUMMIT 1553.

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_SUM1553_BCSched.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() and pass it to Run_SUM1553_BC_Scheduler() for channel configuration.

#if defined (__VXWORKS__)
int32_t SUM1553_BC_Scheduler(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_SUM1553_BC_Scheduler(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 SUMMIT 1553 module. Use the board menu to verify which slots are populated.

Program Structure

Entry Point

The program entry point is main() on most platforms and SUM1553_BC_Scheduler() on VxWorks. Both follow the same logic: run the board menu, then loop over card/module selection until the user quits.

Module Detection

After the user selects a module slot, naibrd_GetModuleID() returns the module identifier. The helper IsSUMMIT1553(modid) (called inside Get1553BCCfg()) validates that the module is a supported SUMMIT 1553 type. SUMMIT 1553 modules provide up to 2 channels, so the BC channel number is constrained accordingly.

User Input Flow

The application walks the user through three selection steps before starting the scheduler:

  1. Card index — naiapp_query_CardIndex() prompts for the board to use.

  2. Module slot — naiapp_query_ModuleNumber() prompts for the slot containing the SUMMIT 1553 module.

  3. BC channel — Get1553BCCfg() prompts for the channel to configure as the Bus Controller (default channel 2).

Once the channel is selected, Run_SUM1553_BC_Scheduler() takes over. It resets the channel, configures it as a BC, loads the command schedule and data blocks, and starts execution.

Interactive Loop

After the scheduler starts, the hardware runs the three-message schedule continuously in the background. The application enters an interactive loop where:

  • Enter — reads back the RT-to-BC data block (Block B) and displays the received words. This lets you verify that a companion RT is responding.

  • 'U' — increments a counter and reloads the BC-to-RT data blocks (Blocks A and C) with updated values. The scheduler picks up the new data on the next cycle.

  • 'Q' — stops the BC execution and returns to the card/module selection prompt.

The scheduler runs entirely in hardware between user interactions. You can press Enter repeatedly to poll the latest RT response, or leave it running and update the transmit data whenever you are ready.

SUM1553 Command Block Architecture

The SUMMIT 1553 BC core uses a flat, sequential model for scheduling messages. Understanding this architecture is essential for reading the sample code and for designing your own schedules.

Command Blocks vs. Frames

SUM1553 organizes its schedule as a flat sequence of command blocks — up to 2048 blocks total — rather than the major/minor frame hierarchy used by M1553 FTx modules. Each command block is 8 words wide and contains:

  • An opcode that tells the hardware what action to perform.

  • One or two MIL-STD-1553 command words (depending on whether the message is RT-to-RT).

  • A data block reference identifying where transmit or receive data lives.

  • A branch target (used by branching opcodes).

  • Timing information.

Command blocks execute sequentially starting from the current command block pointer. Execution proceeds to the next block unless a branching opcode redirects it elsewhere.

Data Blocks

SUM1553 supports up to 1024 data blocks, each 32 words in size. Command blocks reference data blocks by index — a BC-to-RT command block points to the data block holding the transmit payload, while an RT-to-BC command block points to the data block where received data will be stored. Data blocks can be read or written by the host application while the scheduler is running.

Opcodes Used in This Sample

The BC Scheduler sample uses three opcodes to build its schedule:

NAI_SUM1553_OPCODE_LOAD_MINOR_FRAME_TIMER

Sets the minor frame cycle period (100 ms in this sample). This opcode does not transmit a message on the bus — it acts as a timing gate that defines how long each pass through the schedule takes. The hardware waits for the remaining frame time after all messages in the cycle have been sent.

NAI_SUM1553_OPCODE_EXEBLK_CONT

Execute the message defined by this command block, then continue to the next block. This is the primary opcode for sending and receiving 1553 messages. Each of the three messages in the sample schedule (Blocks A, B, and C) uses this opcode.

NAI_SUM1553_OPCODE_GOTO

Unconditional branch to the command block specified by the branch target field. The sample places a GOTO as the last command block, pointing back to the first block. This creates a continuous loop so the schedule repeats indefinitely.

Other Available Opcodes

Beyond the three opcodes used in this sample, SUM1553 provides additional opcodes for more advanced scheduling:

  • ENDOFLIST — terminates execution. The BC stops after processing this block.

  • SKIP — skip this command block and continue to the next one.

  • EXEBLK_BRNCH — execute the message, then branch unconditionally to the target block.

  • EXEBLK_BRNCH_COND — execute the message, then branch conditionally based on message status.

  • RETRY_COND — retry the current message on the alternate bus if the previous attempt failed.

Refer to the SUMMIT 1553 module manual for detailed descriptions of conditional branching and retry behavior.

Execution Flow

The BC execution flow follows a straightforward sequence:

  1. The host application writes command blocks and data blocks into the module memory.

  2. The host sets the command block pointer to the first block in the schedule.

  3. The host enables BC execution.

  4. The hardware begins walking through command blocks sequentially, transmitting and receiving messages as directed by each block’s opcode.

  5. When the hardware reaches the GOTO block, it branches back to the beginning of the sequence.

  6. The cycle repeats continuously until the host application stops execution.

Command Word and Control Word Macros

The SSK provides two macros for building the packed words that go into command blocks:

NAI_SUM1553_COMMAND_WORD(rt, tx, sa, wcmc)

Builds a MIL-STD-1553 command word from the RT address, transmit/receive bit, subaddress, and word count (or mode code). This is the standard 16-bit command word defined by MIL-STD-1553B.

NAI_SUM1553_BC_CTRL_WORD(opcode, retries, busa, rtrt, cond)

Builds the control word stored in the command block. This word encodes the opcode, the number of retries on failure, the bus selection (Bus A or Bus B), whether the message is RT-to-RT, and a condition code for conditional branching opcodes.

Note
If you are familiar with M1553 FTx BC architecture (major/minor frames via naibrd_1553_BcFrameCreate), SUM1553 is conceptually simpler — command blocks execute in sequence with explicit branching.

Device Initialization

Before building the command schedule, the application must reset the SUMMIT 1553 channel and place it into Bus Controller mode. This is handled by two API calls at the start of Run_SUM1553_BC_Scheduler().

First, the channel is reset and the application polls until the reset completes:

/* Reset the channel */
check_status(naibrd_SUM1553_Reset(cardIndex,module,bcchan));

/* Wait for channels to reset */
while(check_status(naibrd_SUM1553_IsResetting(cardIndex,module,bcchan,&resetting)) == NAI_SUCCESS && resetting);

Once the reset finishes, the channel is configured as a Bus Controller:

check_status(naibrd_SUM1553_SetMode(cardIndex,module,bcchan,NAI_SUM1553_OPSTATUS_BC_MODE)); /* Configure as BC */
Note
SUM1553 device initialization is simpler than M1553 FTx initialization. There is no device open or logical device allocation, no auxiliary register configuration, and no platform-specific reset delay. The card index, module slot, and channel number are passed directly to every API call.
Important
  • Reset not completing — the hardware is not responding. Verify that the module is present and the card connection is active. A stuck reset may indicate a hardware fault or a module that was not properly initialized at the board level.

  • Mode set failure — the channel may already be in use by another application or configured in a mode that does not support BC operation. Ensure no other process holds the channel and that the module type supports Bus Controller mode.

Message Schedule Configuration

After device initialization, the application builds the five-command schedule that the BC hardware will execute in a continuous loop. Each command is loaded into a sequential command block using naibrd_SUM1553_BC_LoadCmdBlock(), and messages that carry data also load an associated data block via naibrd_SUM1553_BC_LoadDataBlock().

The complete schedule timeline is:

Timer(100ms) → Msg1(BC→RT, SA2, 32w) → Msg2(RT→BC, SA2, 32w) → Msg3(BC→RT, SA3, 16w) → GOTO 0 → repeat

Macro Reference

The two macros used throughout this section pack multiple fields into single 16-bit or 32-bit words:

NAI_SUM1553_BC_CTRL_WORD(opcode, retries, busa, rtrt, cond)

Builds the control word for a command block. The opcode field selects the action (timer load, execute-and-continue, goto, etc.). retries sets the number of automatic retries on failure (1 in this sample). busa selects Bus A (1) or Bus B (0). rtrt indicates an RT-to-RT transfer when set to 1 (0 for all messages in this sample). cond provides a condition code for conditional branching opcodes (0 = unconditional).

NAI_SUM1553_COMMAND_WORD(rt, tx, sa, wcmc)

Builds a standard MIL-STD-1553 command word. rt is the remote terminal address (1 in this sample). tx is the transmit/receive bit — 0 means the BC is transmitting to the RT (BC-to-RT), 1 means the RT is transmitting to the BC (RT-to-BC). sa is the subaddress. wcmc is the word count (or mode code for SA 0 and SA 31).

Command 0: Minor Frame Timer Gate

The first command block sets the minor frame period to 100,000 microseconds (100 ms). This is a timing-only command — it does not produce any bus traffic. The hardware uses this value to pace the schedule: after all messages in the frame complete, the BC waits until the frame timer expires before starting the next pass.

/* Load Minor Frame Timers to 100000 us (100 ms) */
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_LOAD_MINOR_FRAME_TIMER,1,1,0,0);
cmd1 = 0;
cmd2 = 0;
datablocknum = 0;
branchblock = 0;
timerus = 100000;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));

Because this is a timer command and not a message, both command words (cmd1, cmd2) are zero and no data block is referenced.

Command 1: BC-to-RT Send (SA 2, 32 Words — Block A)

The first message command sends 32 words from the BC to RT address 1, subaddress 2. The control word uses EXEBLK_CONT so that execution continues to the next command block after this message completes. The command word sets tx=0, indicating a BC-to-RT direction.

/* BCRT Message with 32 words to RT SubAddress */
wordcnt = 32;
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT,1,1,0,0);
cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr,0,rtsubaddr,wordcnt);
cmd2 = 0;
datablocknum = BLOCKA;
branchblock = 0;
timerus = 0;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
for (i = 0; i < wordcnt; i++)
   datablock[BLOCKA][i] = (uint16_t)(0xA000 + i);
check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKA,datablock[BLOCKA]));

The data block is initialized with a recognizable pattern: word 0 = 0xA000, word 1 = 0xA001, and so on up to word 31 = 0xA01F. This makes it easy to verify correct transmission on the RT side. The data is loaded into Block A via naibrd_SUM1553_BC_LoadDataBlock().

Command 2: RT-to-BC Receive (SA 2, 32 Words — Block B)

The second message receives 32 words from RT address 1, subaddress 2. The command word sets tx=1, which flips the direction to RT-to-BC — the RT transmits and the BC receives into the specified data block.

/* RTBC Message with 32 words to RT SubAddress */
wordcnt = RTBC_WORDCNT;
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT,1,1,0,0);
cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr,1,rtsubaddr,wordcnt);
cmd2 = 0;
datablocknum = BLOCKB;
branchblock = 0;
timerus = 0;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
/* Writing to the BLOCKB datablock is not necessary. We initialize so we know that getting the RT transmit messages */
for (i = 0; i < wordcnt; i++)
{
   datablock[BLOCKB][i] = (uint16_t)(0xB000 + i);
}
check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKB,datablock[BLOCKB]));

Block B is pre-loaded with placeholder data (0xB000 + offset). This is not strictly required for a receive block — the hardware will overwrite it with actual RT response data. The placeholder values let the application distinguish "data received from the RT" from "initial placeholder still present," which is useful for verifying that the RT is responding.

Command 3: BC-to-RT Send (SA 3, 16 Words — Block C)

The third message sends 16 words from the BC to RT address 1, subaddress 3. Note the subaddress is rtsubaddr+1 (SA 3), differentiating this message from Command 1’s SA 2 target.

/* BCRT Message with 16 words to RT SubAddress */
wordcnt = 16;
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT,1,1,0,0);
cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr,0,rtsubaddr+1,wordcnt);
cmd2 = 0;
datablocknum = BLOCKC;
branchblock = 0;
timerus = 0;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
for (i = 0; i < wordcnt; i++)
   datablock[BLOCKC][i] = (uint16_t)(0xC000 + i);
check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKC,datablock[BLOCKC]));

Block C is initialized with the pattern 0xC000 through 0xC00F (16 words). Like Block A, this data can be updated at runtime by the interactive loop’s 'U' command.

Command 4: GOTO Block 0

The final command block is an unconditional branch back to command block 0. This creates the continuous loop: after all three messages execute, the hardware jumps back to the timer gate and begins the next minor frame.

/* Branch back to beginning of schedule */
ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_GOTO,0,0,0,0);
cmd1 = 0;
cmd2 = 0;
datablocknum = 0;
branchblock = 0;
timerus = 0;
check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));

The GOTO control word uses retries=0, busa=0, and cond=0 because no bus transaction occurs — this is purely a flow-control instruction. The branchblock field is set to 0, directing execution back to the first command block (the timer gate).

Important
  • Command block load failure — verify that the block number is within the valid range (0—​2047) and that all parameters are consistent with the selected opcode. An invalid block number or a malformed control word will cause naibrd_SUM1553_BC_LoadCmdBlock() to return an error status.

  • Data block load failure — data block numbers must be in the range 0—​1023. Attempting to load a block number outside this range will fail. Ensure the datablocknum passed to naibrd_SUM1553_BC_LoadDataBlock() matches a valid block index.

  • Schedule not executing — after loading all command and data blocks, you must set the command block pointer to the first block and then enable BC execution. If the command block pointer is not set before calling the start function, the hardware has no entry point and the schedule will not run.

  • Messages in wrong order — the BC executes command blocks in sequential order starting from the command block pointer. Block numbers must be loaded sequentially (0, 1, 2, …​) to produce the intended message ordering. If blocks are loaded out of sequence, the schedule will not execute in the expected order.

Starting Execution and Retrieving Results

Start

With all command blocks and data blocks loaded, two calls start the BC scheduler. First, set the command block pointer to the entry point of the schedule. Then enable execution:

/* Start with the first command */
check_status(naibrd_SUM1553_BC_SetCmdBlockPtr(cardIndex,module,bcchan,FIRST_CMD));

/* Run the BC */
check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,bcchan,1));

The command block pointer must be set before enabling execution. The hardware needs to know which command block to begin with — if you enable execution without setting the pointer, the starting block is undefined and the schedule will not run correctly.

Retrieving RT-BC Results

After the scheduler is running, the application can read back the results of the RT-to-BC message (Block B) to see what the RT sent. The Retrieve_SUM1553_RTBCMessages() function handles this in two steps: first read the command block metadata, then read the received data.

static void Retrieve_SUM1553_RTBCMessages(int32_t cardIndex, int32_t module, int32_t bcchan)
{
   uint16_t ctrl;
   uint16_t cmd1, cmd2;
   uint16_t status1, status2;
   uint16_t branchblock;
   uint32_t timerus;
   uint16_t *dataptr = NULL;
   uint16_t rxdatablock[32];
   uint16_t rxwordcnt = RTBC_WORDCNT;
   int32_t i;

   check_status(naibrd_SUM1553_BC_ReadCmdBlock(cardIndex,module,bcchan,BLOCKB,&ctrl,&cmd1,&cmd2,dataptr,&status1,&status2,&branchblock,&timerus));
   if ((ctrl & NAI_SUM1553_BC_CNTL_BAME) == 0)
   {
      /* Read the data from the RT */
      naibrd_SUM1553_BC_ReadDataBlock(cardIndex,module,bcchan,BLOCKB,rxdatablock);
      printf ("Status1=%04X Status2=%04X WordCnt = %d: Data=", status1, status2, rxwordcnt);
      for (i=0; i < rxwordcnt; i++)
      {
         if (i != 0)
            printf (",");
         printf ("%04X", rxdatablock[i]);
      }
      printf("\n");
   }
}

naibrd_SUM1553_BC_ReadCmdBlock() reads the command block for Block B and returns the control word, command words, status words, branch target, and timing fields. The control word is then checked for the BAME (Block Access Message Error) flag. If (ctrl & NAI_SUM1553_BC_CNTL_BAME) == 0, the message completed without error and it is safe to read the received data. naibrd_SUM1553_BC_ReadDataBlock() then reads the 32-word receive buffer from Block B into rxdatablock.

BAME and Status Bits

The control word returned by naibrd_SUM1553_BC_ReadCmdBlock() contains several status flags that indicate message outcome:

  • NAI_SUM1553_BC_CNTL_BAME (bit 0) — Block Access Message Error. Set when the message transaction failed (no RT response, wrong address or subaddress, bus error).

  • NAI_SUM1553_BC_CNTL_SERVICE_REQUEST (bit 1) — the RT set the Service Request bit in its status word, indicating it has data or a condition that needs host attention.

  • NAI_SUM1553_BC_CNTL_TERMINAL_FLAG (bit 4) — the RT set the Terminal Flag bit in its status word.

  • NAI_SUM1553_BC_CNTL_BUSY_BIT (bit 5) — the RT responded with the Busy bit set, meaning it could not process the command at this time.

  • NAI_SUM1553_BC_CNTL_MSG_ERROR (bit 6) — a message-level error occurred during the transaction.

Refer to the SUMMIT 1553 module manual for complete definitions of all control word status bits and their interactions with retry and conditional branching logic.

Stop

To halt the BC scheduler, disable execution by passing 0:

check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,bcchan,0));

This stops the hardware from executing further command blocks. The schedule can be restarted later by setting the command block pointer and enabling execution again.

Important
  • BAME set on every message — the RT is not responding. Verify that an RT is connected to the bus, powered on, and configured with the correct RT address and subaddress. A BAME on every cycle typically means no device is present at the target address.

  • BUSY status — the RT is responding but cannot process messages at the current rate. Increase the minor frame cycle time (the timer gate value in Command 0) to give the RT more time between transactions.

  • No data in response block — the RT is not configured with transmit data on the targeted subaddress. The receive data block will still contain the placeholder values loaded during initialization. Verify that the companion RT application has loaded transmit data for the subaddress the BC is requesting.

Dynamic Data Updates

One of the key advantages of the SUM1553 BC architecture is that data blocks can be updated while the scheduler is running. naibrd_SUM1553_BC_LoadDataBlock() can be called at any time during execution — the hardware automatically picks up the new data on the next minor frame cycle. There is no need to stop and restart the scheduler.

Updating Transmit Data at Runtime

The Update_SUM1553_BCSAData() function demonstrates live data block updates. When the user presses 'U' in the interactive loop, the application increments a counter and reloads both Block A and Block C with new data patterns:

static void Update_SUM1553_BCSAData(int32_t cardIndex, int32_t module, int32_t bcchan, uint8_t increment)
{
   int32_t wordcnt = 32;
   uint8_t msb, lsb;
   int32_t i;

   msb = (uint8_t)(0xA0 | (increment & 0x0F)); /* upper byte (subaddress=upper 4 bits | increment=lower 4 bits)) */
   lsb = 0;
   for (i = 0; i < wordcnt; i++)
   {
      datablock[BLOCKA][i] = (msb << 8) | (uint8_t)(lsb + i);     /* incremental data */
   }
   check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKA,datablock[BLOCKA]));

   msb = (uint8_t)(0xC0 | (increment & 0x0F)); /* upper byte (subaddress=upper 4 bits | increment=lower 4 bits)) */
   lsb = 0;
   for (i = 0; i < wordcnt; i++)
   {
      datablock[BLOCKC][i] = (msb << 8) | (uint8_t)(lsb + i);     /* incremental data */
   }
   check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKC,datablock[BLOCKC]));
}

Each press of 'U' advances the increment counter (lower 4 bits, cycling 0—​15). Block A data is updated to the pattern (0xA0 | increment) << 8 | offset — for example, on the third press, word 0 = 0xA300, word 1 = 0xA301, and so on. Block C follows the same scheme with (0xC0 | increment) << 8 | offset. Both blocks are reloaded via naibrd_SUM1553_BC_LoadDataBlock() while the scheduler continues running uninterrupted.

When Dynamic Updates Are Useful

Live data block updates are valuable in any scenario where the BC transmit payload changes between cycles:

  • Real-time telemetry — sensor readings or system state that must be refreshed every frame.

  • Dynamic command payloads — command data that varies based on mission phase, operator input, or feedback from RTs.

  • Continuous data streaming — high-throughput applications where stopping the scheduler would cause unacceptable gaps in bus traffic.

Because the hardware picks up updated data on the very next cycle, there are zero missed cycles during an update.

Contrast with M1553 FTx BC Updates

On M1553 FTx modules, updating BC transmit data while the scheduler is running requires a stop-modify-restart sequence: call naibrd_1553_BcStop(), write the new data with naibrd_1553_BcDataBlockWrite(), and then call naibrd_1553_BcStart() to resume. This interruption means at least one minor frame is lost during every update.

SUM1553 eliminates this interruption entirely. naibrd_SUM1553_BC_LoadDataBlock() writes directly to the module’s data block memory while the scheduler continues executing. The hardware reads the data block at message transmission time, so an update that completes before the next cycle is guaranteed to take effect immediately.

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 your module’s manual for hardware-specific diagnostic procedures.

Diagnosing SUM1553 Scheduled Message Failures

When a SUM1553 scheduled message fails, read the command block for the failed message using naibrd_SUM1553_BC_ReadCmdBlock() and check the BAME bit (bit 0 of the control word). If BAME is set, the message encountered an error — check the remaining status bits (MSG_ERROR, BUSY_BIT, TERMINAL_FLAG) for the specific cause. If BAME is clear but data looks wrong, verify the data block number matches between the command block configuration and your ReadDataBlock() call. Consult your module’s manual for complete status bit definitions.

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.

Module not recognized as SUMMIT 1553

Selected module is not N7/N8/NA/NB/NC. IsSUMMIT1553() returned false.

Verify module type at the selected slot.

Reset not completing

Hardware not responding after reset

Verify module is powered and seated properly.

Mode set failure

Channel already in use or module doesn’t support BC mode

Close other applications using this channel.

Command block load failure

Invalid block number or parameters

Verify block number is within range (0-2047) and parameters are valid.

Data block load failure

Block number out of range

Verify block number is within range (0-1023).

Schedule not executing

Command block pointer not set before enabling execution

Call naibrd_SUM1553_BC_SetCmdBlockPtr() before naibrd_SUM1553_EnableExecution(1).

BAME set on every message

RT not responding, wrong RT address or subaddress

Verify RT is operational and address/subaddress match the schedule configuration.

RT busy status

RT cannot process commands at the scheduled rate

Increase the minor frame timer period (currently 100,000 µs).

No data in response block

RT not configured with transmit data on the targeted subaddress

Verify RT has data loaded for the subaddress the BC is requesting.

Dynamic update not taking effect

Wrong data block number in LoadDataBlock() call

Verify the block number matches the command block’s data block reference (BLOCKA=0, BLOCKB=1, BLOCKC=2).

Full Source

The complete source for this sample is provided below for reference. The sections above explain each part in detail.

Full Source — SUM1553_BC_Scheduler.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.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_sum1553.h"

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

/* Function prototypes */
static bool_t Run_SUM1553_BC_Scheduler(int32_t cardIndex, int32_t module, uint32_t modid);
static void Retrieve_SUM1553_RTBCMessages(int32_t cardIndex, int32_t module, int32_t bcchan);
static void Update_SUM1553_BCSAData(int32_t cardIndex, int32_t module, int32_t bcchan, uint8_t increment);

static const int32_t DEF_BC_CHANNEL    = 2;
static const uint8_t DEF_RT_ADDR       = 1;
static const uint8_t DEF_RT_SUBADDR    = 2;
static const uint16_t RTBC_WORDCNT     = 32;

static const uint16_t BLOCKA = 0;
static const uint16_t BLOCKB = 1;
static const uint16_t BLOCKC = 2;

static uint16_t datablock[3][32];

/**************************************************************************************************************/
/**
<summary>
The purpose of the SUM1553_BC_Scheduler is to illustrate the methods to call in the naibrd library to configure
the 1553 channel as a Bus Controller and send and receive BC-RT and RT-BC scheduled messages.

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

 Note, the SUM1553_BC_Scheduler can run in conjunction with the SUM1553_RT_PingPong or SUM1553_RT_ProcCtrl
 applications to illustrate BC and RT operations together with the NAI 1553 module.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t SUM1553_BC_Scheduler(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_SUM1553_BC_Scheduler(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;
}

/**************************************************************************************************************/
/**
<summary>
Run_SUM1553_BC_Scheduler queries the user for the module and channel to configure as the Bus Controller (BC).
After getting the module/channel selection, methods in the naibrd library are invoked to setup this channel
as a BC with the following scheduled predefined 1553 messages:
1) BC-RT message with 32 words of data to the "DEF_RT_ADDR" RT Address and "DEF_RT_SUBADDR" Subaddress
2) RT-BC message for 32 words of data to the "DEF_RT_ADDR" RT Address and "DEF_RT_SUBADDR" Subaddress
1) BC-RT message with 16 words of data to the "DEF_RT_ADDR" RT Address and "DEF_RT_SUBADDR+1" Subaddress

Once the BC is configured and running, the user can:
1) Type the Enter key to view the RT-BC response.
1) Type 'U' to change the data in the BC-RT message.
3) Type 'Q' to quit stop the BC execution and exit the routine.
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_SUM1553_BC_Scheduler(int32_t cardIndex, int32_t module, uint32_t modid)
{
   bool_t bQuit;
   bool_t bContinue = TRUE;
   int32_t bcchan = 2;

   const uint16_t FIRST_CMD = 0;
   bool_t resetting;
   uint32_t ncmd = 0;
   int32_t wordcnt = 32;
   uint8_t rtaddr = DEF_RT_ADDR;
   uint8_t rtsubaddr = DEF_RT_SUBADDR;

   uint16_t ctrl;
   uint16_t cmd1, cmd2;
   uint16_t datablocknum;
   uint16_t branchblock;
   uint32_t timerus;
   uint8_t increment = 0;
   int32_t i;

   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   bQuit = Get1553BCCfg(modid, DEF_BC_CHANNEL, &bcchan);
   if (!bQuit)
   {
      /* Reset the channel */
      check_status(naibrd_SUM1553_Reset(cardIndex,module,bcchan));

      /* Wait for channels to reset */
      while(check_status(naibrd_SUM1553_IsResetting(cardIndex,module,bcchan,&resetting)) == NAI_SUCCESS && resetting);

      /* Setup the BC */
      check_status(naibrd_SUM1553_SetMode(cardIndex,module,bcchan,NAI_SUM1553_OPSTATUS_BC_MODE)); /* Configure as BC */

      /* Load commands */
      ncmd = FIRST_CMD;
      /* Load Minor Frame Timers to 100000 us (100 ms) */
      ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_LOAD_MINOR_FRAME_TIMER,1,1,0,0);
      cmd1 = 0;
      cmd2 = 0;
      datablocknum = 0;
      branchblock = 0;
      timerus = 100000;
      check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));

      /* BCRT Message with 32 words to RT SubAddress */
      wordcnt = 32;
      ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT,1,1,0,0);
      cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr,0,rtsubaddr,wordcnt);
      cmd2 = 0;
      datablocknum = BLOCKA;
      branchblock = 0;
      timerus = 0;
      check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
      for (i = 0; i < wordcnt; i++)
         datablock[BLOCKA][i] = (uint16_t)(0xA000 + i);
      check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKA,datablock[BLOCKA]));

      /* RTBC Message with 32 words to RT SubAddress */
      wordcnt = RTBC_WORDCNT;
      ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT,1,1,0,0);
      cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr,1,rtsubaddr,wordcnt);
      cmd2 = 0;
      datablocknum = BLOCKB;
      branchblock = 0;
      timerus = 0;
      check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
      /* Writing to the BLOCKB datablock is not necessary. We initialize so we know that getting the RT transmit messages */
      for (i = 0; i < wordcnt; i++)
      {
         datablock[BLOCKB][i] = (uint16_t)(0xB000 + i);
      }
      check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKB,datablock[BLOCKB]));

      /* BCRT Message with 16 words to RT SubAddress */
      wordcnt = 16;
      ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_EXEBLK_CONT,1,1,0,0);
      cmd1 = NAI_SUM1553_COMMAND_WORD(rtaddr,0,rtsubaddr+1,wordcnt);
      cmd2 = 0;
      datablocknum = BLOCKC;
      branchblock = 0;
      timerus = 0;
      check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));
      for (i = 0; i < wordcnt; i++)
         datablock[BLOCKC][i] = (uint16_t)(0xC000 + i);
      check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKC,datablock[BLOCKC]));

      /* Branch back to beginning of schedule */
      ctrl = NAI_SUM1553_BC_CTRL_WORD(NAI_SUM1553_OPCODE_GOTO,0,0,0,0);
      cmd1 = 0;
      cmd2 = 0;
      datablocknum = 0;
      branchblock = 0;
      timerus = 0;
      check_status(naibrd_SUM1553_BC_LoadCmdBlock(cardIndex,module,bcchan,ncmd++,ctrl,cmd1,cmd2,datablocknum,branchblock,timerus));

      /* Start with the first command */
      check_status(naibrd_SUM1553_BC_SetCmdBlockPtr(cardIndex,module,bcchan,FIRST_CMD));

      /* Run the BC */
      check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,bcchan,1));

      while (bContinue)
      {
         printf("\nType Enter key for RT-BC message, or U to update the subaddress transmit data or %c to quit : ", NAI_QUIT_CHAR);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (toupper(inputBuffer[0]) == 'U')
            {
               increment++;
               Update_SUM1553_BCSAData(cardIndex,module,bcchan,increment);
            }
            else
            {
               Retrieve_SUM1553_RTBCMessages(cardIndex, module, bcchan);
            }
         }
         else
            bContinue = FALSE;
      }

      /* Disable the BC */
      check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,bcchan,0));
   }
   return bQuit;
}

/**************************************************************************************************************/
/**
<summary>
Retrieve_SUM1553_RTBCMessages reads the Command Block associated with the RT-BC message sent to the "DEF_RT_ADDR"
RT Address and "DEF_RT_SUBADDR" Subaddress. If the BAME (Block Access Message Error) bit is clear, indicating
no error, the Data block associated with the RT-BC message for RT Address and Subaddress is read.
</summary>
*/
/**************************************************************************************************************/
static void Retrieve_SUM1553_RTBCMessages(int32_t cardIndex, int32_t module, int32_t bcchan)
{
   uint16_t ctrl;
   uint16_t cmd1, cmd2;
   uint16_t status1, status2;
   uint16_t branchblock;
   uint32_t timerus;
   uint16_t *dataptr = NULL;
   uint16_t rxdatablock[32];
   uint16_t rxwordcnt = RTBC_WORDCNT;
   int32_t i;

   check_status(naibrd_SUM1553_BC_ReadCmdBlock(cardIndex,module,bcchan,BLOCKB,&ctrl,&cmd1,&cmd2,dataptr,&status1,&status2,&branchblock,&timerus));
   if ((ctrl & NAI_SUM1553_BC_CNTL_BAME) == 0)
   {
      /* Read the data from the RT */
      naibrd_SUM1553_BC_ReadDataBlock(cardIndex,module,bcchan,BLOCKB,rxdatablock);
      printf ("Status1=%04X Status2=%04X WordCnt = %d: Data=", status1, status2, rxwordcnt);
      for (i=0; i < rxwordcnt; i++)
      {
         if (i != 0)
            printf (",");
         printf ("%04X", rxdatablock[i]);
      }
      printf("\n");
   }
}

/**************************************************************************************************************/
/**
<summary>
Update_SUM1553_BCSAData changes the data that is sent in the BC-RT messages sent to the "DEF_RT_ADDR"
RT Address and "DEF_RT_SUBADDR" and "DEF_RT_SUBADDR+1" Subaddresses.
</summary>
*/
/**************************************************************************************************************/
static void Update_SUM1553_BCSAData(int32_t cardIndex, int32_t module, int32_t bcchan, uint8_t increment)
{
   int32_t wordcnt = 32;
   uint8_t msb, lsb;
   int32_t i;

   msb = (uint8_t)(0xA0 | (increment & 0x0F)); /* upper byte (subaddress=upper 4 bits | increment=lower 4 bits)) */
   lsb = 0;
   for (i = 0; i < wordcnt; i++)
   {
      datablock[BLOCKA][i] = (msb << 8) | (uint8_t)(lsb + i);     /* incremental data */
   }
   check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKA,datablock[BLOCKA]));

   msb = (uint8_t)(0xC0 | (increment & 0x0F)); /* upper byte (subaddress=upper 4 bits | increment=lower 4 bits)) */
   lsb = 0;
   for (i = 0; i < wordcnt; i++)
   {
      datablock[BLOCKC][i] = (msb << 8) | (uint8_t)(lsb + i);     /* incremental data */
   }
   check_status(naibrd_SUM1553_BC_LoadDataBlock(cardIndex,module,bcchan,BLOCKC,datablock[BLOCKC]));
}
Full Source — nai_1553_utils.c (SSK 1.x)
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

/* Common Sample Program include files */
#include "include/naiapp_interrupt.h"
#include "include/naiapp_interrupt_ether.h"
#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"
#include "nai_1553_utils.h"

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

static int32_t g_MenuCmdCnt = 0;

bool_t Get1553Address(int32_t maxaddress, int8_t defaddress, uint8_t *address)
{
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (maxaddress > 1)
   {
      while (bContinue)
      {
         printf("\nEnter address [default=%d]: ", defaddress);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt == 0)
               *address = defaddress;
            else
               *address = (uint8_t)atol((const char*)inputBuffer);
            if ((*address < 0) || (*address > maxaddress))
               printf("ERROR: Invalid address value.\n\n");
            else
               bContinue = FALSE;
         }
      }
   }
   else
      *address = 0;
   return bQuit;
}

bool_t Get1553MTCfg(uint32_t modid, int32_t defchan, int32_t *rtchan )
{
   bool_t bQuit = FALSE;
   int32_t MaxChannel;

   if (IsSUMMIT1553(modid))
   {
      /* Get the number of 1553 channels on the module */
      MaxChannel = 2;
      /* Get the RT channel */
      printf("\nRemote Terminal Setup\n");
      printf("---------------------\n");
      printf("1553 RT Channel Selection:");
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defchan, rtchan);
   }
   else if (IsFTx1553(modid))
   {
      MaxChannel = 4;
      /* Get the RT channel */
      printf("\nRemote Terminal Setup\n");
      printf("---------------------\n");
      printf("1553 RT Channel Selection:");
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defchan, rtchan);
   }
   else
      printf("ERROR: Module selected does not support 1553 Functionality\n");

   return bQuit;
}

bool_t Get1553RTCfg(uint32_t modid, int32_t defchan, uint8_t defaddr, int32_t *rtchan, uint8_t *rtaddr )
{
   bool_t bQuit = FALSE;
   int32_t MaxChannel;

   if (IsSUMMIT1553(modid))
   {
      /* Get the number of 1553 channels on the module */
      MaxChannel = 2;
      /* Get the RT channel */
      printf("\nRemote Terminal Setup\n");
      printf("---------------------\n");
      printf("1553 RT Channel Selection:");
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defchan, rtchan);
      if (!bQuit)
      {
         printf("1553 RT Address Selection:");
         bQuit = Get1553Address(31, defaddr, rtaddr);
      }
   }
   else if (IsFTx1553(modid))
   {
      MaxChannel = 4;
      /* Get the RT channel */
      printf("\nRemote Terminal Setup\n");
      printf("---------------------\n");
      printf("1553 RT Channel Selection:");
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defchan, rtchan);
      if (!bQuit)
      {
         printf("1553 RT Address Selection:");
         bQuit = Get1553Address(31, defaddr, rtaddr);
      }
   }
   else if (IsFTx1760(modid))
   {
      MaxChannel = 4;
      /* Get the RT channel */
      printf("\nRemote Terminal Setup\n");
      printf("---------------------\n");
      printf("1760 RT Channel Selection:");
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defchan, rtchan);
      if (!bQuit)
      {
         printf("1760 RT Address Selection:");
         bQuit = Get1553Address(31, defaddr, rtaddr);
      }
   }
   else
      printf("ERROR: Module selected does not support 1553 Functionality\n");

   return bQuit;
}

bool_t Get1553BCCfg(uint32_t modid, int32_t defchan, int32_t *bcchan )
{
   bool_t bQuit = FALSE;
   int32_t MaxChannel;

   if (IsSUMMIT1553(modid))
   {
      MaxChannel = 2;

      /* Get the BC channel */
      printf("\nBus Controller Setup:\n");
      printf("---------------------\n");
         printf("1553 BC Channel Selection:");
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defchan, bcchan);
   }
   else if (IsFTx1553(modid))
   {
      MaxChannel = 4;

      /* Get the BC channel */
      printf("\nBus Controller Setup:\n");
      printf("---------------------\n");
         printf("1553 BC Channel Selection:");
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defchan, bcchan);
   }
   else
      printf("ERROR: Module selected does not support Summit 1553 Functionality\n");

   return bQuit;
}

bool_t IsSUMMIT1553(uint32_t moduleID)
{
   bool_t bSupportSUM1553Func = FALSE;
   switch (moduleID)
   {
      case NAI_MODULE_ID_N7:
      case NAI_MODULE_ID_N8:
      case NAI_MODULE_ID_NA:
      case NAI_MODULE_ID_NB:
      case NAI_MODULE_ID_NC:
         bSupportSUM1553Func = TRUE;
         break;
      default:
         bSupportSUM1553Func = FALSE;
         break;
   }
   return bSupportSUM1553Func;
}

bool_t IsFTx1553(uint32_t moduleID)
{
   bool_t bSupportFTx1553Func = FALSE;
   switch (moduleID)
   {
      case NAI_MODULE_ID_FT0:
      case NAI_MODULE_ID_FT1:
      case NAI_MODULE_ID_FT2:
      case NAI_MODULE_ID_FT3:
      case NAI_MODULE_ID_FT4:
      case NAI_MODULE_ID_FT5:
      case NAI_MODULE_ID_FT6:
      case NAI_MODULE_ID_FT7:
      case NAI_MODULE_ID_FT8:
      case NAI_MODULE_ID_FT9:
      case NAI_MODULE_ID_FTA:
      case NAI_MODULE_ID_FTB:
      case NAI_MODULE_ID_FTC:
      case NAI_MODULE_ID_FTD:
      case NAI_MODULE_ID_FTE:
      case NAI_MODULE_ID_FTF:
      case NAI_MODULE_ID_FTPIB:
      case NAI_MODULE_ID_FTK:
      case NAI_MODULE_ID_CM1:
      case NAI_MODULE_ID_CM5:
      case NAI_MODULE_ID_CM8:
      case NAI_MODULE_ID_IF2:
         bSupportFTx1553Func = TRUE;
         break;
      default:
         bSupportFTx1553Func = FALSE;
         break;
   }
   return bSupportFTx1553Func;
}

bool_t IsFTx1760(uint32_t moduleID)
{
   bool_t bSupportFTx1760Func = FALSE;
   switch (moduleID)
   {
      case NAI_MODULE_ID_FTK:
         bSupportFTx1760Func = TRUE;
         break;
      default:
         bSupportFTx1760Func = FALSE;
         break;
   }
   return bSupportFTx1760Func;
}

bool_t Get1553LogicalDevNum(int16_t defdevnum, int16_t *devnum)
{
   bool_t bQuit = FALSE;
   bool_t bValidEntry = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nSelect Logical Device Number (0-31). This must be a unique number specific to this channel/device. [Default=%d]: ", defdevnum);
   while (!bValidEntry)
   {
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt == 0)
         {
            *devnum = defdevnum;
            bValidEntry = TRUE;
         }
         else if (atoi((char *)inputBuffer) < 0 || atoi((char *)inputBuffer) > 31)
            printf("\nPlease Select a Valid Logical Device Number (0-31) [Default=%d]: ", defdevnum);
         else
         {
            *devnum = (int16_t)atoi((char *)inputBuffer);
            bValidEntry = TRUE;
         }
      }
   }

   return bQuit;
}

bool_t Get1553RTAddressSource(bool_t defSoftware, bool_t *bSoftware)
{
   bool_t bQuit = FALSE;
   bool_t bValidEntry = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nSelect RT Address Source (S - Software, E - External Inputs) [Default=%s]: ", defSoftware ? "S" : "E");
   while (!bValidEntry)
   {
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt == 0)
         {
            *bSoftware = defSoftware;
            bValidEntry = TRUE;
         }
         else if ((toupper(inputBuffer[0]) != 'S') && (toupper(inputBuffer[0]) != 'E'))
            printf("\nPlease Select a Valid RT Address Source (S - Software, E - External Inputs) [Default=%s]: ", defSoftware ? "S" : "E");
         else
         {
            *bSoftware = (toupper(inputBuffer[0]) == 'S') ? TRUE : FALSE;
            bValidEntry = TRUE;
         }
      }
   }

   return bQuit;
}

bool_t Get1553BCSoftwareOverride(bool_t defSoftware, bool_t *bSoftware)
{
   bool_t bQuit = FALSE;
   bool_t bValidEntry = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nOverride External Inputs (Y or N)? [Default=%s]: ", defSoftware ? "Y" : "N");
   while (!bValidEntry)
   {
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt == 0)
         {
            *bSoftware = defSoftware;
            bValidEntry = TRUE;
         }
         else if ((toupper(inputBuffer[0]) != 'Y') && (toupper(inputBuffer[0]) != 'N'))
            printf("\nPlease Input Y or N. Override External Inputs? [Default=%s]: ", defSoftware ? "Y" : "N");
         else
         {
            *bSoftware = (toupper(inputBuffer[0]) == 'Y') ? TRUE : FALSE;
            bValidEntry = TRUE;
         }
      }
   }

   return bQuit;
}

bool_t Get1553BCAsyncMsgType(bool_t defPriorityHigh, bool_t *bHighPriority)
{
   bool_t bQuit = FALSE;
   bool_t bValidEntry = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nAsync Message Type High or Low (H or L)? [Default=%s]: ", defPriorityHigh ? "H" : "L");
   while (!bValidEntry)
   {
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt == 0)
         {
            *bHighPriority = defPriorityHigh;
            bValidEntry = TRUE;
         }
         else if ((toupper(inputBuffer[0]) != 'H') && (toupper(inputBuffer[0]) != 'L'))
            printf("\nPlease Input H or L. Async Message Type High or Low (H or L)? [Default=%s]: ", defPriorityHigh ? "H" : "L");
         else
         {
            *bHighPriority = (toupper(inputBuffer[0]) == 'H') ? TRUE : FALSE;
            bValidEntry = TRUE;
         }
      }
   }

   return bQuit;
}

bool_t Get1760EEPROMCopy(bool_t defCopyToEEPROM, bool_t* bCopyToEEPROM)
{
   bool_t bQuit = FALSE;
   bool_t bValidEntry = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nWrite Memory Contents to EEPROM? [Default=%s]: ", defCopyToEEPROM ? "Y" : "N");
   while (!bValidEntry)
   {
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt == 0)
         {
            *bCopyToEEPROM = defCopyToEEPROM;
            bValidEntry = TRUE;
         }
         else if ((toupper(inputBuffer[0]) != 'Y') && (toupper(inputBuffer[0]) != 'N'))
            printf("\nPlease Input Y or N. Write Memory Contents to EEPROM? [Default=%s]: ", defCopyToEEPROM ? "Y" : "N");
         else
         {
            *bCopyToEEPROM = (toupper(inputBuffer[0]) == 'Y') ? TRUE : FALSE;
            bValidEntry = TRUE;
         }
      }
   }

   return bQuit;
}

bool_t Get1553RxBufferType(uint16_t defrxbuffertype, uint16_t *rxbuffertype)
{
   bool_t bQuit = FALSE;
   bool_t bValidEntry = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nSelect Rx Buffer Mode:\n\n");
   printf("Single Buffer                        1-32 (number represents size of buffer)\n");
   printf("Double Buffer                        33\n");
   printf("Circular Buffer - 128 words          34\n");
   printf("Circular Buffer - 256 words          35\n");
   printf("Circular Buffer - 512 words          36\n");
   printf("Circular Buffer - 1024 words         37\n");
   printf("Circular Buffer - 2048 words         38\n");
   printf("Circular Buffer - 4096 words         39\n");
   printf("Circular Buffer - 8192 words         40\n");
   printf("Global Circular Buffer - 128 words   41\n");
   printf("Global Circular Buffer - 256 words   42\n");
   printf("Global Circular Buffer - 512 words   43\n");
   printf("Global Circular Buffer - 1024 words  44\n");
   printf("Global Circular Buffer - 2048 words  45\n");
   printf("Global Circular Buffer - 4096 words  46\n");
   printf("Global Circular Buffer - 8192 words  47\n");
   printf("\n\nEnter a Number between 1 and 47 [Default=%d]: ", defrxbuffertype);
   while (!bValidEntry)
   {
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt == 0)
         {
            *rxbuffertype = defrxbuffertype;
            bValidEntry = TRUE;
         }
         else if (atoi((char *)inputBuffer) < 1 || atoi((char *)inputBuffer) > 47)
            printf("\nPlease Enter a valid Number between 1 and 47 [Default=%d]: ", defrxbuffertype);
         else
         {
            *rxbuffertype = (uint16_t)atoi((char *)inputBuffer);
            bValidEntry = TRUE;
         }
      }
   }

   return bQuit;
}

/****** Command Tables *******/
static nai_1553_cmdtbl_type NAI_MenuCmds[25];

void Load1553MenuCommands(int32_t menuCmdCnt, nai_1553_cmdtbl_type menuCmds[])
{
   int32_t i;
   g_MenuCmdCnt = menuCmdCnt;
   /* Load the NAI_MenuCmds structure */
   for (i = 0; i < g_MenuCmdCnt; i++)
   {
      strcpy((char *)NAI_MenuCmds[i].cmdstr, (const char *)menuCmds[i].cmdstr);
      strcpy((char *)NAI_MenuCmds[i].menustr, (const char *)menuCmds[i].menustr);
      NAI_MenuCmds[i].cmdnum = menuCmds[i].cmdnum;
      NAI_MenuCmds[i].func = menuCmds[i].func;
   }
}

void Display1553MenuCommands(int8_t *menuTitle)
{
   int32_t i;

   printf("\n\n\n\t\t %s\n ", menuTitle);
   printf("\n ======== Command Selections ===============");
   for (i=0; i < g_MenuCmdCnt && NAI_MenuCmds[i].cmdstr != NULL; i++)
      printf ("\n %-8s \t%s", NAI_MenuCmds[i].cmdstr, NAI_MenuCmds[i].menustr);
   printf("\n");
}

bool_t Get1553CmdNum(int32_t cmdrequestCnt, int8_t *cmdrequest, int32_t* cmdNum)
{
   bool_t bCmdFound = FALSE;
   int32_t i;

   for (i = 0; i < g_MenuCmdCnt; i++)
   {
      if (naiapp_strnicmp(cmdrequest, NAI_MenuCmds[i].cmdstr, cmdrequestCnt) == 0)
      {
         bCmdFound = TRUE;
         *cmdNum = i;
         break;
      }
   }
   return bCmdFound;
}

void Menu1553Command(int32_t cmd, int16_t devnum)
{
   NAI_MenuCmds[cmd].func(devnum);
}

void LoadIllegalization(int16_t devnum, int32_t channel)
{
   uint8_t filename[128];
   FILE* deffile = NULL;
   int8_t buffer[128];
   int8_t *pval;
   uint32_t count = 0;

   sprintf((char *)filename, "illegalizationCh%d.txt", channel);
   deffile = fopen((const char *)filename,"r");
   if (deffile != NULL)
   {
      while (fgets((char*)buffer,sizeof(buffer),deffile) && count < 0x100)
      {
         pval = (int8_t*)strchr((char*)buffer,'\n');
         if (pval)
            *pval = '\0'; /* Remove LF */
         naibrd_1553_WriteMem(devnum, 0x300+count, (uint16_t)atol((const char*)buffer));
         count++;
      }
      fclose(deffile);
   }
}

void SaveIllegalization(int16_t devnum, int32_t channel)
{
   uint8_t filename[128];
   FILE* deffile = NULL;
   int32_t i;

   sprintf((char *)filename, "illegalizationCh%d.txt", channel);
   deffile = fopen((const char *)filename,"w");
   if (deffile != NULL)
   {
      for (i = 0x300; i <= 0x3FF; i++)
      {
         fprintf(deffile, "%d\n", naibrd_1553_ReadMem(devnum, i));
      }
   }
   fclose(deffile);
}

bool_t M1553_Config_Registers(int16_t devnum)
{
   bool_t bContinue = TRUE;
   bool_t bQuit = FALSE;
   uint16_t registervalue;
   uint32_t registeraddr;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* Display current state of registers */
   DisplayRegisters(devnum);

   while (bContinue)
   {
      /* Prompt User to change the value of a particular register */
      printf("\nSelect Register Address (0x00-0x1F) to Set (or Q to quit): ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         registeraddr = naiapp_utils_HexStrToDecUInt32((int8_t*)inputBuffer);

         if (registeraddr >= 0 && registeraddr < 32)
         {
            while (bContinue)
            {
               printf("\nEnter the value (0x0000-0xFFFF) to set (or Q to quit): ");
               bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               if (!bQuit)
               {
                  if (inputResponseCnt > 0)
                  {
                     registervalue = naiapp_utils_HexStrToDecUInt16((int8_t*)inputBuffer);
                     check_status(naibrd_1553_WriteReg(devnum, registeraddr, registervalue));
                     bContinue = FALSE;
                  }
                  else
                     printf("\nInvalid Value. \n");
               }
               else
                  bContinue = FALSE;
            }
         }
         else
            printf("\nInvalid Value. \n");
      }
      else
         bContinue = FALSE;
   }

   return FALSE;
}

bool_t M1553_Aux_Registers(int16_t devnum)
{
   bool_t bContinue = TRUE;
   bool_t bQuit = FALSE;
   uint16_t registervalue;
   uint32_t registeraddr;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* Display current state of aux registers */
   DisplayAuxRegisters(devnum);

   while (bContinue)
   {
      /* Prompt User to change the value of a particular register */
      printf("\nSelect Auxiliary Register Address (0x00-0xF) to Set (or Q to quit): ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         registeraddr = naiapp_utils_HexStrToDecUInt32((int8_t*)inputBuffer);

         if (registeraddr >= 0 && registeraddr < 32)
         {
            while (bContinue)
            {
               printf("\nEnter the value (0x0000-0xFFFF) to set (or Q to quit): ");
               bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               if (!bQuit)
               {
                  if (inputResponseCnt > 0)
                  {
                     registervalue = naiapp_utils_HexStrToDecUInt16((int8_t*)inputBuffer);
                     check_status(naibrd_1553_WriteAuxReg(devnum, registeraddr, registervalue));
                     bContinue = FALSE;
                  }
                  else
                     printf("\nInvalid Value. \n");
               }
               else
                  bContinue = FALSE;
            }
         }
         else
            printf("\nInvalid Value. \n");
      }
      else
         bContinue = FALSE;
   }

   return FALSE;
}

void DisplayRegisters(int16_t devnum)
{
   int32_t i;
   uint16_t registervalue;

   printf("\n\n");
   printf("********** CONFIGURATION REGISTERS **********\n");
   printf("ADDRESS        VALUE                         \n");

   for (i = 0; i < 32; i++)
   {
      registervalue = naibrd_1553_ReadReg(devnum, i);
      printf(" 0x%02X      0x%02X                       \n", i, registervalue);
   }
   printf("\n\n");
}

void DisplayAuxRegisters(int16_t devnum)
{
   int32_t i;
   uint16_t registervalue;

   printf("\n\n");
   printf("********** AUXILLARY REGISTERS **********\n");
   printf("ADDRESS        VALUE                     \n");

   for (i = 0; i < 16; i++)
   {
      registervalue = naibrd_1553_ReadAuxReg(devnum, i);
      printf(" 0x%02X      0x%02X                       \n", i, registervalue);
   }
   printf("\n\n");
}

bool_t GetRTAddress(int32_t* nRTaddress)
{
   bool_t bContinue = TRUE;
   bool_t bQuit = FALSE;
   int32_t value;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   while (bContinue)
   {
      printf("\nWhat is the RT Address of the command word (0 to 31)? ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         value = atoi((const char*)inputBuffer);
         if (value >= 0 && value < 32)
         {
            *nRTaddress = value;
            bContinue = FALSE;
         }
         else
            printf("\nInvalid Command.\n");
      }
      else
         bContinue = FALSE;
   }

   return bQuit;
}

bool_t GetTxRx(bool_t* bTxMsg)
{
   bool_t bContinue = TRUE;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   while (bContinue)
   {
      printf("\nReceive (R) or Transmit (T) Message? ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (toupper(inputBuffer[0]) == 'R')
         {
            *bTxMsg = FALSE;
            bContinue = FALSE;
         }
         else if (toupper(inputBuffer[0]) == 'T')
         {
            *bTxMsg = TRUE;
            bContinue = FALSE;
         }
         else
            printf("\nInvalid Command.\n");
      }
      else
         bContinue = FALSE;
   }

   return bQuit;
}

bool_t GetSubaddress(int32_t* nSubaddress)
{
   bool_t bContinue = TRUE;
   bool_t bQuit = FALSE;
   int32_t value;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   while (bContinue)
   {
      printf("\nSubaddress (0 to 31)? ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         value = atoi((const char*)inputBuffer);
         if (value >= 0 && value < 32)
         {
            *nSubaddress = value;
            bContinue = FALSE;
         }
         else
            printf("\nInvalid Command.\n");
      }
      else
         bContinue = FALSE;
   }

   return bQuit;
}

bool_t GetWordCount(int32_t* nWordCount)
{
   bool_t bContinue = TRUE;
   bool_t bQuit = FALSE;
   int32_t value;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   while (bContinue)
   {
      printf("\nWord Count (1 to 32)? ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         value = atoi((const char*)inputBuffer);
         if (value > 0 && value <= 32)
         {
            *nWordCount = value;
            bContinue = FALSE;
         }
         else
            printf("\nInvalid Command.\n");
      }
      else
         bContinue = FALSE;
   }

   return bQuit;
}

int32_t MemoryTest(int16_t devnum)
{
   int32_t counter = 0;
   int32_t ErrCnt = 0;
   uint16_t testValues[6] = {0x0000, 0x5555, 0xAAAA, 0xA5A5, 0x5A5A, 0xFFFF};
   uint16_t readValue;
   int32_t i;

   printf("\nDevNum %d - Memory Test started. Please wait for test to complete...\n\n", devnum);

   while (counter < NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY)
   {
      for (i = 0; i < sizeof(testValues)/sizeof(testValues[0]); i++)
      {
         naibrd_1553_WriteMem(devnum, counter, testValues[i]);
         readValue = naibrd_1553_ReadMem(devnum, counter);
         /* If write/read values do not match */
         if (readValue != testValues[i])
         {
            ErrCnt++;
            printf("\nData Mismatch! Memory Location: 0x%04X, WriteVal: 0x%04X, ReadVal: 0x%04X, ErrCnt: %d\n\n", counter, testValues[i], readValue, ErrCnt);
         }
      }

      counter++;

      /* Display Progress */
      if ((counter % 1000) == 250)
         printf("\\ %d%% Complete\r", (counter*100)/NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY);
      else if ((counter % 1000) == 500)
         printf("| %d%% Complete\r", (counter*100)/NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY);
      else if ((counter % 1000) == 750)
         printf("/ %d%% Complete\r", (counter*100)/NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY);
      else if ((counter % 1000) == 0)
         printf("- %d%% Complete\r", (counter*100)/NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY);
   }

   printf("\nDevNum %d - Memory Test Complete. ErrCnt = %d\n\n", devnum, ErrCnt);

   return ErrCnt;
}

int32_t MemoryTestFast(int16_t cardIndex, int16_t module, int16_t channel)
{
   int32_t ErrCnt = 0;
   uint16_t testValues[6] = {0x0000, 0x5555, 0xAAAA, 0xA5A5, 0xFFFF};
   uint32_t testValues32[6] = {0x00000000, 0x55555555, 0xAAAAAAAA, 0xA5A5A5A5, 0xFFFFFFFF};
   int32_t i,j,testIndex;
   uint16_t data[NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY];
   uint32_t data32[NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY];
   uint16_t readdata[NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY];
   uint32_t readdata32[NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY];
   uint32_t M1553memory[4] = NAI_1553_GEN5_REG_MEMORY_ADD;
   uint32_t M1553memory32[4] = NAI_1553_GEN5_32BIT_REG_MEMORY_ADD;
   uint32_t modid;
   int32_t maxmemorysize;
   uint32_t modprocrev, modfpgarev;

   printf("\nChannel %d - Memory Test started. Please wait for test to complete...\n\n", channel);

   modid = naibrd_GetModuleID(cardIndex, module);
   naibrd_GetModuleRev(cardIndex, module, &modprocrev, &modfpgarev);

   if (modfpgarev >= 0x100)
      memcpy(M1553memory, M1553memory32, sizeof(uint32_t)*4);

   if (modid == NAI_MODULE_ID_FT3 || modid == NAI_MODULE_ID_FT6 || modid == NAI_MODULE_ID_FT9)
      maxmemorysize = NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY / 2;
   else
      maxmemorysize = NAI_1553_MAX_SIZE_OF_DEVICE_MEMORY;

   for (i = 0; i < sizeof(testValues)/sizeof(testValues[0]); i++)
   {
      for (testIndex = 0; testIndex < maxmemorysize; testIndex++)
      {
         if (i == 0)
         {
            data[testIndex] = testValues[i]++;
            if (modfpgarev >= 0x100)
               data32[testIndex] = testValues32[i]++;
            else
               data32[testIndex] = testValues[i]++;
         }
         else
         {
            data[testIndex] = testValues[i];
            if (modfpgarev >= 0x100)
               data32[testIndex] = testValues32[i];
            else
               data32[testIndex] = testValues[i];
         }
      }
      if (i == 0)
         printf("Writing Incremental Data to %d words in RAM\n", maxmemorysize);
      else
      {
         if (modfpgarev >= 0x100)
            printf("Writing 0x%08X to %d words in RAM\n", testValues32[i], maxmemorysize);
         else
            printf("Writing 0x%04X to %d words in RAM\n", testValues[i], maxmemorysize);
      }
      if (modfpgarev >= 20)
         naibrd_Write32(cardIndex, module, M1553memory[channel - 1] << 1, 4, maxmemorysize, NAI_REG32, data32);
      else
         naibrd_Write16(cardIndex, module, M1553memory[channel - 1], 2, maxmemorysize, NAI_REG16, data);
      printf("Reading %d words in RAM\n", maxmemorysize);
      if (modfpgarev >= 20)
         naibrd_Read32(cardIndex, module, M1553memory[channel - 1] << 1, 4, maxmemorysize, NAI_REG32, &readdata32[0]);
      else
         naibrd_Read16(cardIndex, module, M1553memory[channel - 1], 2, maxmemorysize, NAI_REG16, &readdata[0]);
      for (j = 0; j < maxmemorysize; j++)
      {
         /* If write/read values do not match */
         if (modfpgarev >= 20)
         {
            if (readdata32[j] != data32[j])
            {
               ErrCnt++;
               printf("\nData Mismatch! Memory Location: 0x%04X, WriteVal: 0x%04X, ReadVal: 0x%04X, ErrCnt: %d\n\n", j, data32[j], readdata32[j], ErrCnt);
            }
         }
         else
         {
            if (readdata[j] != data[j])
            {
               ErrCnt++;
               printf("\nData Mismatch! Memory Location: 0x%04X, WriteVal: 0x%04X, ReadVal: 0x%04X, ErrCnt: %d\n\n", j, data[j], readdata[j], ErrCnt);
            }
         }
      }
      if (ErrCnt == 0)
      {
         printf("Test Passed\n");
      }
   }

   printf("\nChannel %d - Memory Test Complete. ErrCnt = %d\n\n", channel, ErrCnt);

   return ErrCnt;
}

Help Bot

X