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 BasicOpsMenu

SD BasicOps Sample Application (SSK 1.x)

Overview

The SD BasicOps sample application demonstrates how to configure and read synchro/resolver-to-digital (SD) converter channels using the NAI Software Support Kit (SSK 1.x). It covers the core SD operations you will need in your own application: reading angular position, configuring signal format (synchro vs resolver), setting fault thresholds for signal and reference voltages, monitoring channel status (BIT, signal loss, reference loss, lock loss), managing delta angle tracking, configuring floating-point scaling, and running built-in test (BIT) diagnostics.

What Are Synchro and Resolver Sensors?

Synchros and resolvers are rotary electromechanical sensors that encode angular position as analog AC voltage signals. They are widely used in aerospace, defense, and industrial systems because of their ruggedness, reliability, and ability to operate in harsh environments (extreme temperature, vibration, radiation) where optical encoders would fail.

Resolvers are the simpler of the two. A resolver has a rotor winding excited by an AC reference signal and two stator windings mounted 90 degrees apart. As the rotor turns, the stator windings produce two output voltages whose amplitudes vary as the sine and cosine of the shaft angle. The SD module digitizes these sine and cosine amplitudes and computes the shaft angle using an arctangent conversion.

Synchros work on the same principle but use three stator windings spaced 120 degrees apart, producing three output signals (S1, S2, S3) referenced to each other. A synchro-to-digital converter internally transforms the three-wire synchro signals into equivalent sine and cosine components before computing the angle. The SD module handles this transformation transparently — you select synchro or resolver mode, and the module takes care of the signal processing.

Key difference for your code: From a software perspective, the only difference between synchro and resolver operation is the mode setting. You call naibrd_SD_SetChanMode() to select NAI_SD_SYNCHRO or NAI_SD_RESOLVER, and the hardware adapts its input conditioning and conversion algorithm accordingly. All other API calls (reading angle, setting thresholds, checking status) work identically regardless of mode.

This sample supports the following SD module types: SD1 through SD5 and SDP. Check naibrd_sd.h for the complete list of SD module ID definitions. It serves as a practical API reference — each menu command maps directly to one or more naibrd_SD_*() API calls that you can lift into your own code.

Prerequisites

Before running this sample, make sure you have:

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

  • SSK 1.x installed on your development host.

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

How to Run

Launch the SD_BasicOpsMenu executable from your build output directory. On startup the application looks for a configuration file (default_SD_BasicOps.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 command menu lets you exercise each SD operation.

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. For details on board connection configuration, see the First Time Setup Guide.

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

  1. Call naiapp_RunBoardMenu() to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_SD_BasicOps.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear.

  2. Query the user for a card index with naiapp_query_CardIndex().

  3. Query for a module slot with naiapp_query_ModuleNumber().

  4. Retrieve the module ID with naibrd_GetModuleID() 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 = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               g_modId = moduleID;
               if ((moduleID != 0))
               {
                  SDBasicMenu_Run(cardIndex, module, moduleID);
               }
            }
         }

         printf("\nType Q to quit or Enter key to restart application:\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer),
                  NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   naiapp_access_CloseAllOpenCards();
   return 0;
}
Important

Common connection errors you may encounter at this stage:

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

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

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

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

Program Structure

Application Parameters

Once the board connection is established and the module is selected, the sample allocates an naiapp_AppParameters_t struct that carries the session state through every menu command. In your own code, you will track these same values:

  • cardIndex — identifies which board you are communicating with.

  • module — the slot number (1-based) where the SD module is installed.

  • maxChannels — the number of SD channels on this module, obtained from naibrd_SD_GetChannelCount().

  • modId — the module ID returned by naibrd_GetModuleID(), used to determine module-specific behavior.

  • channel — the currently selected channel for per-channel operations.

  • displayHex — toggles between human-readable (converted) and raw hex display formats.

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 = FALSE;

Command Table and Menu Loop

The sample uses a command table (SD_BasicOpMenuCmds[]) that maps user-friendly command names to handler functions. Each handler wraps one or more naibrd_SD_*() API calls. The menu system is a sample convenience — in your own code, call these API functions directly.

The main menu loop works as follows:

  1. Display current measurements and status for all channels by calling SDBasicMenu_displayMeasurements().

  2. Show the command menu.

  3. Accept a command from the user.

  4. For channel-specific commands (mode, thresholds, status), prompt for a channel number first.

  5. Dispatch to the corresponding handler function.

The command table includes two display-mode toggles (Converted and Hex Display) that switch between engineering-unit values and raw hex register values. This is useful for debugging — you can compare the converted values against the raw register contents documented in your module’s manual.

Angular Position and Signal Configuration

This section covers the core measurement and configuration operations of an SD channel: reading the converted angle, setting the signal format, and monitoring the reference and signal voltages.

How Synchro/Resolver-to-Digital Conversion Works

The SD module continuously tracks the angular position of the connected synchro or resolver. The conversion process works as follows:

  1. Excitation — The module provides (or accepts an external) AC reference signal at a known frequency and voltage. This reference excites the sensor’s rotor winding.

  2. Signal acquisition — The sensor’s stator windings produce amplitude-modulated AC signals whose envelopes are proportional to the sine and cosine of the shaft angle (for a resolver) or to a three-wire equivalent (for a synchro).

  3. Demodulation — The SD module demodulates the stator signals against the reference to extract the sine and cosine amplitude components.

  4. Angle computation — A tracking converter (type II servo loop) computes the shaft angle from the sine/cosine ratio using a successive-approximation or phase-tracking algorithm. This produces a continuously updated digital angle.

  5. Velocity derivation — The tracking loop inherently produces an angular velocity estimate as a byproduct of the angle tracking algorithm.

All of this is handled in hardware/firmware on the SD module. Your application simply reads the resulting angle, frequency, and voltage values through the API.

Reading Angular Position

To read the current shaft angle from an SD channel, call naibrd_SD_GetAngle(). The returned value is in degrees (0.0 to 359.9999…​). The module continuously tracks the angle, so each call returns the latest measurement.

float64_t angle = 0.0;
check_status(naibrd_SD_GetAngle(cardIndex, module, channel, &angle));

To read the reference frequency detected by the module, call naibrd_SD_GetFrequency(). This returns the measured excitation frequency in Hz. Use this to verify that the reference signal is present and at the expected frequency.

