M1760 EEPROM Copy
Edit this on GitLab
M1760 EEPROM Copy Sample Application (SSK 1.x)
Overview
The M1760 EEPROM Copy sample application demonstrates how to copy the current contents of the HI-6131 registers and RAM to the serial EEPROM on MIL-STD-1760 modules using the NAI Software Support Kit (SSK 1.x). The EEPROM stores a snapshot of the device state so that on the next power cycle, the module can auto-initialize from EEPROM rather than requiring software configuration. This is useful for deploying a known-good configuration that persists across reboots.
The key 1760 EEPROM API calls demonstrated are:
-
naibrd_1760_SetEEPROMUnlock()— unlocks the serial EEPROM for writing. -
naibrd_1760_SetEECOPY()— drives the EECOPY input to trigger the copy operation. -
naibrd_1760_GetDeviceReady()— polls the READY output to determine when the copy is complete. -
naibrd_1760_MasterReset()— performs a software master reset of the device (used when zeroing RAM).
|
Note
|
This sample is only supported on FTJ and FTK modules. Other 1553 modules (FT0-FTF, CM1, CM5, CM8) 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.
-
The device must have been reset at least once via software after power-up before running this application. The call to
naibrd_1760_Initialize()(performed by other 1760 samples such as M1553_RT_Receive) automatically performs this reset. If you have not run any other 1760 sample on the target channel since power-up, the EEPROM copy may fail.
How to Run
Launch the M1760_EEPROM_Copy executable from your build output directory. On startup the application looks for a configuration file (default_1760_EEPROMCopy.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 channel number, logical device number, and whether to zero out RAM before copying, then performs the EEPROM copy.
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:
-
Call
naiapp_RunBoardMenu()to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_1760_EEPROMCopy.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear. -
Query the user for a card index with
naiapp_query_CardIndex(). -
Query for a module slot with
naiapp_query_ModuleNumber(). -
Retrieve the module ID with
naibrd_GetModuleID()so downstream code can verify it is an FTJ or FTK module. -
If a valid module is found, call
Run_M1760_EEPROM_Copy()to begin the EEPROM copy sequence.
#if defined (__VXWORKS__)
int32_t M1760_EEPROM_Copy(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
while (stop != TRUE)
{
/* Query the user for the card index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Query the user for the module number */
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
if (stop != TRUE)
{
moduleID = naibrd_GetModuleID(cardIndex, module);
if ((moduleID != 0))
{
Run_M1760_EEPROM_Copy(cardIndex, module, moduleID);
}
}
}
printf("\nType Q to quit or Enter key to restart application:\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
printf("\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
The entry point is main() on most platforms, or M1760_EEPROM_Copy() on VxWorks. Both resolve to the same logic.
Module Validation
The first thing Run_M1760_EEPROM_Copy() does is verify that the selected module is an FTK (which covers both FTJ and FTK module IDs in the SSK). Non-1760 modules do not have EEPROM copy capability and will be rejected:
if (modid != NAI_MODULE_ID_FTK)
{
printf("This module does not support EEPROM copy capability\n");
return TRUE;
}
User Input Sequence
After module validation, the application collects configuration through a series of prompts:
-
Channel number —
naiapp_query_ChannelNumber()asks which of the 2 channels to target (default: channel 1). FTJ/FTK modules have 2 channels. -
Logical device number —
Get1553LogicalDevNum()assigns a logical device handle for the naibrd API (default: device 1). -
Zero out RAM —
Get1760EEPROMWriteZeros()asks whether to clear all device RAM before copying. If you want a clean EEPROM image with no leftover data from previous operations, answer Y. If you want to preserve the current device state (e.g., an RT configuration you just set up), answer N.
Device Setup and Optional RAM Clear
After collecting user input, the application opens the 1553 device on the selected channel and optionally clears RAM.
Opening the Device
swResult = naibrd_1553_Open(cardIndex, module, channel, DevNum);
This associates the card, module, and channel with the logical device number. Note that even though this is a 1760-specific operation, the device is still opened through the naibrd_1553_Open() API because the 1760 modules are built on the 1553 core.
Optional RAM Zeroing
If the user chose to zero out RAM, the application performs a master reset, writes zeros across the entire channel’s RAM space, and sets a valid RT address to avoid parity errors:
if (bWriteZeros)
{
naibrd_1760_MasterReset(DevNum);
nai_msDelay(100);
/* Write Zeros to clear out RAM */
naibrd_WriteZeros32(cardIndex, module, 0x20000*channel, 0x20000);
/* Set RT to 1 in operational status register to avoid parity error */
naibrd_1553_RtSetAddress(DevNum, 1);
}
The naibrd_1760_MasterReset() call resets the HI-6131 device to its default state. The 100ms delay allows the reset to complete. naibrd_WriteZeros32() then writes zeros to the entire 0x20000-byte RAM region for the selected channel. The naibrd_1553_RtSetAddress() call sets RT address 1 in the operational status register — this prevents a parity error that would otherwise occur when the EEPROM copy reads an uninitialized address field.
|
Important
|
Common device setup issues you may encounter:
|
EEPROM Copy Sequence
The EEPROM copy is a three-step hardware sequence: unlock the EEPROM, pulse the EECOPY signal, and wait for the device to indicate completion.
Step 1: Unlock the EEPROM
swResult = naibrd_1760_SetEEPROMUnlock(DevNum);
The serial EEPROM is write-protected by default. This call sends the unlock sequence to the HI-6131, allowing the subsequent copy operation to write to the EEPROM. If this call fails, the EEPROM remains locked and the copy will not proceed.
Step 2: Pulse the EECOPY Signal
The EECOPY input must be driven high and then low to trigger the copy. The 10ms high pulse gives the hardware time to latch the copy request:
swResult = naibrd_1760_SetEECOPY(DevNum, TRUE);
/* ... */
nai_msDelay(10);
swResult = naibrd_1760_SetEECOPY(DevNum, FALSE);
When EECOPY goes high, the HI-6131 begins copying registers and RAM contents to the serial EEPROM. When it transitions back to low, the device continues the internal copy process autonomously.
Step 3: Wait for Completion
The application polls the READY output until the device indicates the copy is complete:
do
{
nai_msDelay(1000);
swResult = naibrd_1760_GetDeviceReady(DevNum, &ready);
} while (!ready);
printf("Copy Complete\n");
The READY signal goes low when the EEPROM copy begins and returns high when the copy is finished. The 1-second polling interval is conservative — the actual copy time depends on the amount of data being written. Do not attempt to use the device for 1553 operations while READY is low.
|
Important
|
Common EEPROM copy issues you may encounter:
|
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. |
"This module does not support EEPROM copy capability" |
Module is not FTJ or FTK |
Only FTJ and FTK modules support 1760 EEPROM operations. Select the correct module slot. |
Device open failure |
Wrong card/module/channel, or device already in use |
Verify parameters. Close other applications using this channel. |
EEPROM unlock failure |
Device not reset since power-up |
Run another 1760 sample first, or use the "zero out RAM" option which performs a master reset. |
EECOPY hangs — READY never goes high |
EEPROM not unlocked, or device not properly initialized |
Ensure unlock succeeded. Power cycle the board and retry. |
Parity error in EEPROM contents |
RAM zeroed without setting valid RT address |
Always set a valid RT address after zeroing RAM before performing the EEPROM copy. |
EEPROM content not loading on reboot |
Copy did not complete, or invalid configuration written |
Verify READY went high. Ensure a valid RT configuration was in RAM before copying. |
Master reset required after power-up |
First 1760 operation since power cycle |
The HI-6131 needs at least one software master reset before EEPROM operations. Use |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — M1760_EEPROM_Copy.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_1553.h"
#include "functions/naibrd_1760.h"
static const int8_t *CONFIG_FILE = (int8_t *)"default_1760_EEPROMCopy.txt";
/* Function prototypes */
static bool_t Run_M1760_EEPROM_Copy(int32_t cardIndex, int32_t module, uint32_t modid);
bool_t Get1760EEPROMWriteZeros(bool_t defWriteZeros, bool_t* bWriteZeros);
static const int32_t DEF_CHANNEL = 1;
static const int16_t DEF_DEV_NUM = 1;
static const bool_t DEF_WRITE_ZEROS = FALSE;
/**************************************************************************************************************/
/**
<summary>
The purpose of the M1760_EEPROM_Copy application is to illustrate the methods to call in the naibrd library to
program the serial EEPROM with data from the HI-6131 registers and RAM. Only FTJ/FTK modules are supported in
this application.
NOTE: To run this application and copy to EEPROM successfully after power-up, the device must be reset at least
once via software by setting and resetting the Master Reset bit. This is automatically performed in the call to
naibrd_1760_Initialize(). For instance, running the M1553_RT_Receive sample application on the desired 1760
channel, then running M1760_EEPROM_Copy on the same channel should allow successful programming of the EEPROM.
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_EEPROM_Copy(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
while (stop != TRUE)
{
/* Query the user for the card index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Query the user for the module number */
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
if (stop != TRUE)
{
moduleID = naibrd_GetModuleID(cardIndex, module);
if ((moduleID != 0))
{
Run_M1760_EEPROM_Copy(cardIndex, module, moduleID);
}
}
}
printf("\nType Q to quit or Enter key to restart application:\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
printf("\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
static bool_t Run_M1760_EEPROM_Copy(int32_t cardIndex, int32_t module, uint32_t modid)
{
/* Variables */
bool_t bQuit = FALSE;
int16_t DevNum = 0;
int32_t swResult;
int32_t MaxChannel = 2, channel;
bool_t ready;
bool_t bWriteZeros;
if (modid != NAI_MODULE_ID_FTK)
{
printf("This module does not support EEPROM copy capability\n");
return TRUE;
}
/* Get Card, Module, Channel Numbers and Open a Handle */
bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_CHANNEL, &channel);
if (bQuit)
{
return bQuit;
}
/* Get Logical Device # */
bQuit = Get1553LogicalDevNum(DEF_DEV_NUM, &DevNum);
if (bQuit)
{
return bQuit;
}
/* Get from user whether or not to clear out RAM */
bQuit = Get1760EEPROMWriteZeros(DEF_WRITE_ZEROS, &bWriteZeros);
if (bQuit)
{
return bQuit;
}
/* Associate Card, Module and Channel Numbers with the Logical Device # */
swResult = naibrd_1553_Open(cardIndex, module, channel, DevNum);
if(swResult)
{
bQuit = TRUE;
printf("Error: naibrd_1553_Open %d", swResult);
return bQuit;
}
if (bWriteZeros)
{
naibrd_1760_MasterReset(DevNum);
nai_msDelay(100);
/* Write Zeros to clear out RAM */
naibrd_WriteZeros32(cardIndex, module, 0x20000*channel, 0x20000);
/* Set RT to 1 in operational status register to avoid parity error */
naibrd_1553_RtSetAddress(DevNum, 1);
}
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");
return bQuit;
}
bool_t Get1760EEPROMWriteZeros(bool_t defWriteZeros, bool_t* bWriteZeros)
{
bool_t bQuit = FALSE;
bool_t bValidEntry = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nZero out all registers? (Y or N) [Default=%s]: ", defWriteZeros ? "Y" : "N");
while (!bValidEntry)
{
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt == 0)
{
*bWriteZeros = defWriteZeros;
bValidEntry = TRUE;
}
else if ((toupper(inputBuffer[0]) != 'Y') && (toupper(inputBuffer[0]) != 'N'))
printf("\nPlease Input Y or N. Zero out all registers? [Default=%s]: ", defWriteZeros ? "Y" : "N");
else
{
*bWriteZeros = (toupper(inputBuffer[0]) == 'Y') ? TRUE : FALSE;
bValidEntry = TRUE;
}
}
}
return bQuit;
}