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

SD BasicOps

SD BasicOps Sample Application (SSK 2.x)

Overview

The SD BasicOps sample application demonstrates how to configure and read synchro/resolver-to-digital channels using the NAI Software Support Kit (SSK 2.x). It covers the core SD operations needed in your own application: setting the channel mode (resolver or synchro), configuring fault thresholds (signal loss, reference loss, signal high, reference high, open, and short), managing delta angle reporting, enabling channel status, clearing latched statuses, performing BIT (Built-In Test) operations, and reading angle, frequency, and voltage measurements.

This sample supports the SD1 through SD5 module types. It includes both a main operations menu and a subordinate BIT test menu, as well as the ability to toggle between converted and raw hex display modes. Refer to the SD1-SD5 Manual for detailed module specifications.

For the SSK 1.x version, see SD BasicOps (SSK 1.x).

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with an SD module installed (SD1-SD5).

  • SSK 2.x installed on your development host.

  • The sample applications built. Refer to the SSK 2.x Software Development Guide for platform-specific build instructions.

How to Run

Launch the sd_basic_ops executable from your build output directory. On startup the application looks for a configuration file (default_sd_basic_ops.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, a measurement display shows all channels followed by a command menu.

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

The main() function follows a standard SSK 2.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_sd_basic_ops.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_GetModuleName() so downstream code can adapt to the specific SD variant installed.

#if defined (__VXWORKS__)
int32_t SD_BasicOpsMenu(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = NAI_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) == NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               g_modId = moduleID;
               if ((moduleID != 0))
               {
                  SDBasicMenu_Run(cardIndex, module, moduleID);
               }
            }
         }
         naiif_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);
      }
   }
   naiif_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 the SSK 2.x differences from SSK 1.x in this startup sequence:

  • This sample uses the legacy __VXWORKS__ preprocessor guard. Most SSK 2.x samples use NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS.

  • The module identifier is retrieved with naibrd_GetModuleName() (SSK 1.x uses naibrd_GetModuleID()).

  • Boolean constants are NAI_TRUE / NAI_FALSE (SSK 1.x uses TRUE / FALSE).

  • Console output uses naiif_printf() from the platform abstraction layer (SSK 1.x uses printf() directly).

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 an SD module. Use the board menu to verify which slots are populated.

Program Structure

Entry Point

On standard platforms (Petalinux, DEOS) the entry point is main(). On VxWorks the entry point is SD_BasicOpsMenu().

Note
This source file uses the older __VXWORKS__ preprocessor guard rather than the SSK 2.x standard NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS.

Command Loop

The SDBasicMenu_Run() function loads the command table, displays the current measurements and statuses for all channels, and enters a do…​while loop that processes user commands. Many commands prompt for a channel number before executing.

Command Description

Mode

Set SD mode (Resolver or Synchro)

Enable

Enable or disable channel status reporting

Clear

Clear a specific latched status type

LoSig

Set signal fault low threshold

LoRef

Set reference fault low threshold

HiSig

Set signal fault high threshold

HiRef

Set reference fault high threshold

Open

Set open threshold

Short

Set short threshold

Delta

Set delta angle value

Init

Initialize delta angle status reporting

Float

Enter floating-point submenu

Test

Enter BIT test submenu

Converted

Display values with unit conversion

Hex Display

Display values as raw hex

Read

Read a register directly

Write

Write a register directly

BIT Test Sub-Menu

The BIT test sub-menu provides built-in test diagnostics for verifying SD module health. It displays per-channel BIT status and error limits, the current test angle, D0 test enable state, and power-on BIT completion status.

Command Description

Status

Clear the latched BIT status for a selected channel.

Limit

Set the BIT error limit for a selected channel.

Angle

Set the SD test angle value (module-wide).

Enable

Enable or disable D0 internal test mode.

Power On

Check whether the power-on BIT has completed.

Converted

Display BIT values with unit conversion.

Hex

Display BIT values as raw hex.

Floating-Point Sub-Menu

The floating-point sub-menu allows you to enable hardware floating-point conversion mode and configure per-channel angle and velocity scale/offset attributes. When floating-point mode is enabled, the module returns angle and velocity readings with the configured scale and offset applied in hardware.

Command Description

0 (mode)

Enable or disable floating-point mode.

1 (attributes)

Set a floating-point attribute (angle scale, angle offset, velocity scale, or velocity offset) for a specific channel.

Display Measurements and Status

The SDBasicMenu_displayMeasurements() function reads and displays all channel data in a tabular format. For each channel it shows mode, angle, frequency, signal voltage, reference voltage, fault thresholds, and delta angle. It also displays the channel status table with BIT, signal/reference faults, lock loss, open, short, delta angle, and summary status. The display supports both converted (engineering units) and raw hex modes.

float64_t angle = 0.0, frequency = 0.0, sigvolt = 0.0, refvolt = 0.0;

/* Read the angle, frequency, signal and reference voltages */
naibrd_SD_GetAngle(cardIndex, module, channel, &angle);
naibrd_SD_GetFrequency(cardIndex, module, channel, &frequency);
naibrd_SD_GetSignalVoltage(cardIndex, module, channel, &sigvolt);
naibrd_SD_GetRefVoltage(cardIndex, module, channel, &refvolt);

For raw hex display mode, use the naibrd_SD_GetChannelRaw() function with the appropriate raw type:

uint32_t rawangle = 0u, rawfreq = 0u;

naibrd_SD_GetChannelRaw(cardIndex, module, channel,
   NAIBRD_SD_CHAN_RAW_ANGLE, &rawangle);
naibrd_SD_GetChannelRaw(cardIndex, module, channel,
   NAIBRD_SD_CHAN_RAW_FREQUENCY, &rawfreq);
  • naibrd_SD_GetAngle() — reads the current angle measurement in degrees.

  • naibrd_SD_GetFrequency() — reads the excitation frequency in Hz.

  • naibrd_SD_GetSignalVoltage() / naibrd_SD_GetRefVoltage() — read signal and reference voltages in volts.

  • naibrd_SD_GetThreshold() — reads a specific threshold value.

  • naibrd_SD_GetChanMappedStatus() — reads a specific channel status bit.

  • naibrd_SD_GetChanStatusEnable() — checks whether status reporting is enabled.

The status display reads multiple channel-mapped status types to build a complete health picture:

nai_status_bit_t BitStatus, SigLoss, RefLoss, SummaryStatus;

naibrd_SD_GetChanMappedStatus(cardIndex, module, channel,
   NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED, &BitStatus);
naibrd_SD_GetChanMappedStatus(cardIndex, module, channel,
   NAIBRD_SD_CHAN_MAPPED_STATUS_SIGNAL_LATCHED, &SigLoss);
naibrd_SD_GetChanMappedStatus(cardIndex, module, channel,
   NAIBRD_SD_CHAN_MAPPED_STATUS_REF_LATCHED, &RefLoss);
naibrd_SD_GetChanMappedStatus(cardIndex, module, channel,
   NAIBRD_SD_CHAN_MAPPED_STATUS_SUMMARY_LATCHED, &SummaryStatus);
  • NAI_STATUS_BIT_HI indicates a fault condition; NAI_STATUS_BIT_LO indicates normal operation.

  • Available status types include _BIT_LATCHED, _SIGNAL_LATCHED, _REF_LATCHED, _SIG_FAULT_HIGH_LATCHED, _REF_FAULT_HIGH_LATCHED, _2SPDLOCKLOSS_LATCHED, _OPEN_LATCHED, _SHORT_LATCHED, _ANGLEDELTA_LATCHED, and _SUMMARY_LATCHED.

Set Channel Mode

The SDBasicMenu_SetMode() function sets the channel operating mode to either Resolver (NAIBRD_SD_RESOLVER) or Synchro (NAIBRD_SD_SYNCHRO). The mode determines how the module interprets the input signals — resolver mode expects sine/cosine pairs from a resolver transducer, while synchro mode expects three-wire synchro signals.

naibrd_sd_format_t mode;

/* Set channel to resolver mode */
mode = NAIBRD_SD_RESOLVER;
check_status(naibrd_SD_SetChanMode(cardIndex, module, channel, mode));

/* Set channel to synchro mode */
mode = NAIBRD_SD_SYNCHRO;
check_status(naibrd_SD_SetChanMode(cardIndex, module, channel, mode));
  • cardIndex — identifies the board.

  • module — the slot containing the SD module.

  • channel — the channel to configure.

  • mode — NAIBRD_SD_RESOLVER (0) or NAIBRD_SD_SYNCHRO (1).

Configure Thresholds

Several functions configure fault detection thresholds. Each follows the same pattern: prompt for a value (in converted or raw hex format depending on the display mode), then write it to the module. In converted mode, thresholds are specified as floating-point voltage values; in hex mode, you write the raw register value directly.

float64_t threshold;

/* Set the signal fault low threshold (minimum signal voltage before alert) */
threshold = 0.50;
naibrd_SD_SetThreshold(cardIndex, module, channel,
   NAIBRD_SD_SIG_FAULT_LO_THRESHOLD, threshold);

/* Set the reference fault high threshold (maximum reference voltage before alert) */
threshold = 30.0;
naibrd_SD_SetThreshold(cardIndex, module, channel,
   NAIBRD_SD_REF_FAULT_HI_THRESHOLD, threshold);

For raw hex register access:

uint32_t thresholdRaw = 0x00001000u;

naibrd_SD_SetChannelRaw(cardIndex, module, channel,
   NAIBRD_SD_CHAN_RAW_SIG_LOSS_THRESHOLD, thresholdRaw);
  • naibrd_SD_SetThreshold() — sets a threshold using a converted floating-point value.

  • naibrd_SD_SetChannelRaw() — sets a threshold using a raw hex value.

  • Supported threshold types: NAIBRD_SD_SIG_FAULT_LO_THRESHOLD, NAIBRD_SD_REF_FAULT_LO_THRESHOLD, NAIBRD_SD_SIG_FAULT_HI_THRESHOLD, NAIBRD_SD_REF_FAULT_HI_THRESHOLD, NAIBRD_SD_OPEN_THRESHOLD, NAIBRD_SD_SHORT_THRESHOLD.

Set Delta Angle

The delta angle threshold determines the maximum allowable change in angle between successive readings before a delta angle fault is flagged. This is useful for detecting unexpected jumps in the resolver/synchro position. After setting the threshold, you must initialize delta angle reporting on the channel to start monitoring.

float64_t deltaAngle = 5.0; /* degrees */

/* Set the delta angle threshold */
naibrd_SD_SetAngleDelta(cardIndex, module, channel, deltaAngle);

/* Enable delta angle status reporting */
naibrd_SD_SetAngleDataInit(cardIndex, module, channel, (bool_t)0x1u);

/* To disable delta angle status reporting */
naibrd_SD_SetAngleDataInit(cardIndex, module, channel, (bool_t)0x0u);
  • deltaAngle — the threshold value in degrees. Any angle change exceeding this value triggers a delta angle fault.

  • naibrd_SD_SetAngleDataInit() — pass 0x1u to enable, 0x0u to disable delta angle reporting.

Clear Status and Enable Channel Status

The SDBasicMenu_ClearStatus() function clears a user-selected latched status type. Each status type has a separate latched register that retains the fault indication until explicitly cleared. Channel status enable controls whether the module monitors for faults on a given channel.

/* Enable channel status reporting */
naibrd_SD_SetChanStatusEnable(cardIndex, module, channel, 1u);

/* Disable channel status reporting */
naibrd_SD_SetChanStatusEnable(cardIndex, module, channel, 0u);

/* Clear the latched BIT status */
naibrd_SD_ClearChanMappedStatus(cardIndex, module, channel,
   NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED);

/* Clear the latched signal fault low status */
naibrd_SD_ClearChanMappedStatus(cardIndex, module, channel,
   NAIBRD_SD_CHAN_MAPPED_STATUS_SIGNAL_LATCHED);
  • The second parameter to naibrd_SD_SetChanStatusEnable() is 1u to enable, 0u to disable.

  • Clearable status types: _BIT_LATCHED, _SIGNAL_LATCHED, _REF_LATCHED, _SIG_FAULT_HIGH_LATCHED, _REF_FAULT_HIGH_LATCHED, _2SPDLOCKLOSS_LATCHED, _OPEN_LATCHED, _SHORT_LATCHED, _ANGLEDELTA_LATCHED, _SUMMARY_LATCHED.

BIT Test Operations

The BIT test sub-menu provides comprehensive built-in test functionality. It displays the current BIT status and error limit for each channel, the module-wide test angle, D0 test enable state, and power-on BIT completion status.

Set BIT Error Limit

The BIT error limit defines the maximum acceptable measurement error during D0 testing. If the measured angle deviates from the test angle by more than this limit, the BIT status is set to FAILED.

float64_t bitErrorLimit = 1.0; /* degrees */

/* Set the BIT error limit for a specific channel */
naibrd_SD_SetBITErrorLimit(cardIndex, module, channel, bitErrorLimit);

For raw hex access:

uint32_t bitErrorLimitRaw = 0x00000100u;

naibrd_SD_SetChannelRaw(cardIndex, module, channel,
   NAIBRD_SD_CHAN_RAW_BIT_ERROR_LIMIT, bitErrorLimitRaw);
  • bitErrorLimit — the maximum allowable error in degrees.

Set Test Angle and Enable D0 Test

The test angle is a module-wide value injected as a simulated input when D0 test mode is enabled. This allows you to verify that the SD conversion pipeline is working correctly without an external signal source.

float64_t testAngle = 45.0; /* degrees */

/* Set the test angle */
naibrd_SD_SetTestAngle(cardIndex, module, testAngle);

/* Enable D0 internal test mode */
naibrd_SD_SetModuleBITEnable(cardIndex, module,
   NAIBRD_SD_TEST_ENABLE_D0, (bool_t)NAI_TRUE);

/* Disable D0 internal test mode */
naibrd_SD_SetModuleBITEnable(cardIndex, module,
   NAIBRD_SD_TEST_ENABLE_D0, (bool_t)NAI_FALSE);
  • testAngle — the angle value in degrees to inject during D0 testing.

  • When D0 test is enabled, the module substitutes the test angle for the actual input signal. Each channel’s measured angle should match the test angle within the configured BIT error limit.

Check Power-On BIT

Power-on BIT runs automatically when the module is powered up. Call naibrd_SD_CheckPowerOnBITComplete() to verify that the test has completed, then check the per-channel BIT status to see if any channels failed.

bool_t pBitComplete = NAI_FALSE;
nai_status_bit_t bitStatus;

/* Check if power-on BIT has completed */
naibrd_SD_CheckPowerOnBITComplete(cardIndex, module, &pBitComplete);

if (pBitComplete)
{
   /* Read per-channel BIT status */
   for (channel = 1; channel <= channelCount; channel++)
   {
      naibrd_SD_GetChanMappedStatus(cardIndex, module, channel,
         NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED, &bitStatus);
      /* bitStatus: NAI_STATUS_BIT_LO = Normal, NAI_STATUS_BIT_HI = FAILED */
   }
}
  • pBitComplete — NAI_TRUE if power-on BIT has finished, NAI_FALSE if still in progress.

Clear BIT Status

To clear a latched BIT fault after investigating and resolving the issue, call naibrd_SD_ClearChanMappedStatus():

naibrd_SD_ClearChanMappedStatus(cardIndex, module, channel,
   NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED);

Floating-Point Mode

The floating-point sub-menu enables hardware-level scale and offset conversion for angle and velocity readings. When enabled, the module applies the configured scale and offset to raw measurements before returning them, reducing the processing burden on the host application.

/* Enable floating-point mode for the module */
naibrd_SetFloatingPointModeEnable(cardIndex, module, NAI_TRUE);

/* Set angle scale and offset for a channel */
naibrd_SD_SetFloatingPointAttributes(cardIndex, module, channel,
   NAIBRD_SD_ANGLE_SCALE, 1.0);
naibrd_SD_SetFloatingPointAttributes(cardIndex, module, channel,
   NAIBRD_SD_ANGLE_OFFSET, 0.0);

/* Set velocity scale and offset for a channel */
naibrd_SD_SetFloatingPointAttributes(cardIndex, module, channel,
   NAIBRD_SD_VELOCITY_SCALE, 1.0);
naibrd_SD_SetFloatingPointAttributes(cardIndex, module, channel,
   NAIBRD_SD_VELOCITY_OFFSET, 0.0);

/* Read back floating-point attributes */
float64_t angleScale = 0.0;
naibrd_SD_GetFloatingPointAttributes(cardIndex, module, channel,
   NAIBRD_SD_ANGLE_SCALE, &angleScale);

/* Check if floating-point mode is enabled */
bool_t floatModeEnabled = NAI_FALSE;
naibrd_GetFloatingPointModeEnable(cardIndex, module, &floatModeEnabled);

/* Disable floating-point mode */
naibrd_SetFloatingPointModeEnable(cardIndex, module, NAI_FALSE);
  • Attribute types: NAIBRD_SD_ANGLE_SCALE, NAIBRD_SD_ANGLE_OFFSET, NAIBRD_SD_VELOCITY_SCALE, NAIBRD_SD_VELOCITY_OFFSET.

  • The scale and offset are applied as: output = (raw * scale) + offset.

  • naibrd_SetFloatingPointModeEnable() / naibrd_GetFloatingPointModeEnable() control the module-wide floating-point mode.

Troubleshooting Reference

Error / Symptom Possible Causes Suggested Resolution

No board found

Board not powered or not connected

Verify power and physical connections; check configuration file

Connection timeout

Network/bus misconfiguration

Confirm IP address, subnet, or PCI/PCIe settings

Invalid card or module index

Wrong index values entered

Cards are zero-based, modules are one-based

Module not present at selected slot

Slot is empty or contains a different module type

Use the board menu to verify slot population

Angle reads zero on all channels

Module not connected to synchro/resolver signal source

Verify signal wiring to the SD module

Signal fault low status asserted

Signal voltage below configured threshold

Check signal source; adjust threshold if appropriate

Reference fault low status asserted

Reference voltage below configured threshold

Check reference excitation; adjust threshold if appropriate

BIT status FAILED

Hardware or calibration issue detected

Check module health; clear status and re-run BIT

Invalid SD mode entered

Value other than 0 or 1 provided

Enter 0 for Resolver or 1 for Synchro

Delta angle status asserted

Angle change exceeds configured delta threshold

Adjust delta angle threshold or reinitialize delta angle reporting

Full Source

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