float64_t frequency = 0.0;
check_status(naibrd_SD_GetFrequency(cardIndex, module, channel, &frequency));

To read the signal and reference voltage levels, call naibrd_SD_GetSignalVoltage() and naibrd_SD_GetRefVoltage(). These return the RMS voltage in volts. Monitoring these values helps verify that the sensor is connected and operating within its specified range.

float64_t sigvolt = 0.0, refvolt = 0.0;
check_status(naibrd_SD_GetSignalVoltage(cardIndex, module, channel, &sigvolt));
check_status(naibrd_SD_GetRefVoltage(cardIndex, module, channel, &refvolt));

For raw register access (useful for debugging or when you need to bypass the floating-point conversion), use naibrd_SD_GetChannelRaw() with the appropriate raw-channel type enum:

uint32_t rawangle = 0u;
check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel,
             NAI_SD_CHAN_RAW_ANGLE, &rawangle));

Setting Signal Format (Synchro vs Resolver)

To configure whether a channel expects a synchro or resolver input, call naibrd_SD_SetChanMode(). You must set the correct mode to match your physical sensor — using the wrong mode will produce incorrect angle readings because the demodulation algorithm differs between the two signal formats.

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

/* Set to synchro mode */
check_status(naibrd_SD_SetChanMode(cardIndex, module, channel, NAI_SD_SYNCHRO));

To read back the current mode setting:

nai_sd_format_t mode = 0u;
check_status(naibrd_SD_GetChanMode(cardIndex, module, channel, &mode));
/* mode == NAI_SD_RESOLVER (0) or NAI_SD_SYNCHRO (1) */

When to use each mode:

  • Resolver mode (NAI_SD_RESOLVER) — Use when your sensor has a two-wire sine/cosine output. Resolvers are more common in modern designs because of their simpler wiring and better high-speed performance.

  • Synchro mode (NAI_SD_SYNCHRO) — Use when your sensor has a three-wire (S1/S2/S3) output. Synchros are common in legacy aerospace systems and are electrically compatible with other synchro devices on the same bus.

Channel Status Enable

To enable or disable status reporting for a specific channel, call naibrd_SD_SetChanStatusEnable(). When status reporting is disabled, the module still performs conversions but does not update the fault status bits for that channel. This can be useful during system initialization when transient conditions might trigger false fault indications.

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

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

Common Errors

  • Wrong angle readings — Verify that the channel mode (synchro vs resolver) matches the physical sensor type. A resolver connected to a channel configured for synchro mode will produce erratic or incorrect angles.

  • NAI_ERROR_NOT_SUPPORTED — The selected channel number may exceed the module’s channel count. Call naibrd_SD_GetChannelCount() to verify the valid range.

  • Angle reads as 0.0 with no change — The reference or signal may not be connected. Check naibrd_SD_GetRefVoltage() and naibrd_SD_GetSignalVoltage() to confirm that both are within the expected range for your module. Consult your module’s manual for supported voltage and frequency ranges.

Fault Thresholds and Delta Angle Monitoring

The SD module provides configurable fault thresholds that let you detect abnormal signal conditions. When a measured voltage crosses a threshold boundary, the corresponding status bit is set, alerting your application to a potential wiring fault, sensor failure, or environmental issue.

Signal and Reference Fault Low Thresholds

The signal fault low (signal loss) and reference fault low (reference loss) thresholds define the minimum acceptable voltage levels. If the measured signal or reference voltage drops below these thresholds, the module sets the corresponding fault status bit.

To set the signal loss threshold, call naibrd_SD_SetSigLossThreshold(). To set the reference loss threshold, call naibrd_SD_SetRefLossThreshold().

/* Set the minimum acceptable signal voltage */
check_status(naibrd_SD_SetSigLossThreshold(cardIndex, module, channel, threshold));

/* Set the minimum acceptable reference voltage */
check_status(naibrd_SD_SetRefLossThreshold(cardIndex, module, channel, threshold));

To read back the current thresholds:

float64_t minsigvolt = 0.0, minrefvolt = 0.0;
check_status(naibrd_SD_GetSigLossThreshold(cardIndex, module, channel, &minsigvolt));
check_status(naibrd_SD_GetRefLossThreshold(cardIndex, module, channel, &minrefvolt));

What these mean in practice: If a cable to your synchro/resolver is disconnected or broken, the signal voltage will drop to near zero. Setting an appropriate signal loss threshold (typically a few percent of the expected operating voltage) lets your application detect this condition immediately rather than relying on angle readings that may wander unpredictably.

Signal and Reference Fault High Thresholds

The fault high thresholds define the maximum acceptable voltage levels. If the measured signal or reference voltage exceeds these thresholds, the module sets the corresponding fault high status bit. This can indicate an overvoltage condition or a wiring error (such as connecting a high-voltage source to a low-voltage input module).

/* Set the maximum acceptable signal voltage */
check_status(naibrd_SD_SetThreshold(cardIndex, module, channel,
             NAIBRD_SD_SIG_FAULT_HI_THRESHOLD, threshold));

/* Set the maximum acceptable reference voltage */
check_status(naibrd_SD_SetThreshold(cardIndex, module, channel,
             NAIBRD_SD_REF_FAULT_HI_THRESHOLD, threshold));

To read back the current high thresholds:

float64_t maxsigvolt = 0.0, maxrefvolt = 0.0;
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));

Open and Short Thresholds

The open and short thresholds detect wiring faults in the sensor connections. An open condition indicates a broken or disconnected wire; a short condition indicates a short circuit between sensor leads.

/* Set open circuit detection threshold */
check_status(naibrd_SD_SetThreshold(cardIndex, module, channel,
             NAIBRD_SD_OPEN_THRESHOLD, threshold));

/* Set short circuit detection threshold */
check_status(naibrd_SD_SetThreshold(cardIndex, module, channel,
             NAIBRD_SD_SHORT_THRESHOLD, threshold));

Consult your module’s manual for recommended threshold values based on your sensor’s electrical characteristics and wiring configuration.

Delta Angle Monitoring

Delta angle monitoring lets you detect when the shaft angle has changed by more than a specified amount since the last initialization. This is useful for applications that need to trigger an action or alert when a shaft moves beyond a defined limit (for example, detecting unexpected rotation in a stabilized platform).

To set the delta angle threshold:

/* Set the angular change threshold (in degrees) */
check_status(naibrd_SD_SetAngleDelta(cardIndex, module, channel, deltaAngle));

