Reg Editor BasicOps
Edit this on GitLab
Reg Editor BasicOps Sample Application (SSK 1.x)
Overview
The Reg Editor BasicOps sample application demonstrates how to perform low-level register reads and writes on any NAI board or module using the NAI Software Support Kit (SSK 1.x). Unlike module-specific samples that use high-level API functions (such as naibrd_AD_SetRange() or naibrd_SER_SetBaudRate()), this tool works at the register level — you supply a hex offset and the application reads or writes 32-bit values directly at that address.
Register-level access is useful when you need to:
-
Debug hardware behavior — read back raw register values to verify that a high-level API call produced the expected configuration.
-
Access registers not exposed by the high-level API — some board-level or module-level registers (diagnostic counters, FPGA revision fields, factory calibration data) may not have dedicated API wrappers.
-
Develop and test new modules — when bringing up a new module type before high-level API support is available, direct register access is the only option.
-
Inspect motherboard registers — pass module
0to access the motherboard register space directly, which is not reachable through module-specific APIs.
This sample is not tied to any particular module type. It works with any NAI board, any module slot, and any valid register offset. Consult your module’s register map (available in the module manual) to determine which offsets correspond to which functions.
Prerequisites
Before running this sample, make sure you have:
-
An NAI board (any model) powered on and connected to your development host.
-
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 Reg_Editor_BasicOps executable from your build output directory. On startup the application looks for a configuration file (default_RegEditorConfig.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection and select a card index. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, the application prompts for a module number (or 0 for motherboard registers) and then presents a command menu for reading, writing, and saving register data.
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 any module type. For details on board connection configuration, see the First Time Setup Guide. |
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_RegEditorConfig.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 number. Enter a slot number (1-based) to access that module’s register space, or enter
0to access the motherboard register space. -
Pass the card index and module number into the command loop (
BasicMenu_Run()).
#if defined (__VXWORKS__)
int32_t RunBasicOpsProgramSample(void)
#else
int32_t main(void)
#endif
{
bool_t stop = 0;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == 1)
{
while (stop != 1)
{
/* Query the user for the card index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != 1)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
printf("\r\nEnter Module to access, or '0' for motherboard [defualt=0]:");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!stop)
{
if (inputResponseCnt == 0)
{
BasicMenu_Run(cardIndex, 0);
}
else
{
module = atoi((const char*)inputBuffer);
BasicMenu_Run(cardIndex, module);
}
}
}
printf("\r\nType Q to quit or Enter key to restart application:\r\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
printf("\r\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
Note that the module number 0 is a special value — it routes all subsequent read and write operations to the motherboard register space instead of a module slot. If you press Enter without typing a number, the application defaults to module 0.
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Application Parameters
The application tracks two values throughout the session:
-
cardIndex— identifies which NAI board to communicate with (zero-based). -
module— identifies which module slot to access (one-based), or0for the motherboard register space.
These are stored in an naiapp_AppParameters_t struct and passed to each command handler. In your own code, you would track the same card index and module number and pass them directly to naibrd_Read32() and naibrd_Write32().
Command Menu
The sample presents four commands:
| Key | Command | Description |
|---|---|---|
C |
Change Module Access |
Switch to a different card index and/or module slot |
R |
Read Reg |
Read one or more 32-bit registers starting at a given offset |
W |
Write Reg |
Write one or more 32-bit values starting at a given offset |
S |
Save Last Read |
Save the most recent read results to a file |
The menu system is a sample convenience — in your own code, call naibrd_Read32() and naibrd_Write32() directly without any menu infrastructure.
naiapp_cmdtbl_params_t BasicOpMenuCmds[] =
{
{ "C", "Change Module Access", BASICMENU_CHNG_MOD, BasicMenu_Chng_Mod_Func },
{ "R", "Read Reg", BASICMENU_READ_REG, BasicMenu_ReadReg_Func },
{ "W", "Write Reg", BASICMENU_WRITE_REG, BasicMenu_WriteReg_Func },
{ "S", "Save Last Read", BASICMENU_SAVE_REG_FILE, BasicMenu_SaveRegFile_Func }
};
Saved Read State
The application maintains three global variables that store the results of the most recent read operation:
-
savedAddress— the absolute address (module base + offset) of the first register read. -
savedCount— the number of 32-bit elements that were read. -
savedDataArray[4096]— the raw data buffer.
These are populated automatically after every Read command and consumed by the Save command.
Changing Module Access ©
To switch to a different board or module without restarting the application, use the Change Module Access command. This re-prompts for a card index and module number and updates the session parameters.
static nai_status_t BasicMenu_Chng_Mod_Func(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
bool_t bQuit = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
int32_t cardIndex;
int32_t module;
int32_t moduleCnt;
/* Query the user for the card index */
bQuit = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (bQuit != 1)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
printf("\r\nEnter Module to access, or '0' for motherboard [defualt=0]:");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt == 0)
{
module = 0;
}
else
{
module = atoi((const char*)inputBuffer);
}
p_ad_params->cardIndex = cardIndex;
p_ad_params->module = module;
}
}
return NAI_SUCCESS;
}
In your own application, switching between modules is simply a matter of passing a different module value to subsequent naibrd_Read32() or naibrd_Write32() calls. No explicit "switch" operation is required at the API level.
Reading Registers ®
To read raw register values from the board, use the Read command. The application prompts for two inputs:
-
Offset — the hex offset within the selected module’s (or motherboard’s) register space. The application converts this to an absolute address by adding the module base address retrieved from
naibrd_GetModuleOffset(). -
Element count — the number of 32-bit registers to read. The count is rounded up to the next multiple of 4 for alignment.
The core API call is naibrd_Read32(), which performs a block read of 32-bit registers:
offset = strtol(((const char *)inputBuffer), NULL, 16);
naibrd_GetModuleOffset(cardIndex, module, &modBaseAddr);
address = offset + modBaseAddr;
/* ... prompt for count ... */
count = atoi((const char *)inputBuffer);
count += ((count % 4) != 0) ? (4 - (count % 4)) : 0;
check_status(naibrd_Read32(cardIndex, module, offset, 4, count, 4, data));
naiapp_display_DataInAscii(address, count, 4, data);
naibrd_Read32() Parameters
| Parameter | Description |
|---|---|
|
Zero-based board index. |
|
Module slot (1-based) or |
|
Starting register offset within the module (hex). This is relative to the module base, not an absolute address. |
|
Byte stride between consecutive registers. For 32-bit registers this is always 4. |
|
Number of 32-bit elements to read. |
|
Data width in bytes (4 = 32-bit reads). |
|
Output buffer that receives the read values. |
Display Format
After the read completes, naiapp_display_DataInAscii() prints the data in a hex-dump format showing the absolute address, hex values, and ASCII interpretation of each 32-bit word. The data is also stored in the global savedDataArray so you can save it to a file later with the Save command.
|
Important
|
Common Errors
|
Writing Registers (W)
To write values directly to hardware registers, use the Write command. The application prompts for:
-
Offset — the hex offset within the module’s register space.
-
Element count — the number of consecutive 32-bit registers to write.
-
Data values — one value per register. Enter decimal values by default, or prefix with
0xfor hex.
Each value is written individually using naibrd_Write32():
offset = strtol(((const char *)inputBuffer), NULL, 16);
naibrd_GetModuleOffset(cardIndex, module, &modBaseAddr);
address = offset + modBaseAddr;
/* ... prompt for count and values ... */
for (i = 0; i < (int)count; i++)
{
printf("\r0x%08X: ", address + (i * 4));
/* ... read user input ... */
if (strstr((const char*)inputBuffer, "0x") == NULL)
{
write = atoi((const char *)inputBuffer);
*data = write;
}
else
{
write = strtoul((const char *)inputBuffer, NULL, 0);
*data = write;
}
check_status(naibrd_Write32(cardIndex, module, offset, 4, 1, 4, data));
offset += 4;
}
naibrd_Write32() Parameters
| Parameter | Description |
|---|---|
|
Zero-based board index. |
|
Module slot (1-based) or |
|
Starting register offset (hex), incremented by 4 after each write. |
|
Byte stride between registers. |
|
Number of elements per write call (the sample writes one register at a time inside the loop). |
|
Data width in bytes (4 = 32-bit writes). |
|
Pointer to the 32-bit value to write. |
Input Format
The application accepts two formats for data values:
-
Decimal — type a plain number (e.g.,
255). The value is parsed withatoi(). -
Hexadecimal — prefix with
0x(e.g.,0xFF). The value is parsed withstrtoul().
The address prompt shows the absolute address for each register so you can verify you are writing to the intended location.
|
Important
|
Common Errors
|
Saving Read Results to a File (S)
To export the most recent read results for analysis or record-keeping, use the Save command. The application prompts for a filename (defaulting to default_RegData.txt) and writes a formatted hex dump to that file.
static nai_status_t BasicMenu_SaveRegFile_Func(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ad_params->cardIndex;
int32_t module = p_ad_params->module;
int32_t modid = naibrd_GetModuleID(cardIndex, module);
char *modIdName = (char*)&modid;
char filepathandname[162];
/* ... prompt for filename ... */
/* open the file for writing */
fp = fopen((const char*)filepathandname, "w");
fprintf(fp, "Board Index: %d, %d", cardIndex, module);
if (module > 0)
{
fprintf(fp, "Module No. %d, Module ID: %c%c%c%c\r\n",
module, modIdName[3], modIdName[2], modIdName[1], modIdName[0]);
}
else
{
fprintf(fp, "Motherboard Register Space\r\n");
}
if (((savedAddress != 0) && (savedCount != 0)) || (savedDataArray != NULL))
{
if (save_Last_Read(fp, savedAddress, savedCount, 4, savedDataArray) == 0)
{
printf("Saved %s!", filepathandname);
}
else
{
printf("Failed to save %s!", filepathandname);
}
}
fclose(fp);
return NAI_SUCCESS;
}
File Contents
The output file includes:
-
A header line with the board index and module number. For module slots, it also prints the 4-character module ID (e.g.,
AD4G,SER4). For module0, it prints "Motherboard Register Space". -
A hex-dump table formatted by the
save_Last_Read()helper function. Each row shows an absolute address, four 32-bit hex values, and their ASCII interpretation.
save_Last_Read() Helper
The save_Last_Read() function formats register data into a standard hex-dump layout. It supports 1-byte, 2-byte, and 4-byte data widths (the Register Editor always uses 4-byte width). Each row displays 16 bytes of data (four 32-bit values), with both hex and ASCII columns. Non-printable characters are replaced with . in the ASCII column.
|
Important
|
Common Errors
|
Troubleshooting Reference
|
Note
|
This section summarizes errors covered in the preceding sections. Consult your board’s documentation and module manual for hardware-specific diagnostics. |
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
No board found |
Board not powered on; incorrect interface or address in configuration file. |
Verify power and physical connection. Delete |
Connection timeout |
Network misconfiguration (Ethernet); bus misconfiguration (PCI/PCIe); firewall blocking traffic. |
Confirm IP address and subnet. Check PCI enumeration. Disable or configure firewalls. |
Invalid card or module index |
Card index is not zero-based; module number is not one-based (or zero for motherboard). |
Card indices start at 0. Module slots start at 1. Use 0 only for motherboard access. |
Read returns all |
Offset does not map to a valid register; module not present in the selected slot. |
Verify the offset against the module’s register map. Confirm the module is physically installed. |
Write has no effect (read-back unchanged) |
Register is read-only; value is out of the register’s accepted range. |
Check the register map for read/write permissions and valid value ranges. |
"Failed to save" message |
No prior Read operation was performed; data buffer is empty. |
Run a Read command before attempting to Save. |
File not created or empty |
Insufficient write permissions in the working directory. |
Run the application from a directory where you have write access. |
Count rounded up unexpectedly |
The read count is automatically rounded up to the next multiple of 4 for alignment. |
This is expected behavior. Request a count that is already a multiple of 4 to avoid extra reads. |
Full Source
Full Source — Reg_Editor_BasicOps.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <ctype.h>
#if defined (LINUX)
#include <pthread.h>
#elif defined(_WIN32)
#define PLATFORM "Win32"
#elif defined(_WIN64)
#define PLATFORM "x64"
#else
#define PLATFORM "not linux or windows"
#endif
/* Common Sample Program include files */
#include "include/naiapp_boardaccess_menu.h"
#include "include/naiapp_boardaccess_query.h"
#include "include/naiapp_boardaccess_access.h"
#include "include/naiapp_boardaccess_display.h"
#include "include/naiapp_boardaccess_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#define REG_FILE "default_RegData.txt"
static const int8_t *CONFIG_FILE = (const int8_t *)"default_RegEditorConfig.txt";
FILE* fp = NULL;
static uint32_t savedAddress;
static uint32_t savedCount;
static uint32_t savedDataArray[4096];
/* Function prototypes */
static bool_t BasicMenu_Run(int32_t cardIndex, int32_t module);
static nai_status_t BasicMenu_Chng_Mod_Func(int32_t paramCount, int32_t* p_params);
int32_t save_Last_Read(FILE *deffile,uint32_t addr, int32_t len, int32_t dataWidth, void* p_data);
static nai_status_t BasicMenu_ReadReg_Func(int32_t paramCount, int32_t* p_params);
static nai_status_t BasicMenu_WriteReg_Func(int32_t paramCount, int32_t* p_params);
static nai_status_t BasicMenu_SaveRegFile_Func(int32_t paramCount, int32_t* p_params);
enum basicOpsMenu_commands
{
BASICMENU_CHNG_MOD,
BASICMENU_READ_REG,
BASICMENU_WRITE_REG,
BASICMENU_SAVE_REG_FILE,
BASICMENU_CMD_COUNT
};
naiapp_cmdtbl_params_t BasicOpMenuCmds[] =
{
{ "C", "Change Module Access", BASICMENU_CHNG_MOD, BasicMenu_Chng_Mod_Func },
{ "R", "Read Reg", BASICMENU_READ_REG, BasicMenu_ReadReg_Func },
{ "W", "Write Reg", BASICMENU_WRITE_REG, BasicMenu_WriteReg_Func },
{ "S", "Save Last Read", BASICMENU_SAVE_REG_FILE, BasicMenu_SaveRegFile_Func }
};
#if defined (__VXWORKS__)
int32_t RunBasicOpsProgramSample(void)
#else
int32_t main(void)
#endif
{
bool_t stop = 0;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == 1)
{
while (stop != 1)
{
/* Query the user for the card index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != 1)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
printf("\r\nEnter Module to access, or '0' for motherboard [defualt=0]:");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!stop)
{
if (inputResponseCnt == 0)
{
BasicMenu_Run(cardIndex, 0);
}
else
{
module = atoi((const char*)inputBuffer);
BasicMenu_Run(cardIndex, module);
}
}
}
printf("\r\nType Q to quit or Enter key to restart application:\r\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
printf("\r\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 BasicMenu_Run(int32_t cardIndex, int32_t module)
{
bool_t bQuit = 0, bCmdFound;
int32_t cmd;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
naiapp_AppParameters_t basicops_params;
p_naiapp_AppParameters_t basicOps_params = &basicops_params;
basicOps_params->cardIndex = cardIndex;
basicOps_params->module = module;
naiapp_utils_LoadParamMenuCommands(BASICMENU_CMD_COUNT,BasicOpMenuCmds);
do
{
naiapp_display_ParamMenuCommands((int8_t*)"MENU_TITLE");
printf("\r\nType command or %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit && inputResponseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case BASICMENU_CHNG_MOD:
case BASICMENU_READ_REG:
case BASICMENU_WRITE_REG:
case BASICMENU_SAVE_REG_FILE:
BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)basicOps_params);
break;
default:
continue;
break;
}
}
else printf("Invalid command entered\r\n");
}
} while (!bQuit);
return 1;
}
static nai_status_t BasicMenu_Chng_Mod_Func(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
bool_t bQuit = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
int32_t cardIndex;
int32_t module;
int32_t moduleCnt;
/* Query the user for the card index */
bQuit = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (bQuit != 1)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
printf("\r\nEnter Module to access, or '0' for motherboard [defualt=0]:");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt == 0)
{
module = 0;
}
else
{
module = atoi((const char*)inputBuffer);
}
p_ad_params->cardIndex = cardIndex;
p_ad_params->module = module;
}
}
return NAI_SUCCESS;
}
static nai_status_t BasicMenu_ReadReg_Func(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
uint32_t count;
uint32_t data[4096];
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ad_params->cardIndex;
int32_t module = p_ad_params->module;
int32_t offset;
uint32_t modBaseAddr=0;
uint32_t address;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("Enter valid offset: 0x");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
while(inputResponseCnt==0 && !bQuit)
{
printf("Enter valid offset: 0x");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
if(!bQuit)
{
offset = strtol(((const char *)inputBuffer),NULL,16);
naibrd_GetModuleOffset(cardIndex,module,&modBaseAddr);
address = offset+modBaseAddr;
/* reset buffer*/
memset(inputBuffer,0,sizeof(inputBuffer));
printf("Enter number of elements you would like to read:");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if(!bQuit)
{
count=atoi((const char *)inputBuffer);
count += ((count%4) != 0) ? (4-(count%4)) : 0;
check_status(naibrd_Read32(cardIndex, module, offset,4,count,4,data));
naiapp_display_DataInAscii(address,count,4,data);
}
memcpy(savedDataArray,data,sizeof(data));
savedCount = count;
savedAddress=address;
}
}
return NAI_SUCCESS;
}
static nai_status_t BasicMenu_WriteReg_Func(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
uint32_t write=0;
uint32_t offset;
uint32_t count;
uint32_t data[4096];
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ad_params->cardIndex;
int32_t module = p_ad_params->module;
uint32_t modBaseAddr=0;
uint32_t address;
printf("Please enter a valid offset: 0x");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
while(inputResponseCnt==0 && !bQuit)
{
printf("Please Enter valid offset: 0x");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
offset = strtol(((const char *)inputBuffer),NULL,16);
naibrd_GetModuleOffset(cardIndex,module,&modBaseAddr);
address = offset+modBaseAddr;
/*reset buffer*/
memset(inputBuffer,0,sizeof(inputBuffer));
printf("Enter number of elements you would like to write:");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
while(inputResponseCnt ==0 && !bQuit)
{
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
if(!bQuit)
{
int i;
count = atoi((const char *)inputBuffer);
memset(inputBuffer,0,sizeof(inputBuffer));
printf("Enter a decimal value for each address, or prefix with 0x for hex:\r\n");
for (i=0;i<(int)count;i++)
{
printf("\r0x%08X: ", address + (i * 4));
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
while(inputResponseCnt ==0 && !bQuit)
{
printf("\r0x%08X: ", address + (i * 4));
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
if(strstr((const char*)inputBuffer,"0x")==NULL)
{
write =atoi((const char *)inputBuffer);
*data=write;
}
else
{
write=strtoul((const char *)inputBuffer,NULL,0);
*data=write;
}
memset(inputBuffer,0,sizeof(inputBuffer));
check_status(naibrd_Write32(cardIndex, module, offset,4,1,4, data));
offset+=4;
}
}
}
return NAI_SUCCESS;
}
static nai_status_t BasicMenu_SaveRegFile_Func(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ad_params->cardIndex;
int32_t module = p_ad_params->module;
int32_t modid= naibrd_GetModuleID(cardIndex,module);
char *modIdName = (char*)&modid;
char filepathandname[162];
printf("Enter a file name [default = %s]:", REG_FILE);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if(!bQuit)
{
memset(filepathandname, 0, sizeof(filepathandname));
if(inputResponseCnt==0)
{
#if defined (WIN32)
strcpy_s(filepathandname, sizeof(REG_FILE), (const char*)REG_FILE);
#else
strcpy(filepathandname, (const char*)REG_FILE);
#endif
}
else
{
#if defined(WIN32)
strcpy_s(filepathandname, sizeof(inputBuffer), (const char*)inputBuffer);
#else
strcpy(filepathandname, (const char*)inputBuffer);
#endif
}
}
/* open the file for writing*/
#if defined (WIN32)
fopen_s(&fp, (const char*)filepathandname, "w");
#else
fp = fopen((const char*)filepathandname, "w");
#endif
fprintf(fp,"Board Index: %d, %d", cardIndex, module);
if (module > 0)
{
fprintf(fp,"Module No. %d, Module ID: %c%c%c%c\r\n", module, modIdName[3], modIdName[2], modIdName[1] ,modIdName[0]);
}
else
{
fprintf(fp,"Motherboard Register Space\r\n");
}
if(((savedAddress!=0) && (savedCount!=0)) || (savedDataArray!=NULL))
{
if(save_Last_Read(fp,savedAddress,savedCount,4,savedDataArray)==0)
{
printf("Saved %s!",filepathandname);
}
else
{
printf("Failed to save %s!",filepathandname);
}
}
fclose(fp);
return NAI_SUCCESS;
}
int32_t save_Last_Read(FILE *deffile,uint32_t addr, int32_t len, int32_t dataWidth, void* p_data)
{
uint32_t colData[16];
int32_t index;
int32_t row;
int32_t col;
int32_t retValue = 0;
int32_t missCnt;
int32_t cnt;
int32_t i;
uint8_t ucChar;
uint8_t* p_dataArray8 = (uint8_t*)p_data;
uint16_t* p_dataArray16 = (uint16_t*)p_data;
uint32_t* p_dataArray32 = (uint32_t*)p_data;
/* Check data width */
if (dataWidth == 1 || dataWidth == 2 || dataWidth == 4)
{
/* Print the Header */
/* 00 02 04 06 08 0A 0C 0E */
/* ----- ----- ----- ----- ----- ----- ----- ----- */
/* Print the Data Header */
fprintf(deffile,"\r ");
switch (dataWidth)
{
case 1:
for (index = 0; index < (16 / dataWidth); index++)
{
fprintf(deffile,"%02X ", ((addr + (index * dataWidth)) & 0x0F));
}
fprintf(deffile,"\r\n ");
for (index = 0; index < (16 / dataWidth); index++)
{
fprintf(deffile,"-- ");
}
break;
case 2:
for (index = 0; index < (16 / dataWidth); index++)
{
fprintf(deffile,"%02X ", ((addr + (index * dataWidth)) & 0x0F));
}
fprintf(deffile,"\r\n ");
for (index = 0; index < (16 / dataWidth); index++)
{
fprintf(deffile,"---- ");
}
break;
case 4:
for (index = 0; index < (16 / dataWidth); index++)
{
fprintf(deffile,"%02X ", ((addr + (index * dataWidth)) & 0x0F));
}
fprintf(deffile,"\r ");
for (index = 0; index < (16 / dataWidth); index++)
{
fprintf(deffile,"-------- ");
}
break;
default:
fprintf(deffile," ");
break;
}
/* Print the formatted data */
index = 0;
missCnt = 0;
for (row = 0; row <= (len - 1) / (16 / dataWidth); row++)
{
/* Print the Hex values */
fprintf(deffile,"\r0x%08X: ", addr + (index * dataWidth));
for (col = 0; col < (16 / dataWidth); col++)
{
/* Print the Hex Value of the data */
switch (dataWidth)
{
case 1:
if (index == len)
{ /* No more data */
++missCnt;
colData[col] = 0; /* Save data for ASCII Print */
fprintf(deffile," ");
}
else
{
colData[col] = p_dataArray8[index]; /* Save data for ASCII Print */
fprintf(deffile,"%02X ", p_dataArray8[index++]);
}
break;
case 2:
if (index == len)
{ /* No more data */
++missCnt;
colData[col] = 0; /* Save data for ASCII Print */
fprintf(deffile," ");
}
else
{
colData[col] = p_dataArray16[index]; /* Save data for ASCII Print */
fprintf(deffile,"%04X ", p_dataArray16[index++]);
}
break;
case 4:
if (index == len)
{ /* No more data */
++missCnt;
colData[col] = 0; /* Save data for ASCII Print */
fprintf(deffile," ");
}
else
{
colData[col] = p_dataArray32[index]; /* Save data for ASCII Print */
fprintf(deffile,"%08X ", p_dataArray32[index++]);
}
break;
default:
fprintf(deffile," ");
break;
}
}
/* Print the data in ASCII */
fprintf(deffile," ");
for (col = 0; col < (16 / dataWidth); col++)
{
if (col > ((16 / dataWidth) - missCnt) - 1)
{ /* No more data, print blanks */
switch (dataWidth)
{
case 1:
fprintf(deffile," ");
break;
case 2:
fprintf(deffile," ");
break;
case 4:
fprintf(deffile," ");
break;
default:
fprintf(deffile," ");
break;
}
}
else
{ /* Print the ASCII Value of the data */
switch (dataWidth)
{
case 1:
cnt = 1;
break;
case 2:
cnt = 2;
break;
case 4:
cnt = 4;
break;
default:
cnt = 0;
break;
}
for (i = 1; i <= cnt; i++)
{
ucChar = (colData[col] >> (8 * (cnt - i))) & 0xFF;
if (isprint(ucChar))
{
fprintf(deffile,"%c", ucChar);
}
else
{
fprintf(deffile,".");
}
}
fprintf(deffile," ");
}
}
}
fprintf(deffile,"\r\n");
}
else
{
retValue = -1; /* Invalid data width */
}
return retValue;
}