Full Source — sd_basic_ops.c (SSK 2.x)
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"

/* naibrd include files */
#include "nai_libs/naibrd/include/naibrd.h"
#include "nai_libs/naibrd/include/functions/naibrd_sd.h"

/* naiif include files */
#include "nai_libs/naiif/include/naiif.h"
#include "nai_libs/naiif/include/naiif_stdio.h"

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

#define CHAN_STATUS_ENABLE_MSG_LENGTH (10)
#define STATUS_TYPE_MSG_LENGTH        (18)
#define FLOAT_MODE_MSG_LENGTH         (10)
#define ATTRIBUTE_TYPE_MSG_LENGTH     (20)
#define BIT_STATUS_MSG_LENGTH         (7)
#define D0_TEST_ENABLE_MSG_LENGTH     (10)
#define PBIT_COMPLETE_MSG_LENGTH      (15)
#define PBIT_BIT_STATUS_MSG_LENGTH    (12)
#define READ_REG_BUFFER_MSG_LENGTH    (500)

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

/* Function prototypes */
static bool_t SDBasicMenu_Run(int32_t cardIndex, int32_t module, uint32_t modid);
static void SDBasicMenu_displayMeasurements(int32_t cardIndex, int32_t module, uint32_t modid);
static void SDBasicMenu_displayMode(naibrd_sd_format_t mode);
static void SDBasicMenu_displayStatus(nai_status_bit_t BitStatus, nai_status_bit_t SigLoss, nai_status_bit_t RefLoss,
                                      nai_status_bit_t LockLossStat, nai_status_bit_t DeltaAngleStat, nai_status_bit_t OpenStat,
                                      nai_status_bit_t ShortStat, nai_status_bit_t RefHiStat, nai_status_bit_t SigHiStat,
                                      nai_status_bit_t SummaryStatus);

