Integrator Resources

The official home for NAI Support

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

Toggle Components with Visual Button
JavaScript Form Processing

M1760 RT Program EEPROM

M1760 RT Program EEPROM Sample Application (SSK 1.x)

Overview

The M1760 RT Program EEPROM sample application demonstrates how to configure a MIL-STD-1553 channel as a Remote Terminal (RT), set up data blocks for multiple subaddresses, and save that configuration to the module’s serial EEPROM so the RT auto-initializes on the next power cycle using the NAI Software Support Kit (SSK 1.x). After a successful EEPROM program, the module will respond to BC commands within 100ms of power-up without requiring any software initialization.

The sample configures the RT with:

  • Subaddress 2 — Rx double buffer for receiving data from the BC.

  • Subaddress 15 — Rx double buffer for receiving data from the BC.

  • Subaddress 23 — Tx single buffer (with a second buffer for optional ping-pong), pre-loaded with test data (0xBEEF + offset) that the BC can request.

After the RT configuration is built, the sample starts and immediately stops the RT (the start/stop cycle ensures the configuration is committed to device RAM), then copies the entire configuration to EEPROM using the same unlock/EECOPY/READY sequence demonstrated in the M1760 EEPROM Copy sample.

Note
This sample is only supported on FTJ and FTK modules. Other 1553 modules do not have 1760 EEPROM functionality. For module-specific details, refer to the FTJ-FTK Manual.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with an FTJ or FTK module installed.

  • SSK 1.x installed on your development host.

  • The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.

How to Run