To enable or disable delta angle status reporting, call naibrd_SD_SetAngleDataInit(). Enabling this initializes the reference angle from which delta changes are measured:

/* Enable delta angle monitoring -- captures the current angle as the reference */
check_status(naibrd_SD_SetAngleDataInit(cardIndex, module, channel, (bool_t)0x1u));

/* Disable delta angle monitoring */
check_status(naibrd_SD_SetAngleDataInit(cardIndex, module, channel, (bool_t)0x0u));

When the measured angle deviates from the reference angle by more than the configured delta threshold, the NAI_SD_STATUS_ANGLEDELTA_LATCHED status bit is set.

Important

Common Errors

  • Threshold set but no fault detected — Make sure channel status reporting is enabled via naibrd_SD_SetChanStatusEnable(). If status reporting is disabled, faults are not flagged even when threshold conditions are met.

  • Unexpected open/short faults at startup — During power-up or system initialization, transient conditions can trigger fault status bits. Clear the latched status bits after the system stabilizes and before relying on fault indications.

  • Delta angle status triggers immediately — This occurs if the delta threshold is set too small relative to the sensor’s noise or jitter. Consult your module’s manual for the effective angular resolution and set the delta threshold accordingly.

Floating-Point Scaling

The SD module supports floating-point mode, which applies user-configurable scale and offset values to the angle and velocity outputs. This is useful when your application needs angle readings in a custom unit system or when you need to compensate for a mechanical offset between the sensor’s zero position and your application’s zero reference.

Enabling Floating-Point Mode

Floating-point mode is a module-level setting that applies to all channels:

/* Enable floating-point mode */
check_status(naibrd_SetFloatingPointModeEnable(cardIndex, module, TRUE));

/* Disable floating-point mode */
check_status(naibrd_SetFloatingPointModeEnable(cardIndex, module, FALSE));

To check the current mode:

bool_t floatModeEnabled = FALSE;
check_status(naibrd_GetFloatingPointModeEnable(cardIndex, module, &floatModeEnabled));

Setting Scale and Offset Attributes

When floating-point mode is enabled, the module applies this formula to each output: output = (raw_value * scale) + offset. You can set independent scale and offset values for both angle and velocity on each channel:

/* Set angle scale and offset */
check_status(naibrd_SD_SetFloatingPointAngleScale(cardIndex, module, channel, scaleValue));
check_status(naibrd_SD_SetFloatingPointAngleOffset(cardIndex, module, channel, offsetValue));

/* Set velocity scale and offset */
check_status(naibrd_SD_SetFloatingPointVelocityScale(cardIndex, module, channel, scaleValue));
check_status(naibrd_SD_SetFloatingPointVelocityOffset(cardIndex, module, channel, offsetValue));

To read back the current attributes:

float64_t angleScale = 0.0, angleOffset = 0.0;
float64_t velocityScale = 0.0, velocityOffset = 0.0;
check_status(naibrd_SD_GetFloatingPointAngleScale(cardIndex, module, channel, &angleScale));
check_status(naibrd_SD_GetFloatingPointAngleOffset(cardIndex, module, channel, &angleOffset));
check_status(naibrd_SD_GetFloatingPointVelocityScale(cardIndex, module, channel, &velocityScale));
check_status(naibrd_SD_GetFloatingPointVelocityOffset(cardIndex, module, channel, &velocityOffset));

Practical examples:

  • To apply a mechanical offset correction of 15.5 degrees, set the angle offset to -15.5 (so the reported angle is shifted by that amount).

  • To convert degrees to radians, set the angle scale to approximately 0.01745329 (pi/180).

  • To invert the rotation direction, set the angle scale to -1.0.

Important

Common Errors

  • Angle readings suddenly change after enabling floating-point mode — This is expected behavior. When floating-point mode is enabled, the scale and offset values are applied to all subsequent readings. If scale is 0.0, all readings will return the offset value. Make sure scale is set to 1.0 (or your desired value) before enabling the mode.

  • NAI_ERROR_NOT_SUPPORTED — Not all SD module firmware revisions support floating-point mode. Consult your module’s manual for FPGA revision requirements.

Status and Diagnostics

The SD module maintains a comprehensive set of status bits for each channel. These status bits are latched — once a fault condition is detected, the corresponding bit remains set until your application explicitly clears it. This ensures that intermittent faults are not missed.

Reading Status

The sample’s SDBasicMenu_displayMeasurements() function reads all status bits for every channel in a single display pass. To read a specific status bit in your own code, call naibrd_SD_GetStatus() with the appropriate status type:

uint32_t bitStatus = NAI_STATUS_BIT_LO;
uint32_t sigLoss = NAI_STATUS_BIT_LO;
uint32_t refLoss = NAI_STATUS_BIT_LO;
uint32_t lockLoss = NAI_STATUS_BIT_LO;

check_status(naibrd_SD_GetStatus(cardIndex, module, channel,
             NAI_SD_STATUS_BIT_LATCHED, &bitStatus));
check_status(naibrd_SD_GetStatus(cardIndex, module, channel,
             NAI_SD_STATUS_SIGNAL_LATCHED, &sigLoss));
check_status(naibrd_SD_GetStatus(cardIndex, module, channel,
             NAI_SD_STATUS_REF_LATCHED, &refLoss));
check_status(naibrd_SD_GetStatus(cardIndex, module, channel,
             NAI_SD_STATUS_2SPDLOCKLOSS_LATCHED, &lockLoss));

The full set of status types available:

Status Type What It Indicates

NAI_SD_STATUS_BIT_LATCHED

Built-in test failure. The module’s internal self-test detected an error on this channel.

NAI_SD_STATUS_SIGNAL_LATCHED

Signal fault low. The input signal voltage dropped below the signal loss threshold, indicating a possible disconnected or broken sensor wire.

NAI_SD_STATUS_REF_LATCHED

Reference fault low. The reference excitation voltage dropped below the reference loss threshold, indicating a missing or weak reference signal.

NAI_SD_STATUS_SIG_FAULT_HIGH_LATCHED

Signal fault high. The input signal voltage exceeded the signal high threshold, indicating possible overvoltage.

NAI_SD_STATUS_REF_FAULT_HIGH_LATCHED

Reference fault high. The reference voltage exceeded the reference high threshold.

NAI_SD_STATUS_2SPDLOCKLOSS_LATCHED