/* SD Basic Ops Command Functions */
static nai_status_t SDBasicMenu_SetMode(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_SetChanStatusEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_ClearStatus(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_SetSigLossThreshold(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_SetRefLossThreshold(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_SetSigFaultHiThreshold(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_SetRefFaultHiThreshold(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_SetOpenThreshold(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_SetShortThreshold(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_SetDeltaAngle(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_InitDeltaAngle(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_FloatingPointMenu(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_TestMenu(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_ReadReg(int32_t paramCount, int32_t* p_params);
static nai_status_t SDBasicMenu_WriteReg(int32_t paramCount, int32_t* p_params);

static nai_status_t SDTestMenu_ClearBITStatus(int32_t paramCount, int32_t* p_params);
static nai_status_t SDTestMenu_SetBITErrorLimit(int32_t paramCount, int32_t* p_params);
static nai_status_t SDTestMenu_SetTestAngle(int32_t paramCount, int32_t* p_params);
static nai_status_t SDTestMenu_SetD0TestEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t SDTestMenu_CheckPowerOnBIT(int32_t paramCount, int32_t* p_params);

static bool_t DisplayAsHex = NAI_FALSE;
static uint32_t g_modId = 0u;

/****** Command Table *******/
enum sd_basicOpsMenu_commands
{
   SD_BASICMENU_CMD_SET_MODE,
   SD_BASICMENU_CMD_SET_CHAN_STATUS_ENABLE,
   SD_BASICMENU_CMD_CLEAR_STATUS,
   SD_BASICMENU_CMD_SET_SIGLOSS_THRESHOLD,
   SD_BASICMENU_CMD_SET_REFLOSS_THRESHOLD,
   SD_BASICMENU_CMD_SET_SIG_HI_THRESHOLD,
   SD_BASICMENU_CMD_SET_REF_HI_THRESHOLD,
   SD_BASICMENU_CMD_SET_OPEN_THRESHOLD,
   SD_BASICMENU_CMD_SET_SHORT_THRESHOLD,
   SD_BASICMENU_CMD_SET_DELTA_ANGLE,
   SD_BASICMENU_CMD_INIT_DELTA_ANGLE,
   SD_BASICMENU_CMD_FLOATING_POINT,
   SD_BASICMENU_CMD_TEST,
   SD_BASICMENU_CMD_DISPLAY_CONVERTED,
   SD_BASICMENU_CMD_DISPLAY_HEX,
   SD_BASICMENU_CMD_READ_REG,
   SD_BASICMENU_CMD_WRITE_REG,
   SD_BASICMENU_CMD_COUNT
};

enum sd_basicOpsMenu_test_commands
{
   SD_TESTMENU_CMD_CLEAR_BIT_STATUS,
   SD_TESTMENU_CMD_SET_BIT_ERROR_LIMIT,
   SD_TESTMENU_CMD_SET_TEST_ANGLE,
   SD_TESTMENU_CMD_ENABLE_D0_TEST,
   SD_TESTMENU_CMD_CHECK_PBIT,
   SD_TESTMENU_CMD_DISPLAY_CONVERTED,
   SD_TESTMENU_CMD_DISPLAY_HEX,
   SD_TESTMENU_CMD_COUNT
};

naiapp_cmdtbl_params_t SD_BasicOpMenuCmds[] = {
   {"Mode",        "Set SD Mode",                             SD_BASICMENU_CMD_SET_MODE,               SDBasicMenu_SetMode},
   {"Enable",      "Enable/Disable Channel Status Reporting", SD_BASICMENU_CMD_SET_CHAN_STATUS_ENABLE, SDBasicMenu_SetChanStatusEnable},
   {"Clear",       "Clear Latched Status",                    SD_BASICMENU_CMD_CLEAR_STATUS,           SDBasicMenu_ClearStatus},
   {"LoSig",       "Set SD Signal Fault Low Threshold",       SD_BASICMENU_CMD_SET_SIGLOSS_THRESHOLD,  SDBasicMenu_SetSigLossThreshold},
   {"LoRef",       "Set SD Reference Fault Low Threshold",    SD_BASICMENU_CMD_SET_REFLOSS_THRESHOLD,  SDBasicMenu_SetRefLossThreshold},
   {"HiSig",       "Set SD Signal Fault High Threshold",      SD_BASICMENU_CMD_SET_SIG_HI_THRESHOLD,   SDBasicMenu_SetSigFaultHiThreshold},
   {"HiRef",       "Set SD Reference Fault High Threshold",   SD_BASICMENU_CMD_SET_REF_HI_THRESHOLD,   SDBasicMenu_SetRefFaultHiThreshold},
   {"Open",        "Set SD Open Threshold",                   SD_BASICMENU_CMD_SET_OPEN_THRESHOLD,     SDBasicMenu_SetOpenThreshold},
   {"Short",       "Set SD Short Threshold",                  SD_BASICMENU_CMD_SET_SHORT_THRESHOLD,    SDBasicMenu_SetShortThreshold},
   {"Delta",       "Set SD Delta Angle Value",                SD_BASICMENU_CMD_SET_DELTA_ANGLE,        SDBasicMenu_SetDeltaAngle},
   {"Init",        "Initialize Delta Angle Status Reporting", SD_BASICMENU_CMD_INIT_DELTA_ANGLE,       SDBasicMenu_InitDeltaAngle},
   {"Float",       "SD Floating-Point Menu",                  SD_BASICMENU_CMD_FLOATING_POINT,         SDBasicMenu_FloatingPointMenu},
   {"Test",        "SD BIT Test Menu",                        SD_BASICMENU_CMD_TEST,                   SDBasicMenu_TestMenu},
   {"Converted",   "Display Values with Conversion",          SD_BASICMENU_CMD_DISPLAY_CONVERTED,      NULL},
   {"Hex Display", "Display Value as Hex",                    SD_BASICMENU_CMD_DISPLAY_HEX,            NULL},
   {"Read",        "Read Register",                           SD_BASICMENU_CMD_READ_REG,               SDBasicMenu_ReadReg},
   {"Write",       "Write Register",                          SD_BASICMENU_CMD_WRITE_REG,              SDBasicMenu_WriteReg}
};

naiapp_cmdtbl_params_t SD_TestMenuCmds[] = {
   {"Status",      "Clear BIT Latched Status",                SD_TESTMENU_CMD_CLEAR_BIT_STATUS,        SDTestMenu_ClearBITStatus},
   {"Limit",       "Set BIT Error Limit",                     SD_TESTMENU_CMD_SET_BIT_ERROR_LIMIT,     SDTestMenu_SetBITErrorLimit},
   {"Angle",       "Set SD Test Angle",                       SD_TESTMENU_CMD_SET_TEST_ANGLE,          SDTestMenu_SetTestAngle},
   {"Enable",      "Enable or Disable D0 Test",               SD_TESTMENU_CMD_ENABLE_D0_TEST,          SDTestMenu_SetD0TestEnable},
   {"Power On",    "Check Power-On BIT",                      SD_TESTMENU_CMD_CHECK_PBIT,              SDTestMenu_CheckPowerOnBIT},
   {"Converted",   "Display Values with Conversion",          SD_TESTMENU_CMD_DISPLAY_CONVERTED,       NULL},
   {"Hex",         "Display Values as Hex",                   SD_TESTMENU_CMD_DISPLAY_HEX,             NULL}
};
/*****************************************************************************/
/**
<summary>
The purpose of the sd_basic_ops is to illustrate the methods to call in the
naibrd library to perform basic operations with the SD modules for
configuration setup and reading the channels.

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 SD routines.
 - ConfigDevice
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - CheckModule
</summary>
*/
/*****************************************************************************/
#if defined (__VXWORKS__)
int32_t SD_BasicOpsMenu(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = NAI_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) == NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         /* Query the user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Query the user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               g_modId = moduleID;
               if ((moduleID != 0))
               {
                  SDBasicMenu_Run(cardIndex, module, moduleID);
               }
            }
         }

         naiif_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);
      }
   }

   naiif_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;
}
/*****************************************************************************/
/**
<summary>
SDBasicMenu_Run illustrates the channel configuration and prepares the menu
which will handle user command requests. Returns NAI_TRUE if the user enters
the Quit Command at any point within its scope.
</summary>
*/
/*****************************************************************************/
static bool_t SDBasicMenu_Run(int32_t cardIndex, int32_t module, uint32_t modid)
{
   bool_t bQuit = NAI_FALSE, bCmdFound = NAI_FALSE;
   int32_t MAX_CHANNELS = naibrd_SD_GetChannelCount(modid);
   int32_t cmd;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   naiapp_AppParameters_t  sd_basicops_params;
   p_naiapp_AppParameters_t sd_basicOps_params = &sd_basicops_params;
   sd_basicOps_params->cardIndex = cardIndex;
   sd_basicOps_params->module = module;
   sd_basicOps_params->maxChannels = naibrd_SD_GetChannelCount(modid);
   sd_basicOps_params->modId = modid;
   sd_basicOps_params->displayHex = NAI_FALSE;

   naiapp_utils_LoadParamMenuCommands(SD_BASICMENU_CMD_COUNT, SD_BasicOpMenuCmds);
   do
   {
      naiapp_utils_LoadParamMenuCommands(SD_BASICMENU_CMD_COUNT, SD_BasicOpMenuCmds);
      SDBasicMenu_displayMeasurements(cardIndex, module, modid);
      naiapp_display_ParamMenuCommands((int8_t*)"SD Basic Ops");
      naiif_printf("\r\n Type 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 ((cmd >= 0) && (cmd < SD_BASICMENU_CMD_COUNT) && (bCmdFound))
         {
            if (cmd == SD_BASICMENU_CMD_DISPLAY_CONVERTED)
            {
               DisplayAsHex = NAI_FALSE;
            }
            else if (cmd == SD_BASICMENU_CMD_DISPLAY_HEX)
            {
               DisplayAsHex = NAI_TRUE;
            }
            else
            {
               if ((cmd == SD_BASICMENU_CMD_SET_MODE) || (cmd == SD_BASICMENU_CMD_SET_CHAN_STATUS_ENABLE) ||
                   (cmd == SD_BASICMENU_CMD_CLEAR_STATUS) || (cmd == SD_BASICMENU_CMD_SET_SIGLOSS_THRESHOLD) ||
                   (cmd == SD_BASICMENU_CMD_SET_REFLOSS_THRESHOLD) || (cmd == SD_BASICMENU_CMD_SET_SIG_HI_THRESHOLD) ||
                   (cmd == SD_BASICMENU_CMD_SET_REF_HI_THRESHOLD) || (cmd == SD_BASICMENU_CMD_SET_OPEN_THRESHOLD) ||
                   (cmd == SD_BASICMENU_CMD_SET_SHORT_THRESHOLD) || (cmd == SD_BASICMENU_CMD_SET_DELTA_ANGLE) ||
                   (cmd == SD_BASICMENU_CMD_INIT_DELTA_ANGLE) || (cmd == SD_BASICMENU_CMD_FLOATING_POINT) ||
                   (cmd == SD_BASICMENU_CMD_TEST) || (cmd == SD_BASICMENU_CMD_READ_REG) ||
                   (cmd == SD_BASICMENU_CMD_WRITE_REG))
               {
                  if ((cmd != SD_BASICMENU_CMD_FLOATING_POINT) && (cmd != SD_BASICMENU_CMD_TEST) &&
                      (cmd != SD_BASICMENU_CMD_READ_REG) && (cmd != SD_BASICMENU_CMD_WRITE_REG))
                  {
                     naiapp_query_ChannelNumber(MAX_CHANNELS, 1, &sd_basicOps_params->channel);
                  }
                  SD_BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)sd_basicOps_params);
               }
            }
         }
         else
         {
            naiif_printf(" Invalid command entered\r\n");
         }
      }
   } while (!bQuit);
   return bQuit;
}

/*****************************************************************************/
/**
<summary>
SDBasicMenu_displayMeasurements illustrates the methods to call in the naibrd library
to retrieve the basic operation configuration states and status states
as well as the current SD reading for all channels.
</summary>
*/
/*****************************************************************************/
static void SDBasicMenu_displayMeasurements(int32_t cardIndex, int32_t module, uint32_t modid)
{
   uint32_t chanStatusEnable = 0u;
   int32_t channel = 0, MAX_CHANNEL = naibrd_SD_GetChannelCount(modid);
   naibrd_sd_format_t mode = 0u;
   float64_t angle = 0.0, frequency = 0.0, sigvolt = 0.0, refvolt = 0.0, minsigvolt = 0.0, minrefvolt = 0.0;
   float64_t maxsigvolt = 0.0, maxrefvolt = 0.0, openThres = 0.0, shortThres = 0.0, deltaAngle = 0.0;
   nai_status_bit_t BitStatus = NAI_STATUS_BIT_LO;
   nai_status_bit_t SigLoss = NAI_STATUS_BIT_LO;
   nai_status_bit_t RefLoss = NAI_STATUS_BIT_LO;
   nai_status_bit_t SummaryStatus = NAI_STATUS_BIT_LO;
   nai_status_bit_t SigHiStat = NAI_STATUS_BIT_LO;
   nai_status_bit_t RefHiStat = NAI_STATUS_BIT_LO;
   nai_status_bit_t OpenStat = NAI_STATUS_BIT_LO;
   nai_status_bit_t ShortStat = NAI_STATUS_BIT_LO;
   nai_status_bit_t DeltaAngleStat = NAI_STATUS_BIT_LO;
   nai_status_bit_t LockLossStat = NAI_STATUS_BIT_LO;
   uint32_t rawangle = 0u, rawfreq = 0u, rawsigvolt = 0u, rawrefvolt = 0u, rawminsigvolt = 0u, rawminrefvolt = 0u;
   uint32_t rawmaxsigvolt = 0u, rawmaxrefvolt = 0u, rawOpenThres = 0u, rawShortThres = 0u, rawDeltaAngle = 0u;
   char strChanStatusEnable[CHAN_STATUS_ENABLE_MSG_LENGTH] = "";

   naiif_printf("\r\n\r\n ==========================================================================================");
   naiif_printf("========================================================= \r\n");
   naiif_printf(" Channel  Mode        Angle      Frequency   Signal      Ref          Min       Min           Max");
   naiif_printf("       Max          Open        Short       Delta\r\n");
   naiif_printf("                                             Voltage    Voltage     Signal    Reference     Signal ");
   naiif_printf("   Reference    Threshold   Threshold     Angle\r\n");
   naiif_printf(" --------------------------------------------------------------------------------------------------");
   naiif_printf("-------------------------------------------------\r\n");
   for( channel = 1; channel <= MAX_CHANNEL; channel++)
   {
      naiif_printf("  %2d    ", channel);
      check_status(naibrd_SD_GetChanMode(cardIndex, module, channel, &mode));
      SDBasicMenu_displayMode(mode);
      if (DisplayAsHex)
      {
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_ANGLE, &rawangle));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_FREQUENCY, &rawfreq));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SIGNAL_VOLTAGE, &rawsigvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_REF_VOLTAGE, &rawrefvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SIG_LOSS_THRESHOLD, &rawminsigvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_REF_LOSS_THRESHOLD, &rawminrefvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SIG_FAULT_HI_THRESHOLD, &rawmaxsigvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_REF_FAULT_HI_THRESHOLD, &rawmaxrefvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_OPEN_THRESHOLD, &rawOpenThres));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SHORT_THRESHOLD, &rawShortThres));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_ANGLE_DELTA, &rawDeltaAngle));
         naiif_printf("0x%08X  0x%08X  0x%08X  0x%08X 0x%08X  0x%08X  0x%08X  0x%08X  0x%08X  0x%08X  0x%08X\r\n", rawangle, rawfreq,
                      rawsigvolt, rawrefvolt, rawminsigvolt, rawminrefvolt, rawmaxsigvolt, rawmaxrefvolt, rawOpenThres, rawShortThres,
                      rawDeltaAngle);
      }
      else
      {
         check_status(naibrd_SD_GetAngle(cardIndex, module, channel, &angle));
         check_status(naibrd_SD_GetFrequency(cardIndex, module, channel, &frequency));
         check_status(naibrd_SD_GetSignalVoltage(cardIndex, module, channel, &sigvolt));
         check_status(naibrd_SD_GetRefVoltage(cardIndex, module, channel, &refvolt));
         check_status(naibrd_SD_GetThreshold(cardIndex, module, channel, NAIBRD_SD_SIG_FAULT_LO_THRESHOLD, &minsigvolt));
         check_status(naibrd_SD_GetThreshold(cardIndex, module, channel, NAIBRD_SD_REF_FAULT_LO_THRESHOLD, &minrefvolt));
         check_status(naibrd_SD_GetThreshold(cardIndex, module, channel, NAIBRD_SD_SIG_FAULT_HI_THRESHOLD, &maxsigvolt));
         check_status(naibrd_SD_GetThreshold(cardIndex, module, channel, NAIBRD_SD_REF_FAULT_HI_THRESHOLD, &maxrefvolt));
         check_status(naibrd_SD_GetThreshold(cardIndex, module, channel, NAIBRD_SD_OPEN_THRESHOLD, &openThres));
         check_status(naibrd_SD_GetThreshold(cardIndex, module, channel, NAIBRD_SD_SHORT_THRESHOLD, &shortThres));
         check_status(naibrd_SD_GetAngleDelta(cardIndex, module, channel, &deltaAngle));
         naiif_printf("%9.4f      %6.2f      %6.2f     %6.2f     %6.2f       %6.2f     %6.2f       %6.2f   %10.2f  %10.2f   %9.4f%s",
                      angle, frequency, sigvolt, refvolt, minsigvolt, minrefvolt, maxsigvolt, maxrefvolt, openThres, shortThres,
                      deltaAngle, "\r\n");
      }
   }

   naiif_printf("\r\n\r\n ==========================================================================================");
   naiif_printf("==================================== \r\n");
   naiif_printf(" Channel ChannelStat BIT      Sig Fault   Ref Fault   Sig Fault   Ref Fault   Lock Loss   Open");
   naiif_printf("     Short   Delta Angle  Summary\r\n");
   naiif_printf("         Enable      Status   Lo Status   Lo Status   Hi Status   Hi Status    Status     Status   ");
   naiif_printf("Status    Status     Status\r\n");
   naiif_printf(" --------------------------------------------------------------------------------------------------");
   naiif_printf("----------------------------\r\n");
   for( channel = 1; channel <= MAX_CHANNEL; channel++)
   {
      naiif_printf("  %2d     ", channel);
      check_status(naibrd_SD_GetChanStatusEnable(cardIndex, module, channel, &chanStatusEnable));
      switch (chanStatusEnable)
      {
         case NAI_TRUE:
            naiif_snprintf(strChanStatusEnable, CHAN_STATUS_ENABLE_MSG_LENGTH + 1, "Enabled ");
         break;
         case NAI_FALSE:
            naiif_snprintf(strChanStatusEnable, CHAN_STATUS_ENABLE_MSG_LENGTH + 1, "Disabled");
         break;
         default:
            naiif_snprintf(strChanStatusEnable, CHAN_STATUS_ENABLE_MSG_LENGTH + 1, "Unknown ");
         break;
      }
      naiif_printf("%8s ", strChanStatusEnable);
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED, &BitStatus));
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_SIGNAL_LATCHED, &SigLoss));
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_REF_LATCHED, &RefLoss));
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_2SPDLOCKLOSS_LATCHED,
                                                 &LockLossStat));
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_ANGLEDELTA_LATCHED,
                                                 &DeltaAngleStat));
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_OPEN_LATCHED, &OpenStat));
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_SHORT_LATCHED, &ShortStat));
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_REF_FAULT_HIGH_LATCHED,
                                                 &RefHiStat));
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_SIG_FAULT_HIGH_LATCHED,
                                                 &SigHiStat));
      check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_SUMMARY_LATCHED, &SummaryStatus));
      SDBasicMenu_displayStatus(BitStatus, SigLoss, RefLoss, LockLossStat, DeltaAngleStat, OpenStat, ShortStat, RefHiStat, SigHiStat,
                                SummaryStatus);
   }
}
/*****************************************************************************/
/**
<summary>
SDBasicMenu_displayMode prints mode value.
</summary>
*/
/*****************************************************************************/
static void SDBasicMenu_displayMode(naibrd_sd_format_t mode)
{
   if (mode == NAIBRD_SD_RESOLVER)
   {
      naiif_printf("RSL(%d)     ", mode);
   }
   else if (mode == NAIBRD_SD_SYNCHRO)
   {
      naiif_printf("SYN(%d)     ", mode);
   }
   else
   {
      naiif_printf("UNKNOWN(%d) ", mode);
   }
}
/*****************************************************************************/
/**
<summary>
SDBasicMenu_displayStatus prints to stdin the BIT Status,
Signal Fault Low Status, Reference Fault Low Status,
Signal Fault High Status, Reference Fault High Status,
Two Speed Lock Loss Status, Open Status, Short Status, Delta Angle Status,
and Summary Status.
</summary>
*/
/*****************************************************************************/
static void SDBasicMenu_displayStatus(nai_status_bit_t BitStatus, nai_status_bit_t SigLoss, nai_status_bit_t RefLoss,
                                      nai_status_bit_t LockLossStat, nai_status_bit_t DeltaAngleStat, nai_status_bit_t OpenStat,
                                      nai_status_bit_t ShortStat, nai_status_bit_t RefHiStat, nai_status_bit_t SigHiStat,
                                      nai_status_bit_t SummaryStatus)
{
   if (BitStatus == NAI_STATUS_BIT_HI)
      naiif_printf("   FAILED  ");
   else if (BitStatus == NAI_STATUS_BIT_LO)
      naiif_printf("   Normal  ");
   else
      naiif_printf("   Error   ");

   if (SigLoss == NAI_STATUS_BIT_HI)
      naiif_printf("  FAILED     ");
   else if (SigLoss == NAI_STATUS_BIT_LO)
      naiif_printf("  Normal     ");
   else
      naiif_printf("  Error      ");

   if (RefLoss == NAI_STATUS_BIT_HI)
      naiif_printf(" FAILED   ");
   else if (RefLoss == NAI_STATUS_BIT_LO)
      naiif_printf(" Normal   ");
   else
      naiif_printf("  Error   ");

   if (SigHiStat == NAI_STATUS_BIT_HI)
      naiif_printf("   FAILED   ");
   else if (SigHiStat == NAI_STATUS_BIT_LO)
      naiif_printf("   Normal   ");
   else
      naiif_printf("    Error   ");

   if (RefHiStat == NAI_STATUS_BIT_HI)
      naiif_printf("   FAILED   ");
   else if (RefHiStat == NAI_STATUS_BIT_LO)
      naiif_printf("   Normal   ");
   else
      naiif_printf("    Error   ");

   if (LockLossStat == NAI_STATUS_BIT_HI)
      naiif_printf("   FAILED   ");
   else if (LockLossStat == NAI_STATUS_BIT_LO)
      naiif_printf("   Normal   ");
   else
      naiif_printf("    Error   ");

   if (OpenStat == NAI_STATUS_BIT_HI)
      naiif_printf("  FAILED  ");
   else if (OpenStat == NAI_STATUS_BIT_LO)
      naiif_printf("  Normal  ");
   else
      naiif_printf("   Error  ");

   if (ShortStat == NAI_STATUS_BIT_HI)
      naiif_printf(" FAILED   ");
   else if (ShortStat == NAI_STATUS_BIT_LO)
      naiif_printf(" Normal   ");
   else
      naiif_printf("  Error   ");

   if (DeltaAngleStat == NAI_STATUS_BIT_HI)
      naiif_printf(" FAILED   ");
   else if (DeltaAngleStat == NAI_STATUS_BIT_LO)
      naiif_printf(" Normal   ");
   else
      naiif_printf("  Error   ");

   if (SummaryStatus == NAI_STATUS_BIT_HI)
      naiif_printf("  FAILED\r\n");
   else if (SummaryStatus == NAI_STATUS_BIT_LO)
      naiif_printf("  Normal\r\n");
   else
      naiif_printf("   Error\r\n");
}