Launch the M1760_RT_Program_EEPROM executable from your build output directory. On startup the application looks for a configuration file (default_1760_RTProgramEEPROM.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, the application prompts for RT channel and address, configures the RT with data blocks on subaddresses 2, 15, and 23, and programs the configuration to EEPROM.

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

The main() function follows a standard SSK 1.x startup flow:

  1. Call naiapp_RunBoardMenu() to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_1760_RTProgramEEPROM.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().

  5. Call Run_M1760_RT_Program_EEPROM() to perform the RT configuration and EEPROM programming.

#if defined (__VXWORKS__)
int32_t M1760_RT_Program_EEPROM(void)
#else
int32_t main(void)
#endif
{
   bool_t bQuit = FALSE;
   int32_t cardIndex = -1;
   int32_t module = 0;
   int32_t moduleCount = 0;
   uint32_t modid = 0u;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {

      while (!bQuit)
      {
         bQuit = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         bQuit = naibrd_GetModuleCount(cardIndex, &moduleCount);
         bQuit = naiapp_query_ModuleNumber(moduleCount, 1, &module);
         modid = naibrd_GetModuleID(cardIndex, module);
      }

      bQuit = Run_M1760_RT_Program_EEPROM(cardIndex, module, modid);
      printf("Type %c to exit program or Enter key to restart application: ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   }

   naiapp_access_CloseAllOpenCards();

   return 0;
}
Important

Common connection errors you may encounter at this stage:

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

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

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

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

Program Structure

The entry point is main() on most platforms, or M1760_RT_Program_EEPROM() on VxWorks. Both resolve to the same logic.

The application flow is linear — it configures the RT, programs the EEPROM, and exits. There is no monitoring loop because the purpose is to write the configuration, not to operate the RT at runtime.

User Input Sequence

After the board connection is established, Run_M1760_RT_Program_EEPROM() collects configuration through a series of prompts:

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

  2. Logical device number — Get1553LogicalDevNum() assigns a logical device handle for the naibrd API (default: 1).

Device Initialization

Opening and Initializing

swResult = naibrd_1553_Open(cardIndex, module, rtchan, DevNum);

swResult = naibrd_1553_Initialize(DevNum, NAI_1553_ACCESS_CARD, NAI_1553_MODE_RT, 0, 0, 0);

The device is initialized in standard RT mode. The RT address is read back to confirm it was set correctly:

swResult = naibrd_1553_RtGetAddress(DevNum, &usData);
printf("RT Address set to %d\n\n", usData);

On 1760 modules, the RT address is typically determined by external hardware pins. naibrd_1553_RtGetAddress() reads the current address from the device, confirming what the hardware has latched.

Important

Common initialization issues you may encounter:

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

  • RT address reads as 0 — the external RT address pins may not be connected or the address has not been latched. Verify the hardware configuration on the module.

RT Data Block Configuration

The sample creates data blocks for three subaddresses to demonstrate a typical RT configuration that you might want to persist in EEPROM.

Subaddresses 2 and 15 — Rx Double Buffers

Two Rx double buffers are created and mapped to subaddresses 2 and 15 for receiving data from the BC:

swResult = naibrd_1553_RtDataBlockCreate(DevNum, DBLK_SA2, NAI_1553_RT_DATABLOCK_DOUBLE, NULL, 0);
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DBLK_SA2, 2, NAI_1553_RT_MESSAGE_TYPE_RX, 0, 1);

swResult = naibrd_1553_RtDataBlockCreate(DevNum, DBLK_SA15, NAI_1553_RT_DATABLOCK_DOUBLE, NULL, 0);
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DBLK_SA15, 15, NAI_1553_RT_MESSAGE_TYPE_RX, 0, 1);

Double buffering prevents data corruption when the BC sends data while the previous message is being read. After the EEPROM is programmed, the module will respond with clear status to Rx messages on these subaddresses within 100ms of power-up.

Subaddress 23 — Tx Buffers with Pre-loaded Data

Two Tx single buffers are created for subaddress 23. The first is mapped as the active Tx buffer; the second is available for runtime ping-pong buffering:

swResult = naibrd_1553_RtDataBlockCreate(DevNum, DBLK_SA23_1, NAI_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DBLK_SA23_2, NAI_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DBLK_SA23_1, 23, NAI_1553_RT_MESSAGE_TYPE_TX, 0, 1);

The Tx buffer is pre-loaded with test data so that when the BC requests a Tx from subaddress 23, the RT responds with known data:

for (i = 0; i < 32; i++)
{
   txData[i] = (uint16_t)(0xBEEF + i);
}
swResult = naibrd_1553_RtDataBlockWrite(DevNum, DBLK_SA23_1, txData, 32, 0);

This data (0xBEEF, 0xBEF0, 0xBEF1, …​) will be stored in EEPROM along with the rest of the configuration, so the RT will transmit it immediately after auto-initialization on the next power cycle.

Important

Common data block issues you may encounter:

  • Data block creation failure — the device may have run out of memory for data blocks. Reduce the number of data blocks or use smaller buffer types.

  • Subaddress mapping failure — verify the subaddress is in the valid range (0-31) and no conflicting mapping exists.

  • Tx data not appearing after EEPROM load — verify that naibrd_1553_RtDataBlockWrite() was called before the EEPROM copy, and that the RT was started and stopped to commit the configuration to RAM.

RT Start/Stop Cycle

Before copying to EEPROM, the sample starts and immediately stops the RT:

swResult = naibrd_1553_RtStart(DevNum);

/* Stop RT - For EEPROM copy to work, the RT must not be running. */
swResult = naibrd_1553_RtStop(DevNum);

The start/stop cycle is required to commit the RT configuration into the device’s internal RAM in a format that the EEPROM copy can capture. The RT must not be running during the EEPROM copy operation — the stop call ensures this.

EEPROM Programming Sequence

The EEPROM copy follows the same three-step sequence as the M1760 EEPROM Copy sample: unlock, pulse EECOPY, and wait for READY.

Step 1: Unlock the EEPROM

swResult = naibrd_1760_SetEEPROMUnlock(DevNum);

The serial EEPROM is write-protected by default. This unlocks it for the copy operation.

Step 2: Pulse the EECOPY Signal

swResult = naibrd_1760_SetEECOPY(DevNum, TRUE);
nai_msDelay(10);
swResult = naibrd_1760_SetEECOPY(DevNum, FALSE);

Driving EECOPY high triggers the HI-6131 to begin copying registers and RAM to the serial EEPROM. The 10ms high pulse gives the hardware time to latch the request. Driving it low allows the copy to proceed autonomously.

Step 3: Wait for Completion

do
{
   nai_msDelay(1000);
   swResult = naibrd_1760_GetDeviceReady(DevNum, &ready);
} while (!ready);

printf("Copy Complete\n");

The READY signal returns high when the EEPROM copy is finished. Do not use the device for any other operations while READY is low.

What Happens on Next Power Cycle

After a successful EEPROM program, the FTJ/FTK module will auto-initialize on the next power cycle:

  • The RT will come up at the address that was latched when the EEPROM was programmed.

  • Subaddresses 2 and 15 will be legalized for Rx with double buffers.

  • Subaddress 23 will be legalized for Tx with the pre-loaded data.

  • The RT will respond with clear status to BC commands within approximately 100ms of power-up.

This eliminates the need for software initialization in the deployed system, which is critical for applications where the RT must be operational before the host processor has fully booted.

Important

Common EEPROM programming issues you may encounter:

  • EEPROM unlock failure — the device may not have been properly initialized. Ensure naibrd_1553_Initialize() was called successfully before attempting the EEPROM sequence.

  • EECOPY hangs — READY never goes high — the unlock may have failed, or the device state is invalid. Power cycle the board and try again.

  • RT does not auto-initialize after reboot — verify the EEPROM copy completed (READY went high). Check that the RT address pins are set to the same address that was configured during programming.

  • RT must be stopped before EEPROM copy — the copy cannot proceed while the RT is running. The sample handles this with the start/stop sequence, but in your own code, ensure naibrd_1553_RtStop() is called before the EEPROM copy.

Troubleshooting Reference

This table summarizes common errors and symptoms covered in the sections above. For detailed context on each entry, refer to the relevant section. Consult the FTJ-FTK Manual for hardware-specific diagnostic procedures.

Error / Symptom Possible Causes Suggested Resolution

No board found or connection timeout

Board not powered, missing configuration file, network issue

Verify hardware and configuration. If file doesn’t exist, configure and save from board menu.

Device open or initialization failure

Wrong card/module/channel, or device already in use

Verify parameters. Close other applications using this channel.

RT address reads as 0

External address pins not connected or not latched

Verify hardware pin configuration on the FTJ/FTK module.

Data block creation failure

Device out of memory for data blocks

Reduce number of data blocks or buffer sizes.

EEPROM unlock failure

Device not properly initialized

Ensure naibrd_1553_Initialize() succeeded. Power cycle if needed.

EECOPY hangs — READY never goes high

EEPROM not unlocked, or device state invalid

Verify unlock succeeded. Power cycle the board and retry.

RT not auto-initializing after reboot

EEPROM copy did not complete, or RT address pins changed

Confirm READY went high. Verify address pin settings match the programmed configuration.

Tx data not present after EEPROM auto-init

Data not written to buffer before EEPROM copy

Call naibrd_1553_RtDataBlockWrite() before the start/stop and EEPROM copy sequence.

EEPROM copy fails — RT was still running

naibrd_1553_RtStop() not called before copy

Always stop the RT before performing the EEPROM copy.

Full Source

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

Full Source — M1760_RT_Program_EEPROM.c (SSK 1.x)
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* Common Sample Program include files */
#include "include/naiapp_boardaccess_menu.h"
#include "include/naiapp_boardaccess_query.h"
#include "include/naiapp_boardaccess_access.h"
#include "include/naiapp_boardaccess_display.h"
#include "include/naiapp_boardaccess_utils.h"

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

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

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

/* Function prototypes */
static bool_t Run_M1760_RT_Program_EEPROM(int32_t cardIndex, int32_t module, uint32_t modid);

#define DBLK_SA2        1
#define DBLK_SA15       2
#define DBLK_SA23_1     3
#define DBLK_SA23_2     4

#define DEF_RT_CHANNEL     1
#define DEF_RT_DEV_NUM     1
#define DEF_RT_ADDRESS     1

/**************************************************************************************************************/
/**
<summary>
The purpose of the M1760_RT_Program_EEPROM is to illustrate the methods to call in the naibrd library to configure
the FTJ or FTK channel as a Remote Terminal, create buffers and legalize Subaddresses 2 and 15 for Rx messages,
create buffers and legalize Subaddress 23 for Tx messages and copy the current configuration to the module EEPROM
so that when the module is rebooted, the channel will auto-initialize with this configuration. With this configuration,
the channel will respond with clear status (within 100 ms from power-up) to Rx messages on subaddresses 2 and 15.
Additionally, the channel will respond with clear status and data to Tx messages on subaddress 23.
This application demonstrates the usage of the following naibrd 1553 routines.
 - naibrd_1553_GetChannelCount
 - naibrd_1553_Open
 - naibrd_1553_Initialize
 - naibrd_1553_RtGetAddress
 - naibrd_1553_RtDataBlockCreate
 - naibrd_1553_RtDataBlockMapToSubaddress
 - naibrd_1553_RtDataBlockWrite
 - naibrd_1553_RtStart
 - naibrd_1553_RtStop
 - naibrd_1760_SetEEPROMUnlock
 - naibrd_1760_SetEECOPY
 - naibrd_1760_GetDeviceReady
 - naibrd_1553_Free

The following system configuration routines from the nai_sys_cfg.c file are called to assist with the configuration
setup for this program prior to calling the naibrd 1553 routines.
 - ConfigDevice
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - CheckModule
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t M1760_RT_Program_EEPROM(void)
#else
int32_t main(void)
#endif
{
   bool_t bQuit = FALSE;
   int32_t cardIndex = -1;
   int32_t module = 0;
   int32_t moduleCount = 0;
   uint32_t modid = 0u;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {

      while (!bQuit)
      {
         bQuit = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         bQuit = naibrd_GetModuleCount(cardIndex, &moduleCount);
         bQuit = naiapp_query_ModuleNumber(moduleCount, 1, &module);
         modid = naibrd_GetModuleID(cardIndex, module);
      }

      bQuit = Run_M1760_RT_Program_EEPROM(cardIndex, module, modid);
      printf("Type %c to exit program or Enter key to restart application: ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   }

   naiapp_access_CloseAllOpenCards();

   return 0;
}

static bool_t Run_M1760_RT_Program_EEPROM(int32_t cardIndex, int32_t module, uint32_t modid)
{
   /* Variables */
   bool_t bQuit = FALSE;
   int32_t rtchan;
   uint8_t rtaddr;
   int16_t DevNum = 0;
   int32_t swResult;
   uint16_t usData;
   uint16_t txData[32];
   int32_t i;
   bool_t ready;

   /* Get Card, Module, Channel Numbers and Open a Handle */
   bQuit = Get1553RTCfg(modid, DEF_RT_CHANNEL, DEF_RT_ADDRESS, &rtchan, &rtaddr);
   if (bQuit)
   {
      return bQuit;
   }

   /* Get Logical Device # */
   bQuit = Get1553LogicalDevNum(DEF_RT_DEV_NUM, &DevNum);
   if (bQuit)
   {
      return bQuit;
   }

   /* Associate Card, Module and Channel Numbers with the Logical Device # */
   swResult = naibrd_1553_Open(cardIndex, module, rtchan, DevNum);
   if (swResult)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_Open  %d", swResult);
      return bQuit;
   }

   /* Initialize Device */
   swResult = naibrd_1553_Initialize(DevNum, NAI_1553_ACCESS_CARD, NAI_1553_MODE_RT, 0, 0, 0);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_Initialize  %d", swResult);
      return bQuit;
   }

   /* Read RT Address */
   swResult = naibrd_1553_RtGetAddress(DevNum, &usData);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtGetAddress  %d", swResult);
      return bQuit;
   }

   printf("RT Address set to %d\n\n", usData);

   /* Create a Rx Double Buffer and map to subaddress 2 */
   swResult = naibrd_1553_RtDataBlockCreate(DevNum, DBLK_SA2, NAI_1553_RT_DATABLOCK_DOUBLE, NULL, 0);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockCreate  %d", swResult);
      return bQuit;
   }
   swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DBLK_SA2, 2, NAI_1553_RT_MESSAGE_TYPE_RX, 0, 1);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockMapToSubaddress  %d", swResult);
      return bQuit;
   }

   /* Create a Rx Double Buffer and map to subaddress 15 */
   swResult = naibrd_1553_RtDataBlockCreate(DevNum, DBLK_SA15, NAI_1553_RT_DATABLOCK_DOUBLE, NULL, 0);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockCreate  %d", swResult);
      return bQuit;
   }
   swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DBLK_SA15, 15, NAI_1553_RT_MESSAGE_TYPE_RX, 0, 1);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockMapToSubaddress  %d", swResult);
      return bQuit;
   }

   /* Create two Tx Single Buffers and map the first buffer to subaddress 23. The second buffer may be used during operation */
   /* for software-controlled ping pong buffering between the first and second buffer */
   swResult = naibrd_1553_RtDataBlockCreate(DevNum, DBLK_SA23_1, NAI_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockCreate  %d", swResult);
      return bQuit;
   }
   swResult = naibrd_1553_RtDataBlockCreate(DevNum, DBLK_SA23_2, NAI_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockCreate  %d", swResult);
      return bQuit;
   }
   swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DBLK_SA23_1, 23, NAI_1553_RT_MESSAGE_TYPE_TX, 0, 1);
   if (swResult < 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockMapToSubaddress  %d", swResult);
      return bQuit;
   }

   /* Load the Tx Buffer with data that will be requested from the Bus Controller */
   for (i = 0; i < 32; i++)
   {
      txData[i] = (uint16_t)(0xBEEF + i);
   }
   swResult = naibrd_1553_RtDataBlockWrite(DevNum, DBLK_SA23_1, txData, 32, 0);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtDataBlockWrite  %d", swResult);
      return bQuit;
   }

   /* Start RT */
   swResult = naibrd_1553_RtStart(DevNum);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtStart  %d", swResult);
      return bQuit;
   }

   /* Stop RT - For EEPROM copy to work, the RT must not be running. */
   swResult = naibrd_1553_RtStop(DevNum);
   if (swResult != 0)
   {
      bQuit = TRUE;
      printf("Error: naibrd_1553_RtStop  %d", swResult);
      return bQuit;
   }

   /* Copy the RT configuration to EEPROM for auto-initialization */
   swResult = naibrd_1760_SetEEPROMUnlock(DevNum);
   if (swResult != NAI_SUCCESS)
   {
      printf("Error: naibrd_1760_SetEEPROMUnlock  %d", swResult);
      return TRUE;
   }
   printf("\nSerial EEPROM Unlock Successful.");

   swResult = naibrd_1760_SetEECOPY(DevNum, TRUE);
   if (swResult != NAI_SUCCESS)
   {
      printf("Error: naibrd_1760_SetEECOPY  %d", swResult);
   }

   printf("\nDriving EECOPY input high.");

   nai_msDelay(10);

   swResult = naibrd_1760_SetEECOPY(DevNum, FALSE);
   if (swResult != NAI_SUCCESS)
   {
      printf("Error: naibrd_1760_SetEECOPY  %d", swResult);
      return TRUE;
   }

   printf("\nDriving EECOPY input low.");

   printf("\nWait until READY output goes high for EEPROM copy completion...");
   do
   {
      nai_msDelay(1000);
      swResult = naibrd_1760_GetDeviceReady(DevNum, &ready);
   } while (!ready);

   printf("Copy Complete\n");

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

   return bQuit;
}

Help Bot

X