Two-speed lock loss. For two-speed synchro/resolver systems, this indicates the coarse and fine channels have lost synchronization.

NAI_SD_STATUS_OPEN_LATCHED

Open circuit detected on the sensor wiring.

NAI_SD_STATUS_SHORT_LATCHED

Short circuit detected on the sensor wiring.

NAI_SD_STATUS_ANGLEDELTA_LATCHED

The measured angle has changed by more than the configured delta angle threshold since initialization.

NAI_SD_STATUS_SUMMARY_LATCHED

Summary status. Set if any of the above fault conditions are active on this channel.

Clearing Latched Status

Once you have acknowledged a fault condition, clear the latched status bit so that you can detect the next occurrence. Call naibrd_SD_ClearStatus() with the specific status type:

/* Clear the BIT latched status for a channel */
check_status(naibrd_SD_ClearStatus(cardIndex, module, channel,
             NAI_SD_STATUS_BIT_LATCHED));

/* Clear the signal loss latched status */
check_status(naibrd_SD_ClearStatus(cardIndex, module, channel,
             NAI_SD_STATUS_SIGNAL_LATCHED));

/* Clear the summary status */
check_status(naibrd_SD_ClearStatus(cardIndex, module, channel,
             NAI_SD_STATUS_SUMMARY_LATCHED));

Best practice: Clear all latched status bits after your system completes initialization and the sensor signals have stabilized. Then monitor the status bits during normal operation to detect genuine faults.

Important

Common Errors

  • Status bit re-latches immediately after clearing — The underlying fault condition is still present. Resolve the hardware issue (reconnect a cable, fix a short) before clearing the status.

  • Summary status is set but individual status bits are all clear — The individual fault condition may have been transient and was cleared, but the summary bit was not cleared separately. Clear the summary status explicitly with NAI_SD_STATUS_SUMMARY_LATCHED.

  • Status bits never set despite known fault conditions — Verify that channel status reporting is enabled via naibrd_SD_SetChanStatusEnable().

BIT Test and Diagnostics

The SD module includes a built-in test (BIT) subsystem that verifies the conversion hardware is functioning correctly. The BIT system injects a known test angle into the conversion pipeline and compares the result against the expected value. If the difference exceeds the configured error limit, the BIT status is flagged as failed.

Test Menu Overview

The sample provides a dedicated test submenu (SDBasicMenu_TestMenu()) that displays BIT status, test angle, D0 test enable state, and power-on BIT completion status for all channels.

Setting the Test Angle

The test angle is a module-level parameter (shared across all channels) that defines the known angle injected during BIT. To set it in your own application:

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

/* Read back the current test angle */
float64_t testAngle = 0.0;
check_status(naibrd_SD_GetTestAngle(cardIndex, module, &testAngle));

Setting the BIT Error Limit

The BIT error limit defines the maximum acceptable difference (in degrees) between the test angle and the measured result during BIT. If the measured error exceeds this limit, the BIT status for that channel is set to FAILED.

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

/* Read back the current error limit */
float64_t bitErrorLimit = 0.0;
check_status(naibrd_SD_GetBITErrorLimit(cardIndex, module, channel, &bitErrorLimit));

Enabling/Disabling D0 Test

The D0 test enable controls whether the module’s continuous background BIT is active. When enabled, the module periodically runs the self-test and updates the BIT status:

/* Enable D0 continuous BIT */
check_status(naibrd_SD_SetModuleBITEnable(cardIndex, module,
             NAI_SD_TEST_ENABLE_D0, (bool_t)TRUE));

/* Disable D0 continuous BIT */
check_status(naibrd_SD_SetModuleBITEnable(cardIndex, module,
             NAI_SD_TEST_ENABLE_D0, (bool_t)FALSE));

To read the current D0 test enable state:

bool_t d0TestEnabled = FALSE;
check_status(naibrd_SD_GetModuleBITEnable(cardIndex, module,
             NAI_SD_TEST_ENABLE_D0, &d0TestEnabled));

Checking Power-On BIT

Power-on BIT runs automatically when the module is first powered up. To check whether it has completed and review the results:

bool_t pBitComplete = FALSE;
check_status(naibrd_SD_CheckPowerOnBITComplete(cardIndex, module, &pBitComplete));

if (pBitComplete)
{
   uint32_t bitStatus = 0u;
   for (channel = 1; channel <= channelCount; channel++)
   {
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel,
                   NAI_SD_STATUS_BIT_LATCHED, &bitStatus));
      /* bitStatus == 0: passed, bitStatus == 1: FAILED */
   }
}

Clearing BIT Status

To clear a latched BIT failure after resolving the underlying issue:

check_status(naibrd_SD_ClearStatus(cardIndex, module, channel,
             NAI_SD_STATUS_BIT_LATCHED));
Important

Common Errors

  • BIT always reports FAILED — The BIT error limit may be set too tight for the module’s inherent accuracy. Consult your module’s manual for the specified accuracy and set the error limit accordingly.

  • Power-on BIT never completes — This can indicate a hardware fault or that the module firmware is not responding. Power-cycle the board and check the module’s physical installation.

  • BIT passes but angle readings are incorrect — BIT tests the internal conversion hardware, not the external sensor or wiring. If BIT passes but readings are wrong, check the sensor connections, mode setting, and reference signal.

Troubleshooting Reference

The following table summarizes common errors and symptoms you may encounter when working with SD modules. Consult your module’s manual for hardware-specific diagnostics and specifications.

Error / Symptom Possible Causes Suggested Resolution

Angle reads 0.0 or does not change

Reference signal not connected; signal wires disconnected; channel mode mismatch (synchro vs resolver)

Verify reference and signal wiring. Check naibrd_SD_GetRefVoltage() and naibrd_SD_GetSignalVoltage() for non-zero values. Confirm mode matches sensor type via naibrd_SD_GetChanMode().

Angle drifts or is noisy

Low signal voltage; reference frequency mismatch; electromagnetic interference on sensor wiring

Verify signal and reference voltages are within the module’s specified operating range. Use shielded cabling. Consult the module manual for supported frequency ranges.

Signal loss status triggered

Input signal voltage below the signal loss threshold; broken sensor wire; loose connector

Check physical wiring. Verify the signal loss threshold is set appropriately for your sensor’s output voltage range using naibrd_SD_GetSigLossThreshold().

Reference loss status triggered