static nai_status_t SDBasicMenu_SetMode(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   naibrd_sd_format_t mode;
   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 channel = p_ad_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   naiif_printf("Select SD Mode to set: [0 (RSL) or 1 (SYN)]: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if ((inputBuffer[0] == '0') || (inputBuffer[0] == '1'))
      {
         if (inputBuffer[0] == '0')
            mode = NAIBRD_SD_RESOLVER;
         else
            mode = NAIBRD_SD_SYNCHRO;
         check_status(naibrd_SD_SetChanMode(cardIndex, module, channel, mode));
      }
      else
         naiif_printf("\r\nInvalid SD Mode Entered\r\n");
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetChanStatusEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   uint32_t enable = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   naiif_printf("Select Channel Status Enabled/Disabled Setting to set (0 for Disabled, 1 for Enabled): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      if ((inputBuffer[0] == '0') || (inputBuffer[0] == '1'))
      {
         if (inputBuffer[0] == '1')
         {
            enable = 1u;
         }
         check_status(naibrd_SD_SetChanStatusEnable(cardIndex, module, channel, enable));
      }
      else
      {
         naiif_printf("\r\nInvalid setting entered\r\n");
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_ClearStatus(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   naibrd_sd_chan_mapped_status_type_t statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED;
   char statusTypeStr[STATUS_TYPE_MSG_LENGTH] = "";
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   naiif_printf("Select Latched Status Type to clear: (0 for BIT, 1 for Signal Fault Low, 2 for Ref Fault Low, 3 for Signal Fault High, ");
   naiif_printf("4 for Ref Fault High, 5 for Lock Loss, 6 for Open, 7 for Short, 8 for Delta Angle, 9 for Summary, q for quit): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      switch (inputBuffer[0])
      {
         case '0':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "BIT");
         break;
         case '1':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_SIGNAL_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "Signal Fault Low");
         break;
         case '2':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_REF_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "Ref Fault Low");
         break;
         case '3':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_SIG_FAULT_HIGH_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "Signal Fault High");
         break;
         case '4':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_REF_FAULT_HIGH_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "Ref Fault High");
         break;
         case '5':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_2SPDLOCKLOSS_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "Lock Loss");
         break;
         case '6':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_OPEN_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "Open");
         break;
         case '7':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_SHORT_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "Short");
         break;
         case '8':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_ANGLEDELTA_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "Delta Angle");
         break;
         case '9':
            statusTypeToClear = NAIBRD_SD_CHAN_MAPPED_STATUS_SUMMARY_LATCHED;
            naiif_snprintf(statusTypeStr, STATUS_TYPE_MSG_LENGTH + 1, "Summary");
         break;
         case 'q':
         case 'Q':
            bQuit = NAI_TRUE;
         break;
         default:
            bQuit = NAI_TRUE;
            naiif_printf("\r\nInvalid status type entered\r\n");
         break;
      }

      if (!bQuit)
      {
         naiif_printf("\r\nAre you sure you want to clear the %s status? (Y for Yes or N for No): ", statusTypeStr);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if ((!bQuit) && (inputResponseCnt > 0) && (toupper(inputBuffer[0]) == 'Y'))
         {
            check_status(naibrd_SD_ClearChanMappedStatus(cardIndex, module, channel, statusTypeToClear));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetSigLossThreshold(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t threshold = 0.0;
   uint32_t thresholdRaw = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   if (DisplayAsHex)
   {
      naiif_printf("Type Raw Hex Signal Low Threshold Value to set: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         thresholdRaw = (uint32_t)strtoul((const char*)inputBuffer, NULL, 16);
         if (thresholdRaw == 0u)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SIG_LOSS_THRESHOLD, thresholdRaw));
            }
            else
            {
               naiif_printf("\r\nInvalid value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SIG_LOSS_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      naiif_printf("Enter the minimum signal voltage to allow before raising an alert: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         threshold = atof((const char*)inputBuffer);
         if (threshold == 0.0)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_SIG_FAULT_LO_THRESHOLD, threshold));
            }
            else
            {
               naiif_printf("\r\nInvalid Signal Threshold Entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_SIG_FAULT_LO_THRESHOLD, threshold));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetRefLossThreshold(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t threshold = 0.0;
   uint32_t thresholdRaw = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   if (DisplayAsHex)
   {
      naiif_printf("Type Raw Hex Reference Low Threshold Value to set: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         thresholdRaw = (uint32_t)strtoul((const char*)inputBuffer, NULL, 16);
         if (thresholdRaw == 0u)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_REF_LOSS_THRESHOLD, thresholdRaw));
            }
            else
            {
               naiif_printf("\r\nInvalid value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_REF_LOSS_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      naiif_printf("Enter the minimum reference voltage to allow before raising an alert: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         threshold = atof((const char*)inputBuffer);
         if (threshold == 0.0)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_REF_FAULT_LO_THRESHOLD, threshold));
            }
            else
            {
               naiif_printf("\r\nInvalid Reference Threshold Entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_REF_FAULT_LO_THRESHOLD, threshold));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetSigFaultHiThreshold(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t threshold = 0.0;
   uint32_t thresholdRaw = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   if (DisplayAsHex)
   {
      naiif_printf("Type Raw Hex Signal High Threshold Value to set: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         thresholdRaw = (uint32_t)strtoul((const char*)inputBuffer, NULL, 16);
         if (thresholdRaw == 0u)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SIG_FAULT_HI_THRESHOLD, thresholdRaw));
            }
            else
            {
               naiif_printf("\r\nInvalid value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SIG_FAULT_HI_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      naiif_printf("Enter the maximum signal voltage to allow before raising an alert: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         threshold = atof((const char*)inputBuffer);
         if (threshold == 0.0)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_SIG_FAULT_HI_THRESHOLD, threshold));
            }
            else
            {
               naiif_printf("\r\nInvalid Signal Threshold Entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_SIG_FAULT_HI_THRESHOLD, threshold));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetRefFaultHiThreshold(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t threshold = 0.0;
   uint32_t thresholdRaw = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   if (DisplayAsHex)
   {
      naiif_printf("Type Raw Hex Reference High Threshold Value to set: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         thresholdRaw = (uint32_t)strtoul((const char*)inputBuffer, NULL, 16);
         if (thresholdRaw == 0u)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_REF_FAULT_HI_THRESHOLD, thresholdRaw));
            }
            else
            {
               naiif_printf("\r\nInvalid value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_REF_FAULT_HI_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      naiif_printf("Enter the maximum reference voltage to allow before raising an alert: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         threshold = atof((const char*)inputBuffer);
         if (threshold == 0.0)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_REF_FAULT_HI_THRESHOLD, threshold));
            }
            else
            {
               naiif_printf("\r\nInvalid Reference Threshold Entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_REF_FAULT_HI_THRESHOLD, threshold));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetOpenThreshold(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t threshold = 0.0;
   uint32_t thresholdRaw = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   if (DisplayAsHex)
   {
      naiif_printf("Type Raw Hex Open Threshold Value to set: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         thresholdRaw = (uint32_t)strtoul((const char*)inputBuffer, NULL, 16);
         if (thresholdRaw == 0u)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_OPEN_THRESHOLD, thresholdRaw));
            }
            else
            {
               naiif_printf("\r\nInvalid value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_OPEN_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      naiif_printf("Enter Open Threshold value to set: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         threshold = atof((const char*)inputBuffer);
         if (threshold == 0.0)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_OPEN_THRESHOLD, threshold));
            }
            else
            {
               naiif_printf("\r\nInvalid Open Threshold Entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_OPEN_THRESHOLD, threshold));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetShortThreshold(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t threshold = 0.0;
   uint32_t thresholdRaw = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   if (DisplayAsHex)
   {
      naiif_printf("Type Raw Hex Short Threshold Value to set: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         thresholdRaw = (uint32_t)strtoul((const char*)inputBuffer, NULL, 16);
         if (thresholdRaw == 0u)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SHORT_THRESHOLD, thresholdRaw));
            }
            else
            {
               naiif_printf("\r\nInvalid value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_SHORT_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      naiif_printf("Enter Short Threshold value to set: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         threshold = atof((const char*)inputBuffer);
         if (threshold == 0.0)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_SHORT_THRESHOLD, threshold));
            }
            else
            {
               naiif_printf("\r\nInvalid Short Threshold Entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetThreshold(cardIndex, module, channel, NAIBRD_SD_SHORT_THRESHOLD, threshold));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetDeltaAngle(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t deltaAngle = 0.0;
   uint32_t deltaAngleRaw = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   if (DisplayAsHex)
   {
      naiif_printf("Type Raw Hex Delta Angle Value to set: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         deltaAngleRaw = (uint32_t)strtoul((const char*)inputBuffer, NULL, 16);
         if (deltaAngleRaw == 0u)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_ANGLE_DELTA, deltaAngleRaw));
            }
            else
            {
               naiif_printf("\r\nInvalid value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_ANGLE_DELTA, deltaAngleRaw));
         }
      }
   }
   else
   {
      naiif_printf("Type Delta Angle Value to set: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         deltaAngle = atof((const char*)inputBuffer);
         if (deltaAngle == 0.0)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetAngleDelta(cardIndex, module, channel, deltaAngle));
            }
            else
            {
               naiif_printf("\r\nInvalid Delta Angle value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetAngleDelta(cardIndex, module, channel, deltaAngle));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_InitDeltaAngle(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   naiif_printf("Do you want to enable or disable Delta Angle Status reporting for channel %d? (1 for Enable, 0 for Disable): ", channel);
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      if (inputBuffer[0] == '0')
      {
         status = check_status(naibrd_SD_SetAngleDataInit(cardIndex, module, channel, (bool_t)0x0u));
         if (status == NAI_SUCCESS)
         {
            naiif_printf("\r\nDelta Angle Status reporting has been disabled for channel %d.\r\n", channel);
         }
      }
      else if (inputBuffer[0] == '1')
      {
         status = check_status(naibrd_SD_SetAngleDataInit(cardIndex, module, channel, (bool_t)0x1u));
         if (status == NAI_SUCCESS)
         {
            naiif_printf("\r\nDelta Angle Status reporting has been enabled for channel %d.\r\n", channel);
         }
      }
      else
      {
         naiif_printf("\r\nInvalid selection entered\r\n");
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_FloatingPointMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t floatModeEnabled = NAI_FALSE;
   int32_t channel = 0;
   int32_t maxChannel = 0;
   float64_t angleOffset = 0.0, angleScale = 0.0, velocityOffset = 0.0, velocityScale = 0.0;
   naibrd_sd_floating_point_attributes_t attributeTypeToSet = NAIBRD_SD_ANGLE_SCALE;
   bool_t bQuit = NAI_FALSE;
   bool_t bExit = NAI_FALSE;
   float64_t valueToSet = 0.0;
   char strFloatModeEnabled[FLOAT_MODE_MSG_LENGTH] = "";
   char strAttributeType[ATTRIBUTE_TYPE_MSG_LENGTH] = "";
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   maxChannel = naibrd_SD_GetChannelCount(g_modId);

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   while (bQuit == NAI_FALSE)
   {
      naiif_printf("====================================================\r\n");
      naiif_printf("%4s%12s%11s%13s%12s\r\n", "Chan", "Angle", "Angle", "Velocity", "Velocity");
      naiif_printf("%4s%12s%12s%10s%13s\r\n", "", "Scale", "Offset", "Scale", "Offset");
      naiif_printf("----------------------------------------------------\r\n");
      for (channel = 1; channel <= maxChannel; channel++)
      {
         angleScale = 0.0;
         angleOffset = 0.0;
         velocityScale = 0.0;
         velocityOffset = 0.0;
         check_status(naibrd_SD_GetFloatingPointAttributes(cardIndex, module, channel, NAIBRD_SD_ANGLE_SCALE, &angleScale));
         check_status(naibrd_SD_GetFloatingPointAttributes(cardIndex, module, channel, NAIBRD_SD_ANGLE_OFFSET, &angleOffset));
         check_status(naibrd_SD_GetFloatingPointAttributes(cardIndex, module, channel, NAIBRD_SD_VELOCITY_SCALE, &velocityScale));
         check_status(naibrd_SD_GetFloatingPointAttributes(cardIndex, module, channel, NAIBRD_SD_VELOCITY_OFFSET, &velocityOffset));

         naiif_printf("%2d", channel);
         naiif_printf("%14.4f%12.4f%12.4f%12.4f\r\n", angleScale, angleOffset, velocityScale, velocityOffset);
      }
      check_status(naibrd_GetFloatingPointModeEnable(cardIndex, module, &floatModeEnabled));
      switch (floatModeEnabled)
      {
         case NAI_FALSE:
            naiif_snprintf(strFloatModeEnabled, FLOAT_MODE_MSG_LENGTH + 1, "DISABLED");
         break;
         case NAI_TRUE:
            naiif_snprintf(strFloatModeEnabled, FLOAT_MODE_MSG_LENGTH + 1, "ENABLED ");
         break;
         default:
            naiif_snprintf(strFloatModeEnabled, FLOAT_MODE_MSG_LENGTH + 1, "UNKNOWN ");
         break;
      }
      naiif_printf("Floating-Point Mode: %s\r\n\r\n", strFloatModeEnabled);
      naiif_printf("\r\nDo you want to enable/disable floating-point mode, set floating-point attributes, or refresh the display? ");
      naiif_printf("(0 for mode, 1 for attributes, q for quit, anything else to refresh the display): ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0) && ((inputBuffer[0] == '0') || (inputBuffer[0] == '1')))
      {
         if (inputBuffer[0] == '1')
         {
            naiapp_query_ChannelNumber(maxChannel, 1, &channel);
            naiif_printf("\r\nSet Floating-Point Attributes (0 for Angle Scale, 1 for Angle Offset, 2 for Velocity Scale, ");
            naiif_printf("3 for Velocity Offset, anything else to refresh the display): ");
            bExit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if ((!bExit) && (inputResponseCnt > 0))
            {
               switch (inputBuffer[0])
               {
                  case '0':
                     attributeTypeToSet = NAIBRD_SD_ANGLE_SCALE;
                     naiif_snprintf(strAttributeType, ATTRIBUTE_TYPE_MSG_LENGTH + 1, "Angle Scale");
                  break;
                  case '1':
                     attributeTypeToSet = NAIBRD_SD_ANGLE_OFFSET;
                     naiif_snprintf(strAttributeType, ATTRIBUTE_TYPE_MSG_LENGTH + 1, "Angle Offset");
                  break;
                  case '2':
                     attributeTypeToSet = NAIBRD_SD_VELOCITY_SCALE;
                     naiif_snprintf(strAttributeType, ATTRIBUTE_TYPE_MSG_LENGTH + 1, "Velocity Scale");
                  break;
                  case '3':
                     attributeTypeToSet = NAIBRD_SD_VELOCITY_OFFSET;
                     naiif_snprintf(strAttributeType, ATTRIBUTE_TYPE_MSG_LENGTH + 1, "Velocity Offset");
                  break;
                  default:
                     bExit = NAI_TRUE;
                  break;
               }

               if (!bExit)
               {
                  naiif_printf("\r\nEnter %s value to set: ", strAttributeType);
                  bExit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
                  if ((!bExit) && (inputResponseCnt > 0))
                  {
                     valueToSet = atof((const char*)inputBuffer);
                     if (valueToSet == 0.0)
                     {
                        if (inputBuffer[0] == '0')
                        {
                           check_status(naibrd_SD_SetFloatingPointAttributes(cardIndex, module, channel, attributeTypeToSet, valueToSet));
                        }
                        else
                        {
                           naiif_printf("\r\nInvalid value entered\r\n");
                        }
                     }
                     else
                     {
                        check_status(naibrd_SD_SetFloatingPointAttributes(cardIndex, module, channel, attributeTypeToSet, valueToSet));
                     }
                  }
               }
            }
         }
         else
         {
            naiif_printf("\r\nEnable or Disable floating-point mode? (0 to disable, 1 to enable, anything else to refresh the display): ");
            bExit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if ((!bExit) && (inputResponseCnt > 0))
            {
               switch (inputBuffer[0])
               {
                  case '0':
                     check_status(naibrd_SetFloatingPointModeEnable(cardIndex, module, NAI_FALSE));
                  break;
                  case '1':
                     check_status(naibrd_SetFloatingPointModeEnable(cardIndex, module, NAI_TRUE));
                  break;
               }
            }
         }
      }
   }

   return NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_TestMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   int32_t cmd = 0;
   float64_t testAngle = 0.0;
   uint32_t testAngleRaw = 0u;
   bool_t d0TestEnabled = NAI_FALSE;
   bool_t pBitComplete = 0u;
   nai_status_bit_t bitStatus = NAI_STATUS_BIT_LO;
   float64_t bitErrorLimit = 0.0;
   uint32_t bitErrorLimitRaw = 0u;
   int32_t channelCount = 0;
   char strBITStatus[BIT_STATUS_MSG_LENGTH] = "";
   char strD0TestEnabled[D0_TEST_ENABLE_MSG_LENGTH] = "";
   char strPBITComplete[PBIT_COMPLETE_MSG_LENGTH] = "";
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel = p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   channelCount = naibrd_SD_GetChannelCount(g_modId);
   naiapp_utils_LoadParamMenuCommands(SD_TESTMENU_CMD_COUNT, SD_TestMenuCmds);
   do
   {
      naiif_printf("\r\n\r\n ============================= \r\n");
      naiif_printf(" channel    BIT        BIT Error\r\n");
      naiif_printf("         Status        Limit\r\n");
      naiif_printf(" -----------------------------\r\n");
      for (channel = 1; channel <= channelCount; channel++)
      {
         check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED, &bitStatus));
         switch (bitStatus)
         {
            case NAI_STATUS_BIT_LO:
               naiif_snprintf(strBITStatus, BIT_STATUS_MSG_LENGTH + 1, "Normal");
            break;
            case NAI_STATUS_BIT_HI:
               naiif_snprintf(strBITStatus, BIT_STATUS_MSG_LENGTH + 1, "FAILED");
            break;
            default:
               naiif_snprintf(strBITStatus, BIT_STATUS_MSG_LENGTH + 1, "Error ");
            break;
         }
         if (DisplayAsHex)
         {
            check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_BIT_ERROR_LIMIT, &bitErrorLimitRaw));
            naiif_printf("  %2d     %s     0x%08X\r\n", channel, strBITStatus, bitErrorLimitRaw);
         }
         else
         {
            check_status(naibrd_SD_GetBITErrorLimit(cardIndex, module, channel, &bitErrorLimit));
            naiif_printf("  %2d     %s   %12.4f\r\n", channel, strBITStatus, bitErrorLimit);
         }
      }
      if (DisplayAsHex)
      {
         check_status(naibrd_SD_GetRaw(cardIndex, module, NAIBRD_SD_RAW_TEST_ANGLE, &testAngleRaw));
      }
      else
      {
         check_status(naibrd_SD_GetTestAngle(cardIndex, module, &testAngle));
      }
      check_status(naibrd_SD_GetModuleBITEnable(cardIndex, module, NAIBRD_SD_TEST_ENABLE_D0, &d0TestEnabled));
      switch (d0TestEnabled)
      {
         case NAI_TRUE:
            naiif_snprintf(strD0TestEnabled, D0_TEST_ENABLE_MSG_LENGTH + 1, "ENABLED ");
         break;
         case NAI_FALSE:
            naiif_snprintf(strD0TestEnabled, D0_TEST_ENABLE_MSG_LENGTH + 1, "DISABLED");
         break;
         default:
            naiif_snprintf(strD0TestEnabled, D0_TEST_ENABLE_MSG_LENGTH + 1, "UNKNOWN ");
         break;
      }
      check_status(naibrd_SD_CheckPowerOnBITComplete(cardIndex, module, &pBitComplete));
      switch (pBitComplete)
      {
         case NAI_TRUE:
            naiif_snprintf(strPBITComplete, PBIT_COMPLETE_MSG_LENGTH + 1, "COMPLETED");
         break;
         case NAI_FALSE:
            naiif_snprintf(strPBITComplete, PBIT_COMPLETE_MSG_LENGTH + 1, "NOT COMPLETED");
         break;
         default:
            naiif_snprintf(strPBITComplete, PBIT_COMPLETE_MSG_LENGTH + 1, "UNKNOWN");
         break;
      }
      if (DisplayAsHex)
      {
         naiif_printf("\r\nTest Angle Raw Hex Value: 0x%08X\r\n", testAngleRaw);
      }
      else
      {
         naiif_printf("\r\nTest Angle: %-16.8f\r\n", testAngle);
      }
      naiif_printf("D0 Test Enabled/Disabled: %s\r\n", strD0TestEnabled);
      naiif_printf("Power-On BIT Complete: %s\r\n", strPBITComplete);
      naiapp_display_ParamMenuCommands((int8_t*)"SD Test Menu");
      naiif_printf("\r\n Type command or %c to quit : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
         if ((cmd >= 0) && (cmd < SD_TESTMENU_CMD_COUNT))
         {
            if (cmd == SD_TESTMENU_CMD_DISPLAY_CONVERTED)
            {
               DisplayAsHex = NAI_FALSE;
            }
            else if (cmd == SD_TESTMENU_CMD_DISPLAY_HEX)
            {
               DisplayAsHex = NAI_TRUE;
            }
            else if ((cmd == SD_TESTMENU_CMD_CLEAR_BIT_STATUS) || (cmd == SD_TESTMENU_CMD_SET_BIT_ERROR_LIMIT))
            {
               naiapp_query_ChannelNumber(channelCount, 1, &p_sd_params->channel);
               SD_TestMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)p_params);
            }
            else
            {
               SD_TestMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)p_params);
            }
         }
         else
         {
            naiif_printf(" Invalid command entered\r\n");
         }
      }
   } while (!bQuit);

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_ReadReg(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   uint32_t Addr = 0;
   uint32_t data = 0;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   uint32_t dataCount;
   uint32_t idx = 0;
   uint32_t rowAddr = 0;
   uint32_t addrOffset = 0;
   int8_t buffer[READ_REG_BUFFER_MSG_LENGTH];

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
   naiif_printf("\r\nEnter the Address(relative to the MB) to read from: 0x");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
        Addr = strtoul(((const char *)inputBuffer), NULL, 16);
        check_status(naibrd_ReadReg32(cardIndex, 0, Addr, &data));
        naiif_printf("Read Register: 0x%x\r\n", Addr);
        naiif_printf("Read value: 0x%x\r\n", data);
      }
   }
   do
   {
      naiif_printf("\r\nEnter the Address(relative to the MB) to read from: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         addrOffset = strtoul ((const char *)inputBuffer, NULL, 16);
         naiif_printf("Enter Number of data to retrieve: ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            memset(buffer, 0, sizeof(buffer));
            naiif_snprintf((char *)buffer, READ_REG_BUFFER_MSG_LENGTH + 1,
                           "\r\n            0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x"
                                            "0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x\r\n",
                           0x0, 0x4, 0x8, 0xc, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c);
            naiif_printf("%s", buffer);
            dataCount = strtoul ((const char *)inputBuffer, NULL, 10);
            for (idx = 0; idx < dataCount; idx++)
            {
               naibrd_ReadReg32(cardIndex, 0, addrOffset+(idx*4), &data);
               if( (idx % 16) == 0)
               {
                  rowAddr = 4*idx + addrOffset;
                  naiif_printf("            \r\n0x%-10x0x%-10x", rowAddr,data);
               }
               else
                  naiif_printf("0x%-10x", data);
            }
         }
      }
      naiif_printf("\r\nType %c to exit: ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   }while(!bQuit);
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static nai_status_t SDBasicMenu_WriteReg(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   uint32_t Addr = 0;
   uint32_t data = 0;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
   naiif_printf("\r\nEnter the Address(relative to the MB) to write to: 0x");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         Addr = strtoul(((const char *)inputBuffer), NULL, 16);
         naiif_printf("\r\nEnter the value to write: 0x");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               data = strtoul(((const char *)inputBuffer), NULL, 16);
               check_status(naibrd_WriteReg32(cardIndex, 0, Addr, data));
               naiif_printf("Write Register: 0x%x\r\n", Addr);
               naiif_printf("Write value: 0x%x\r\n", data);
            }
         }
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDTestMenu_ClearBITStatus(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel = p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   naiif_printf("Are you sure you want to clear the Latched BIT status? (Y for Yes or N for No): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0) && (toupper(inputBuffer[0]) == 'Y'))
   {
      check_status(naibrd_SD_ClearChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED));
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDTestMenu_SetBITErrorLimit(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t bitErrorLimit = 0.0;
   uint32_t bitErrorLimitRaw = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel = p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   if (DisplayAsHex)
   {
      naiif_printf("Type BIT Error Limit Raw Hex value to set: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         bitErrorLimitRaw = (uint32_t)strtoul((const char*)inputBuffer, NULL, 16);
         if (bitErrorLimitRaw == 0u)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_BIT_ERROR_LIMIT, bitErrorLimitRaw));
            }
            else
            {
               naiif_printf("\r\nInvalid value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAIBRD_SD_CHAN_RAW_BIT_ERROR_LIMIT, bitErrorLimitRaw));
         }
      }
   }
   else
   {
      naiif_printf("Type BIT Error Limit value to set: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         bitErrorLimit = atof((const char*)inputBuffer);
         if (bitErrorLimit == 0.0)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetBITErrorLimit(cardIndex, module, channel, bitErrorLimit));
            }
            else
            {
               naiif_printf("\r\nInvalid BIT Error Limit entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetBITErrorLimit(cardIndex, module, channel, bitErrorLimit));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDTestMenu_SetTestAngle(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t testAngle = 0.0;
   uint32_t testAngleRaw = 0u;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   if (DisplayAsHex)
   {
      naiif_printf("Type Test Angle Raw Hex value to set: 0x");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         testAngleRaw = (uint32_t)strtoul((const char*)inputBuffer, NULL, 16);
         if (testAngleRaw == 0u)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetRaw(cardIndex, module, NAIBRD_SD_RAW_TEST_ANGLE, testAngleRaw));
            }
            else
            {
               naiif_printf("\r\nInvalid value entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetRaw(cardIndex, module, NAIBRD_SD_RAW_TEST_ANGLE, testAngleRaw));
         }
      }
   }
   else
   {
      naiif_printf("Type Test Angle value to set: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         testAngle = atof((const char*)inputBuffer);
         if (testAngle == 0.0)
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_SD_SetTestAngle(cardIndex, module, testAngle));
            }
            else
            {
               naiif_printf("\r\nInvalid Test Angle entered\r\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetTestAngle(cardIndex, module, testAngle));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDTestMenu_SetD0TestEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   naiif_printf("Enable or Disable D0 Test (0 for disable, 1 for enable): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      switch (inputBuffer[0])
      {
         case '0':
            check_status(naibrd_SD_SetModuleBITEnable(cardIndex, module, NAIBRD_SD_TEST_ENABLE_D0, (bool_t)NAI_FALSE));
         break;
         case '1':
            check_status(naibrd_SD_SetModuleBITEnable(cardIndex, module, NAIBRD_SD_TEST_ENABLE_D0, (bool_t)NAI_TRUE));
         break;
         default:
            naiif_printf("\r\nInvalid selection entered\r\n");
         break;
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDTestMenu_CheckPowerOnBIT(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   int32_t channelCount = 0;
   bool_t pBitComplete = NAI_FALSE;
   nai_status_bit_t bitStatus = NAI_STATUS_BIT_LO;
   char strBitStatus[PBIT_BIT_STATUS_MSG_LENGTH] = "";
   p_naiapp_AppParameters_t p_sd_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_sd_params->cardIndex;
   int32_t module = p_sd_params->module;
   int32_t channel = p_sd_params->channel;
   channel = 0;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   channelCount = naibrd_SD_GetChannelCount(g_modId);

   /* Check to see if PBIT ran for the module. */
   naiif_printf("Checking if the Power-On BIT test has run...\r\n");
   check_status(naibrd_SD_CheckPowerOnBITComplete(cardIndex, module, &pBitComplete));
   switch (pBitComplete)
   {
      case 0u:
         naiif_printf("\r\nPBIT Complete: NOT COMPLETED\r\n");
      break;
      case 1u:
         naiif_printf("\r\nPBIT Complete: COMPLETED\r\n");
      break;
      default:
         naiif_printf("\r\nPBIT Complete: UNKNOWN\r\n");
      break;
   }

   if (pBitComplete)
   {
      /* Read the BIT status */
      naiif_printf("Checking the result of the Power-on BIT test...\r\n");
      for (channel = 1; channel <= channelCount; channel++)
      {
         check_status(naibrd_SD_GetChanMappedStatus(cardIndex, module, channel, NAIBRD_SD_CHAN_MAPPED_STATUS_BIT_LATCHED, &bitStatus));
         switch (bitStatus)
         {
            case 0:
               naiif_snprintf(strBitStatus, PBIT_BIT_STATUS_MSG_LENGTH + 1, "BIT Passed");
            break;
            case 1:
               naiif_snprintf(strBitStatus, PBIT_BIT_STATUS_MSG_LENGTH + 1, "BIT FAILED");
            break;
            default:
               naiif_snprintf(strBitStatus, PBIT_BIT_STATUS_MSG_LENGTH + 1, "Unknown");
            break;
         }
         naiif_printf("Ch. %d: %s\r\n", channel, strBitStatus);
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

Help Bot

X