Reference excitation voltage below the reference loss threshold; reference source not powered; incorrect reference frequency

Verify the reference source is powered and within the module’s supported frequency and voltage range. Check naibrd_SD_GetRefVoltage() and naibrd_SD_GetFrequency().

BIT failure on one or more channels

Internal conversion hardware fault; BIT error limit set too tight; test angle not set

Review the BIT error limit via naibrd_SD_GetBITErrorLimit(). Consult the module manual for expected accuracy. If the error limit is appropriate, the module may need service.

Open or short circuit status

Physical wiring fault; sensor damage; incorrect open/short threshold settings

Inspect sensor wiring for physical damage. Verify threshold settings are appropriate for your wiring configuration per the module manual.

Lock loss status (two-speed systems)

Coarse and fine synchro/resolver channels are out of synchronization; wiring error between coarse and fine sensors

Verify that both coarse and fine sensors are properly connected and that their angular alignment is within the module’s lock range. Refer to the module manual for two-speed configuration details.

NAI_ERROR_NOT_SUPPORTED

API call not supported by the installed module’s firmware revision; channel number out of range

Verify the channel number is within naibrd_SD_GetChannelCount(). Check the module’s firmware revision against the API documentation for feature availability.

Full Source

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

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

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_sd.h"
#include "advanced/nai_ether_adv.h"

static const int8_t *CONFIG_FILE = (const int8_t *)"default_SD_BasicOps.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(nai_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 nai_status_t DisplayAsHex = 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_BasicOpsMenu 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 AD routines.
 - ConfigDevice
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - CheckModule
</summary>
*/
/*****************************************************************************/
#if defined (__VXWORKS__)
int32_t SD_BasicOpsMenu(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         /* Query the user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

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

         printf("\nType Q to quit or Enter key to restart application:\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   printf("\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();

   return 0;
}
/*****************************************************************************/
/**
<summary>
SDBasicMenu_Run illustrates the channel configuration and prepares the menu
which will handle user command requests. Returns 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 = FALSE, bCmdFound = 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 = 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*)"MENU_TITLE");
      printf("\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_BASICMENU_CMD_COUNT))
         {
            if (cmd == SD_BASICMENU_CMD_DISPLAY_CONVERTED)
               DisplayAsHex = FALSE;
            else if (cmd == SD_BASICMENU_CMD_DISPLAY_HEX)
               DisplayAsHex = TRUE;
            else
            {
               if ((cmd == SD_BASICMENU_CMD_SET_MODE) || (cmd == SD_BASICMENU_CMD_SET_CHAN_STATUS_ENABLE) ||
                   (cmd == SD_BASICMENU_CMD_SET_SIGLOSS_THRESHOLD) || (cmd == SD_BASICMENU_CMD_SET_REFLOSS_THRESHOLD) ||
                   (cmd == SD_BASICMENU_CMD_CLEAR_STATUS) || (cmd == SD_BASICMENU_CMD_FLOATING_POINT) ||
                   (cmd == SD_BASICMENU_CMD_SET_DELTA_ANGLE) || (cmd == SD_BASICMENU_CMD_INIT_DELTA_ANGLE) ||
                   (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))
                  naiapp_query_ChannelNumber(MAX_CHANNELS, 1, &sd_basicOps_params->channel);
               else
               bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
               if (bCmdFound)
               {
                  SD_BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)sd_basicOps_params);
               }
            }
         }
         else
            printf(" Invalid command entered\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);
   nai_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;
   uint32_t BitStatus = NAI_STATUS_BIT_LO, SigLoss = NAI_STATUS_BIT_LO, RefLoss = NAI_STATUS_BIT_LO, SummaryStatus = NAI_STATUS_BIT_LO;
   uint32_t SigHiStat = NAI_STATUS_BIT_LO, RefHiStat = NAI_STATUS_BIT_LO, OpenStat = NAI_STATUS_BIT_LO, ShortStat = NAI_STATUS_BIT_LO;
   uint32_t DeltaAngleStat = NAI_STATUS_BIT_LO, 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[10] = "";

   printf("\n\n =================================================================================================================================================== \n");
   printf(" channel  Mode          Angle    Frequency     Signal      Ref          Min       Min           Max       Max          Open        Short       Delta\n");
   printf("                                             Voltage    Voltage     Signal    Reference     Signal    Reference    Threshold   Threshold     Angle\n");
   printf(" ---------------------------------------------------------------------------------------------------------------------------------------------------\n");
   for( channel = 1; channel <= MAX_CHANNEL; channel++)
   {
      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, NAI_SD_CHAN_RAW_ANGLE, &rawangle));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_FREQUENCY, &rawfreq));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_SIGNAL_VOLTAGE, &rawsigvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_REF_VOLTAGE, &rawrefvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_SIG_LOSS_THRESHOLD, &rawminsigvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_REF_LOSS_THRESHOLD, &rawminrefvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_SIG_FAULT_HI_THRESHOLD, &rawmaxsigvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_REF_FAULT_HI_THRESHOLD, &rawmaxrefvolt));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_OPEN_THRESHOLD, &rawOpenThres));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_SHORT_THRESHOLD, &rawShortThres));
         check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_ANGLE_DELTA, &rawDeltaAngle));
         printf("0x%08X  0x%08X  0x%08X  0x%08X 0x%08X  0x%08X  0x%08X  0x%08X  0x%08X  0x%08X  0x%08X\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_GetSigLossThreshold(cardIndex, module, channel, &minsigvolt));
         check_status(naibrd_SD_GetRefLossThreshold(cardIndex, module, channel, &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));
         printf("%9.4f      %6.2f      %6.2f     %6.2f     %6.2f       %6.2f     %6.2f       %6.2f       %6.2f      %6.2f   %9.4f\n", angle,
                frequency, sigvolt, refvolt, minsigvolt, minrefvolt, maxsigvolt, maxrefvolt, openThres, shortThres, deltaAngle);
      }
   }

   printf("\n\n ============================================================================================================================== \n");
   printf(" channel  channelStat     BIT     Sig Fault   Ref Fault   Sig Fault   Ref Fault   Lock Loss    Open    Short   Delta Angle  Summary\n");
   printf("         Enable      Status   Lo Status   Lo Status   Hi Status   Hi Status    Status     Status   Status    Status     Status\n");
   printf(" ------------------------------------------------------------------------------------------------------------------------------\n");
   for( channel = 1; channel <= MAX_CHANNEL; channel++)
   {
      printf("  %2d    ", channel);
      check_status(naibrd_SD_GetChanStatusEnable(cardIndex, module, channel, &chanStatusEnable));
      switch (chanStatusEnable)
      {
         case TRUE:
            sprintf(strChanStatusEnable, "Enabled ");
         break;
         case FALSE:
            sprintf(strChanStatusEnable, "Disabled");
         break;
         default:
            sprintf(strChanStatusEnable, "Unknown ");
         break;
      }
      printf("%8s  ", strChanStatusEnable);
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_BIT_LATCHED, &BitStatus));
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_SIGNAL_LATCHED, &SigLoss));
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_REF_LATCHED, &RefLoss));
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_2SPDLOCKLOSS_LATCHED, &LockLossStat));
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_ANGLEDELTA_LATCHED, &DeltaAngleStat));
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_OPEN_LATCHED, &OpenStat));
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_SHORT_LATCHED, &ShortStat));
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_REF_FAULT_HIGH_LATCHED, &RefHiStat));
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_SIG_FAULT_HIGH_LATCHED, &SigHiStat));
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_SUMMARY_LATCHED, &SummaryStatus));
      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);
   }
}
/*****************************************************************************/
/**
<summary>
SDBasicMenu_displayMode prints mode value.
</summary>
*/
/*****************************************************************************/
static void SDBasicMenu_displayMode(nai_sd_format_t mode)
{
   if (mode == NAI_SD_RESOLVER)
      printf("RSL(%d)     ", mode);
   else if (mode == NAI_SD_SYNCHRO)
      printf("SYN(%d)     ", mode);
   else
      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)
      printf("   FAILED  ");
   else if (BitStatus == NAI_STATUS_BIT_LO)
      printf("   Normal  ");
   else
      printf("   Error   ");

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

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

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

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

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

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

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

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

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

static nai_status_t SDBasicMenu_SetMode(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_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

   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 = NAI_SD_RESOLVER;
         else
            mode = NAI_SD_SYNCHRO;
         check_status(naibrd_SD_SetChanMode(cardIndex, module, channel, mode));
      }
      else
         printf("\nInvalid SD Mode Entered\n");
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetChanStatusEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = 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

   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
      {
         printf("\nInvalid setting entered\n");
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_ClearStatus(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_sd_status_type_t statusTypeToClear = 0u;
   char statusTypeStr[18] = "";
   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

   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, ");
   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 = NAI_SD_STATUS_BIT_LATCHED;
            sprintf(statusTypeStr, "BIT");
         break;
         case '1':
            statusTypeToClear = NAI_SD_STATUS_SIGNAL_LATCHED;
            sprintf(statusTypeStr, "Signal Fault Low");
         break;
         case '2':
            statusTypeToClear = NAI_SD_STATUS_REF_LATCHED;
            sprintf(statusTypeStr, "Ref Fault Low");
         break;
         case '3':
            statusTypeToClear = NAI_SD_STATUS_SIG_FAULT_HIGH_LATCHED;
            sprintf(statusTypeStr, "Signal Fault High");
         break;
         case '4':
            statusTypeToClear = NAI_SD_STATUS_REF_FAULT_HIGH_LATCHED;
            sprintf(statusTypeStr, "Ref Fault High");
         break;
         case '5':
            statusTypeToClear = NAI_SD_STATUS_2SPDLOCKLOSS_LATCHED;
            sprintf(statusTypeStr, "Lock Loss");
         break;
         case '6':
            statusTypeToClear = NAI_SD_STATUS_OPEN_LATCHED;
            sprintf(statusTypeStr, "Open");
         break;
         case '7':
            statusTypeToClear = NAI_SD_STATUS_SHORT_LATCHED;
            sprintf(statusTypeStr, "Short");
         break;
         case '8':
            statusTypeToClear = NAI_SD_STATUS_ANGLEDELTA_LATCHED;
            sprintf(statusTypeStr, "Delta Angle");
         break;
         case '9':
            statusTypeToClear = NAI_SD_STATUS_SUMMARY_LATCHED;
            sprintf(statusTypeStr, "Summary");
         break;
         case 'q':
         case 'Q':
            bQuit = TRUE;
         break;
         default:
            bQuit = TRUE;
            printf("\nInvalid status type entered\n");
         break;
      }

      if (!bQuit)
      {
         printf("\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_ClearStatus(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 = 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

   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)
   {
      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, NAI_SD_CHAN_RAW_SIG_LOSS_THRESHOLD, thresholdRaw));
            }
            else
            {
               printf("\nInvalid value entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_SIG_LOSS_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      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_SetSigLossThreshold(cardIndex, module, channel, threshold));
            }
            else
            {
               printf("\nInvalid Signal Threshold Entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetSigLossThreshold(cardIndex, module, channel, threshold));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetRefLossThreshold(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = 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

   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)
   {
      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, NAI_SD_CHAN_RAW_REF_LOSS_THRESHOLD, thresholdRaw));
            }
            else
            {
               printf("\nInvalid value entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_REF_LOSS_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      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_SetRefLossThreshold(cardIndex, module, channel, threshold));
            }
            else
            {
               printf("\nInvalid Reference Threshold Entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetRefLossThreshold(cardIndex, module, channel, threshold));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_SetSigFaultHiThreshold(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = 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)
   {
      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, NAI_SD_CHAN_RAW_SIG_FAULT_HI_THRESHOLD, thresholdRaw));
            }
            else
            {
               printf("\nInvalid value entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_SIG_FAULT_HI_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      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
            {
               printf("\nInvalid Signal Threshold Entered\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 = 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)
   {
      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, NAI_SD_CHAN_RAW_REF_FAULT_HI_THRESHOLD, thresholdRaw));
            }
            else
            {
               printf("\nInvalid value entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_REF_FAULT_HI_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      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
            {
               printf("\nInvalid Reference Threshold Entered\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 = 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)
   {
      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, NAI_SD_CHAN_RAW_OPEN_THRESHOLD, thresholdRaw));
            }
            else
            {
               printf("\nInvalid value entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_OPEN_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      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
            {
               printf("\nInvalid Open Threshold Entered\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 = 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)
   {
      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, NAI_SD_CHAN_RAW_SHORT_THRESHOLD, thresholdRaw));
            }
            else
            {
               printf("\nInvalid value entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_SHORT_THRESHOLD, thresholdRaw));
         }
      }
   }
   else
   {
      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
            {
               printf("\nInvalid Short Threshold Entered\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 = 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)
   {
      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, NAI_SD_CHAN_RAW_ANGLE_DELTA, deltaAngleRaw));
            }
            else
            {
               printf("\nInvalid value entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_ANGLE_DELTA, deltaAngleRaw));
         }
      }
   }
   else
   {
      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
            {
               printf("\nInvalid Delta Angle value entered\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 = 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

   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)
         {
            printf("\nDelta Angle Status reporting has been disabled for channel %d.\n", channel);
         }
      }
      else if (inputBuffer[0] == '1')
      {
         status = check_status(naibrd_SD_SetAngleDataInit(cardIndex, module, channel, (bool_t)0x1u));
         if (status == NAI_SUCCESS)
         {
            printf("\nDelta Angle Status reporting has been enabled for channel %d.\n", channel);
         }
      }
      else
      {
         printf("\nInvalid selection entered\n");
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_FloatingPointMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t floatModeEnabled = FALSE;
   int32_t channel= 0;
   int32_t maxChannel = 0;
   float64_t angleOffset = 0.0, angleScale = 0.0, velocityOffset = 0.0, velocityScale = 0.0;
   uint32_t attributeTypeToSet = 0u;
   bool_t bQuit = FALSE;
   bool_t bExit = FALSE;
   float64_t valueToSet = 0.0;
   char strFloatModeEnabled[10] = "";
   char strAttributeType[20] = "";
   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 chan= p_sd_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   maxChannel = naibrd_SD_GetChannelCount(g_modId);

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

   while (bQuit == FALSE)
   {
      printf("====================================================\n");
      printf("%4s%12s%11s%13s%12s\n", "Chan", "Angle", "Angle", "Velocity", "Velocity");
      printf("%4s%12s%12s%10s%13s\n", "", "Scale", "Offset", "Scale", "Offset");
      printf("----------------------------------------------------\n");
      for (channel= 1; channel<= maxChannel; chan++)
      {
         check_status(naibrd_SD_GetFloatingPointAngleScale(cardIndex, module, chan, &angleScale));
         check_status(naibrd_SD_GetFloatingPointAngleOffset(cardIndex, module, chan, &angleOffset));
         check_status(naibrd_SD_GetFloatingPointVelocityScale(cardIndex, module, chan, &velocityScale));
         check_status(naibrd_SD_GetFloatingPointVelocityOffset(cardIndex, module, chan, &velocityOffset));

         printf("%2d", chan);
         printf("%14.4f%12.4f%12.4f%12.4f\n", angleScale, angleOffset, velocityScale, velocityOffset);
      }
      check_status(naibrd_GetFloatingPointModeEnable(cardIndex, module, &floatModeEnabled));
      switch (floatModeEnabled)
      {
         case FALSE:
            sprintf(strFloatModeEnabled, "DISABLED");
         break;
         case TRUE:
            sprintf(strFloatModeEnabled, "ENABLED ");
         break;
         default:
            sprintf(strFloatModeEnabled, "UNKNOWN ");
         break;
      }
      printf("Floating-Point Mode: %s\n\n", strFloatModeEnabled);
      printf("\nDo you want to enable/disable floating-point mode, set floating-point attributes, or refresh the display? (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')
         {
            printf("\nSet Floating-Point Attributes (0 for Angle Scale, 1 for Angle Offset, 2 for Velocity Scale, 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 = 0u;
                     sprintf(strAttributeType, "Angle Scale");
                  break;
                  case '1':
                     attributeTypeToSet = 1u;
                     sprintf(strAttributeType, "Angle Offset");
                  break;
                  case '2':
                     attributeTypeToSet = 2u;
                     sprintf(strAttributeType, "Velocity Scale");
                  break;
                  case '3':
                     attributeTypeToSet = 3u;
                     sprintf(strAttributeType, "Velocity Offset");
                  break;
                  default:
                     bExit = TRUE;
                  break;
               }

               if (!bExit)
               {
                  printf("\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')
                        {
                           switch (attributeTypeToSet)
                           {
                              case 0u:
                                 check_status(naibrd_SD_SetFloatingPointAngleScale(cardIndex, module, channel, valueToSet));
                              break;
                              case 1u:
                                 check_status(naibrd_SD_SetFloatingPointAngleOffset(cardIndex, module, channel, valueToSet));
                              break;
                              case 2u:
                                 check_status(naibrd_SD_SetFloatingPointVelocityScale(cardIndex, module, channel, valueToSet));
                              break;
                              case 3u:
                                 check_status(naibrd_SD_SetFloatingPointVelocityOffset(cardIndex, module, channel, valueToSet));
                              break;
                           }
                        }
                        else
                        {
                           printf("\nInvalid value entered\n");
                        }
                     }
                     else
                     {
                        switch (attributeTypeToSet)
                        {
                           case 0u:
                              check_status(naibrd_SD_SetFloatingPointAngleScale(cardIndex, module, channel, valueToSet));
                           break;
                           case 1u:
                              check_status(naibrd_SD_SetFloatingPointAngleOffset(cardIndex, module, channel, valueToSet));
                           break;
                           case 2u:
                              check_status(naibrd_SD_SetFloatingPointVelocityScale(cardIndex, module, channel, valueToSet));
                           break;
                           case 3u:
                              check_status(naibrd_SD_SetFloatingPointVelocityOffset(cardIndex, module, channel, valueToSet));
                           break;
                        }
                     }
                  }
               }
            }
         }
         else
         {
            printf("\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, FALSE));
                  break;
                  case '1':
                     check_status(naibrd_SetFloatingPointModeEnable(cardIndex, module, TRUE));
                  break;
               }
            }
         }
      }
   }

   return NAI_SUCCESS;
}

static nai_status_t SDBasicMenu_TestMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   int32_t cmd = 0;
   float64_t testAngle = 0.0;
   uint32_t testAngleRaw = 0u;
   bool_t d0TestEnabled = FALSE;
   bool_t pBitComplete = 0u;
   uint32_t bitStatus = 0u;
   float64_t bitErrorLimit = 0.0;
   uint32_t bitErrorLimitRaw = 0u;
   int32_t channelCount = 0;
   char strBITStatus[7] = "";
   char strD0TestEnabled[10] = "";
   char strPBITComplete[15] = "";
   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
   {
      printf("\n\n ============================= \n");
      printf(" channel    BIT        BIT Error\n");
      printf("         Status        Limit\n");
      printf(" -----------------------------\n");
      for (channel = 1; channel <= channelCount; channel++)
      {
         check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_BIT_LATCHED, &bitStatus));
         switch (bitStatus)
         {
            case (uint32_t)NAI_STATUS_BIT_LO:
               sprintf(strBITStatus, "Normal");
            break;
            case (uint32_t)NAI_STATUS_BIT_HI:
               sprintf(strBITStatus, "FAILED");
            break;
            default:
               sprintf(strBITStatus, "Error ");
            break;
         }
         if (DisplayAsHex)
         {
            check_status(naibrd_SD_GetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_BIT_ERROR_LIMIT, &bitErrorLimitRaw));
            printf("  %2d     %s     0x%08X\n", channel, strBITStatus, bitErrorLimitRaw);
         }
         else
         {
            check_status(naibrd_SD_GetBITErrorLimit(cardIndex, module, channel, &bitErrorLimit));
            printf("  %2d     %s   %12.4f\n", channel, strBITStatus, bitErrorLimit);
         }
      }
      if (DisplayAsHex)
      {
         check_status(naibrd_SD_GetRaw(cardIndex, module, NAI_SD_RAW_TEST_ANGLE, &testAngleRaw));
      }
      else
      {
         check_status(naibrd_SD_GetTestAngle(cardIndex, module, &testAngle));
      }
      check_status(naibrd_SD_GetModuleBITEnable(cardIndex, module, NAI_SD_TEST_ENABLE_D0, &d0TestEnabled));
      switch (d0TestEnabled)
      {
         case TRUE:
            sprintf(strD0TestEnabled, "ENABLED ");
         break;
         case FALSE:
            sprintf(strD0TestEnabled, "DISABLED");
         break;
         default:
            sprintf(strD0TestEnabled, "UNKNOWN ");
         break;
      }
      check_status(naibrd_SD_CheckPowerOnBITComplete(cardIndex, module, &pBitComplete));
      switch (pBitComplete)
      {
         case TRUE:
            sprintf(strPBITComplete, "COMPLETED");
         break;
         case FALSE:
            sprintf(strPBITComplete, "NOT COMPLETED");
         break;
         default:
            sprintf(strPBITComplete, "UNKNOWN");
         break;
      }
      if (DisplayAsHex)
      {
         printf("\nTest Angle Raw Hex Value: 0x%08X\n", testAngleRaw);
      }
      else
      {
         printf("\nTest Angle: %-16.8f\n", testAngle);
      }
      printf("D0 Test Enabled/Disabled: %s\n", strD0TestEnabled);
      printf("Power-On BIT Complete: %s\n", strPBITComplete);
      naiapp_display_ParamMenuCommands((int8_t*)"SD Test Menu");
      printf("\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 = FALSE;
            }
            else if (cmd == SD_TESTMENU_CMD_DISPLAY_HEX)
            {
               DisplayAsHex = 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
         {
            printf(" Invalid command entered\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 = 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[500];

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
   printf("\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 = strtol(((const char *)inputBuffer), NULL, 16);
        check_status(naibrd_ReadReg32(cardIndex, 0, Addr, &data));
        printf("Read Register: 0x%x\n", Addr);
        printf("Read value: 0x%x\n", data);
      }
   }
   do
   {
      printf("\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 = strtol ((const char *)inputBuffer, NULL, 16);
         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));
            sprintf((char *)buffer, "\n            0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x0x%-10x\n",
                                         0x0, 0x4, 0x8, 0xc, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c);
            printf("%s", buffer);
            dataCount = strtol ((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;
                  printf("            \n0x%-10x0x%-10x", rowAddr,data);
               }
               else
                  printf("0x%-10x", data);
            }
         }
      }
      printf("\nType %c to exit: ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   }while(!bQuit);
   return bQuit;
}
static nai_status_t SDBasicMenu_WriteReg(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = 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
   printf("\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 = strtol(((const char *)inputBuffer), NULL, 16);
         printf("\nEnter the value to write: 0x");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               data = strtol(((const char *)inputBuffer), NULL, 16);
               check_status(naibrd_WriteReg32(cardIndex, 0, Addr, data));
               printf("Write Register: 0x%x\n", Addr);
               printf("Write value: 0x%x\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 = 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

   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_ClearStatus(cardIndex, module, channel, NAI_SD_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 = 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)
   {
      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, NAI_SD_CHAN_RAW_BIT_ERROR_LIMIT, bitErrorLimitRaw));
            }
            else
            {
               printf("\nInvalid value entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetChannelRaw(cardIndex, module, channel, NAI_SD_CHAN_RAW_BIT_ERROR_LIMIT, bitErrorLimitRaw));
         }
      }
   }
   else
   {
      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
            {
               printf("\nInvalid BIT Error Limit entered\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 = 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)
   {
      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, NAI_SD_RAW_TEST_ANGLE, testAngleRaw));
            }
            else
            {
               printf("\nInvalid value entered\n");
            }
         }
         else
         {
            check_status(naibrd_SD_SetRaw(cardIndex, module, NAI_SD_RAW_TEST_ANGLE, testAngleRaw));
         }
      }
   }
   else
   {
      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
            {
               printf("\nInvalid Test Angle entered\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 = 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

   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, NAI_SD_TEST_ENABLE_D0, (bool_t)FALSE));
         break;
         case '1':
            check_status(naibrd_SD_SetModuleBITEnable(cardIndex, module, NAI_SD_TEST_ENABLE_D0, (bool_t)TRUE));
         break;
         default:
            printf("\nInvalid selection entered\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 = FALSE;
   int32_t channelCount = 0;
   bool_t pBitComplete = FALSE;
   uint32_t bitStatus = 0u;
   char strBitStatus[12] = "";
   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. */
   printf("Checking if the Power-On BIT test has run...\n");
   check_status(naibrd_SD_CheckPowerOnBITComplete(cardIndex, module, &pBitComplete));
   switch (pBitComplete)
   {
      case 0u:
         printf("\nPBIT Complete: NOT COMPLETED\n");
      break;
      case 1u:
         printf("\nPBIT Complete: COMPLETED\n");
      break;
      default:
         printf("\nPBIT Complete: UNKNOWN\n");
      break;
   }

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

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

Help Bot

X