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

VR BasicOps

VR BasicOps Sample Application (SSK 1.x)

Overview

The VR BasicOps sample application demonstrates how to configure and read variable reluctance (VR) sensor channels using the NAI Software Support Kit (SSK 1.x). VR modules measure the AC signal generated by a toothed wheel or gear rotating past a magnetic pickup. As each tooth passes the sensor, it induces a voltage pulse whose frequency is proportional to rotational speed. The module conditions this signal and extracts amplitude, frequency, RPM, period, phase, percent torque, and cumulative cycle count — all readable through the naibrd_VR_*() API.

This sample supports the VR1 module type. It serves as a practical API reference — each menu command maps directly to one or more naibrd_VR_*() API calls that you can lift into your own code.

Note
VR modules measure the raw AC signal from a variable reluctance sensor. If your application requires synchro-to-digital or resolver-to-digital conversion (computing angular position from reference and signal windings), see the SD BasicOpsMenu sample application instead.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a VR module installed (VR1).

  • 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 VR_BasicOps executable from your build output directory. On startup the application looks for a configuration file (default_VR_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 main menu lets you exercise each VR operation through four submenus: Channel Setup, Display Readings, System Test Setup, and Display Monitor/Status.

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 VR. 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_VR_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 VR variant installed.

#if defined (__VXWORKS__)
int32_t VR_BasicOps(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;

   g_ReadingsUpdateRate = 1000;
   g_StatusUpdateRate = 1000;
   g_stopReadingsUpdateThread = TRUE;
   g_stopStatusUpdateThread = TRUE;
   g_initialReadingsThreadStarted = FALSE;
   g_initialStatusThreadStarted = FALSE;

   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);
               if ((moduleID != 0))
               {
                  VRBasicMenu_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 a VR module. Use the board menu to verify which slots are populated.

Program Structure

Application Parameters

Once connected, VRBasicMenu_Run() populates an naiapp_AppParameters_t struct that is passed to every submenu handler. Your application will need to track the same values:

  • cardIndex — zero-based board identifier.

  • module — one-based module slot number.

  • modId — module ID returned by naibrd_GetModuleID().

  • maxChannels — channel count returned by naibrd_VR_GetChannelCount().

  • channel — the currently selected channel (set to 0 when applying a command to all channels).

naiapp_AppParameters_t  VR_basicOps_params;
p_naiapp_AppParameters_t p_VR_basicOps_params = &VR_basicOps_params;
p_VR_basicOps_params->cardIndex = cardIndex;
p_VR_basicOps_params->module = module;
p_VR_basicOps_params->modId = modid;
MAX_CHANNELS = naibrd_VR_GetChannelCount(modid);
p_VR_basicOps_params->maxChannels = MAX_CHANNELS;

The main menu presents four submenus. The menu system is a sample convenience — in your own code, call these API functions directly.

Command Submenu Purpose

CS

Channel Setup Menu

Configure per-channel measurement parameters

R

Display Readings Menu

Poll and display live measurements

T

System Test Setup Menu

Enable BIT, power supply, and floating-point mode

Mon

Display Monitor/Status Menu

View and manage channel status flags

Channel Setup

The Channel Setup submenu lets you configure every per-channel parameter that controls how the VR module conditions and interprets the incoming sensor signal. When you select a channel setup command, the sample prompts you to apply the setting to all channels (A) or to a specific channel (S). This maps to either looping over all channels or calling the API once for the selected channel.

The display function VRChannelMenu_DisplayChannelSetup() reads back every configuration parameter across all channels using the corresponding naibrd_VR_Get*() calls and prints them in a tabular format.

Number of Teeth

To configure the number of teeth on the target wheel or gear, call naibrd_VR_SetConfigValue() with the NAI_VR_CONFIG_NUMBER_OF_TEETH parameter. The module uses this value to convert the measured signal frequency into RPM: RPM = (frequency x 60) / number_of_teeth.

numberOfTeeth = atof((const char*)inputBuffer);
check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_NUMBER_OF_TEETH, numberOfTeeth));

Parameters:

  • numberOfTeeth — the number of teeth on the target wheel. Must match the physical hardware for accurate RPM calculation.

Monopole / Dipole Select

To configure the sensor type, call naibrd_VR_SetChanMappedControl() with NAI_VR_CHAN_MAPPED_CONTROL_DIPOLE_ENABLE. A monopole sensor produces one pulse per tooth; a dipole sensor produces a positive and negative pulse pair per tooth. The module adjusts its measurement algorithm accordingly.

check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
             NAI_VR_CHAN_MAPPED_CONTROL_DIPOLE_ENABLE, enableDipole));

Parameters:

  • enableDipole — TRUE for dipole mode, FALSE for monopole mode.

Channel Enable

To enable or disable measurement on a channel, call naibrd_VR_SetChanMappedControl() with NAI_VR_CHAN_MAPPED_CONTROL_CHANNEL_ENABLE. A disabled channel does not process input signals and reports no measurements.

check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
             NAI_VR_CHAN_MAPPED_CONTROL_CHANNEL_ENABLE, enable));

Parameters:

  • enable — TRUE to enable the channel, FALSE to disable it.

Voltage Thresholds (High and Low)

To set the voltage thresholds that define valid signal crossings, call naibrd_VR_SetConfigValue() with NAI_VR_CONFIG_VOLTAGE_THRESHOLD_HIGH or NAI_VR_CONFIG_VOLTAGE_THRESHOLD_LOW. The module counts a tooth passage when the signal crosses above the high threshold and then below the low threshold (or vice versa for falling-edge polarity). Setting appropriate thresholds is critical for rejecting noise.

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_VOLTAGE_THRESHOLD_HIGH, voltThresHigh));

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_VOLTAGE_THRESHOLD_LOW, voltThresLow));

Parameters:

  • voltThresHigh — high voltage threshold in volts.

  • voltThresLow — low voltage threshold in volts.

Note
If the high and low thresholds are set too close together or too close to the noise floor, the module may count spurious crossings. Consult your module’s manual for recommended threshold values based on your sensor output levels.

Auto Threshold

The auto threshold feature allows the module to dynamically adjust voltage thresholds based on the measured signal amplitude. Three related parameters control this behavior:

Auto Threshold Enable

To enable or disable automatic threshold adjustment, call naibrd_VR_SetChanMappedControl() with NAI_VR_CHAN_MAPPED_CONTROL_AUTO_THRESHOLD_ENABLE.

check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
             NAI_VR_CHAN_MAPPED_CONTROL_AUTO_THRESHOLD_ENABLE, enable));

Auto Threshold Percent

To set the percentage of the measured peak amplitude used to compute automatic threshold levels, call naibrd_VR_SetConfigValue() with NAI_VR_CONFIG_AUTO_THRESHOLD_PERCENT.

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_AUTO_THRESHOLD_PERCENT, autoThresholdPercent));

Auto Threshold Hysteresis

To set the hysteresis applied to the auto threshold levels (preventing rapid toggling near the threshold boundary), call naibrd_VR_SetConfigValue() with NAI_VR_CONFIG_AUTO_THRESHOLD_HYSTERESIS. The value is specified as a percentage.

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_AUTO_THRESHOLD_HYSTERESIS, autoThresholdHysteresis));

Auto Down-Range Time

To set the time the module waits before automatically reducing the input range when the signal amplitude drops, call naibrd_VR_SetAutoDownRangeTime(). This only applies when range is set to Auto. The available time selections are:

Selection Time Constant

NAI_VR_AUTO_DOWN_RANGE_TIME_100MS

100 ms

NAI_VR_AUTO_DOWN_RANGE_TIME_500MS

500 ms

NAI_VR_AUTO_DOWN_RANGE_TIME_1S

1 second

NAI_VR_AUTO_DOWN_RANGE_TIME_2S

2 seconds

NAI_VR_AUTO_DOWN_RANGE_TIME_5S

5 seconds

NAI_VR_AUTO_DOWN_RANGE_TIME_10S

10 seconds

check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel,
             NAI_VR_AUTO_DOWN_RANGE_TIME_1S));

Range Select

To set the input voltage range for a channel, call naibrd_VR_SetRangeSelect(). Selecting a range that closely matches your expected signal amplitude maximizes measurement resolution. The NAI_VR_RANGE_AUTO setting enables automatic range selection.

Enum Constant Range

NAI_VR_RANGE_AUTO

Automatic

NAI_VR_RANGE_50mV

50 mV

NAI_VR_RANGE_100mV

100 mV

NAI_VR_RANGE_250mV

250 mV

NAI_VR_RANGE_500mV

500 mV

NAI_VR_RANGE_1V

1 V

NAI_VR_RANGE_2P5V

2.5 V

NAI_VR_RANGE_5V

5 V

NAI_VR_RANGE_12P5V

12.5 V

NAI_VR_RANGE_25V

25 V

NAI_VR_RANGE_50V

50 V

NAI_VR_RANGE_100V

100 V

check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_5V));

Polarity Select

To configure which signal edge triggers a measurement, call naibrd_VR_SetChanMappedControl() with NAI_VR_CHAN_MAPPED_CONTROL_FALLING_EDGE_MEASUREMENT_ENABLE. By default the module triggers on the rising edge. Enabling falling-edge measurement may be appropriate depending on the sensor’s signal polarity.

check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
             NAI_VR_CHAN_MAPPED_CONTROL_FALLING_EDGE_MEASUREMENT_ENABLE,
             enableFallingEdgeMeas));

Parameters:

  • enableFallingEdgeMeas — TRUE for falling edge, FALSE for rising edge.

AC Couple Enable

To enable or disable AC coupling on the input, call naibrd_VR_SetChanMappedControl() with NAI_VR_CHAN_MAPPED_CONTROL_AC_COUPLE_ENABLE. AC coupling removes any DC offset from the sensor signal, which is important when the VR sensor produces a signal with a DC bias.

check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
             NAI_VR_CHAN_MAPPED_CONTROL_AC_COUPLE_ENABLE, enable));

Termination Enable

To enable or disable input termination on a channel, call naibrd_VR_SetChanMappedControl() with NAI_VR_CHAN_MAPPED_CONTROL_TERMINATION_ENABLE. Termination matches the input impedance to the cable and sensor to reduce signal reflections.

check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
             NAI_VR_CHAN_MAPPED_CONTROL_TERMINATION_ENABLE, enable));

Averaging Time

To set the measurement averaging time in seconds, call naibrd_VR_SetConfigValue() with NAI_VR_CONFIG_AVERAGING_TIME. Longer averaging times produce more stable readings at the cost of slower response to changes in speed.

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_AVERAGING_TIME, averagingTime));

Torque Measurement Parameters

The VR module supports percent-torque measurement by comparing the measured phase angle against reference angles. This requires three configuration parameters:

Zero Torque Signal Phase

To set the signal phase angle that represents zero torque, call naibrd_VR_SetConfigValue() with NAI_VR_CONFIG_ZERO_TORQUE_SIGNAL_PHASE. The value is specified in degrees.

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_ZERO_TORQUE_SIGNAL_PHASE, zeroTorqueSigPhase));

Set Zero Torque Signal Phase to Current Phase Reading

To capture the current measured phase angle and store it as the zero torque reference, call naibrd_VR_SetZeroTorqueSignalPhaseToPhaseReading(). This is a convenience function that eliminates the need to read the phase and write it back separately.

check_status(naibrd_VR_SetZeroTorqueSignalPhaseToPhaseReading(cardIndex, module, channel));

Max Torque Signal Phase

To set the signal phase angle that represents maximum torque, call naibrd_VR_SetConfigValue() with NAI_VR_CONFIG_MAX_TORQUE_SIGNAL_PHASE. The module computes percent torque as: measured_phase - zero_torque_phase) / (max_torque_phase - zero_torque_phase x 100.

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_MAX_TORQUE_SIGNAL_PHASE, maxTorqueSigPhase));

Debounce Time

To set the debounce time that filters rapid transitions (preventing false counts from contact bounce or noise), call naibrd_VR_SetConfigValue() with NAI_VR_CONFIG_DEBOUNCE_TIME. The value is in seconds.

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_DEBOUNCE_TIME, debounceTime));

Minimum Amplitude

To set the minimum signal amplitude (in volts) below which the module ignores input transitions, call naibrd_VR_SetConfigValue() with NAI_VR_CONFIG_MINIMUM_AMPLITUDE. This rejects low-level noise when the target wheel is stationary or moving very slowly.

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_MINIMUM_AMPLITUDE, minAmplitude));

Minimum Frequency

To set the minimum signal frequency (in Hz) below which the module ignores input transitions, call naibrd_VR_SetConfigValue() with NAI_VR_CONFIG_MINIMUM_FREQUENCY. Signals below this frequency are treated as no signal present.

check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel,
             NAI_VR_CONFIG_MINIMUM_FREQUENCY, minFreq));

Reset Cycle Count

To reset the cumulative cycle (tooth passage) counter to zero, call naibrd_VR_ResetCycleCount(). This is useful when beginning a new measurement session or when the counter approaches its maximum value.

check_status(naibrd_VR_ResetCycleCount(cardIndex, module, channel));

Save and Load Setup

The sample provides Save (S) and Load (L) commands that write all per-channel configuration parameters to a text file (VR_BasicOps_Setup.txt by default) and restore them. The save function reads each parameter with the corresponding naibrd_VR_Get*() call and writes it to the file. The load function parses the file and applies each parameter with the corresponding naibrd_VR_Set*() call. In your own application, you can use this pattern to implement configuration persistence.

Important

Common Errors

  • NAI_ERROR_NOT_SUPPORTED — the configuration parameter is not supported by the installed VR module variant. Verify the module ID and consult your module’s manual for supported features.

  • No measurement change after setting parameters — the channel may be disabled. Ensure NAI_VR_CHAN_MAPPED_CONTROL_CHANNEL_ENABLE is set to TRUE.

  • Erratic RPM readings — verify that the number of teeth is correctly configured. An incorrect tooth count directly scales the RPM calculation.

  • Threshold values rejected — the high threshold must be greater than the low threshold. Ensure the values are within the configured range.

Display Readings

The Display Readings submenu starts a background polling thread that periodically reads and displays all measurement values across all channels. The thread calls VRReadingsMenu_DisplayChannelReadings() at a configurable update rate (default: 1000 ms).

Measurement Values

The display function reads the following measurements for each channel using naibrd_VR_GetMeasurement():

Measurement API Constant Description

Amplitude (V)

NAI_VR_MEASURED_AMPLITUDE

Peak signal amplitude

Frequency (Hz)

NAI_VR_MEASURED_FREQUENCY

Signal frequency

RPM

NAI_VR_MEASURED_RPM

Revolutions per minute (derived from frequency and tooth count)

Period (Sec)

NAI_VR_MEASURED_PERIOD

Signal period

Phase (Deg)

NAI_VR_MEASURED_PHASE

Signal phase angle

Percent Torque

NAI_VR_MEASURED_PERCENT_TORQUE

Torque as percentage of configured range

Cycle Count

NAI_VR_MEASURED_CYCLE_COUNT

Cumulative tooth passage count

The sample also computes a Phase Delta value locally as the difference between the measured phase and the configured zero torque signal phase:

check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum,
             NAI_VR_MEASURED_AMPLITUDE, &amplitudeMeas));
check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum,
             NAI_VR_MEASURED_FREQUENCY, &freqMeas));
check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum,
             NAI_VR_MEASURED_RPM, &rpmMeas));
check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum,
             NAI_VR_MEASURED_PERIOD, &periodMeas));
check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum,
             NAI_VR_MEASURED_PHASE, &(phaseMeas[chanNum - 1])));
check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum,
             NAI_VR_MEASURED_PERCENT_TORQUE, &percentTorqueMeas));
check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum,
             NAI_VR_MEASURED_CYCLE_COUNT, &cycleCount));

/* Phase delta = measured phase - zero torque signal phase */
check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum,
             NAI_VR_CONFIG_ZERO_TORQUE_SIGNAL_PHASE, &zeroTorqueSigPhase));
phaseDelta = phaseMeas[chanNum - 1] - zeroTorqueSigPhase;

Polling Controls

Command Action

R

Change the update rate (in milliseconds)

C

Resume polling (restarts the display thread)

S

Stop polling (pauses the display thread)

MM

Return to the main menu

To change the update rate in your own code, simply adjust the delay between successive naibrd_VR_GetMeasurement() calls. The threading model in the sample is a convenience for continuous display.

Important

Common Errors

  • All measurements read zero — the channel may not be enabled, or there may be no signal connected. Verify channel enable and physical wiring.

  • RPM reads zero but frequency is nonzero — the number of teeth may be set to zero. The RPM calculation divides by tooth count.

  • Cycle count overflow — the counter wraps at its maximum value. Use naibrd_VR_ResetCycleCount() to reset it periodically in long-running applications.

System Test Setup

The System Test Setup submenu provides module-level diagnostic and configuration controls. These are not per-channel settings — they apply to the entire VR module.

IBIT (D3) Test Enable

To enable or disable the Initiated Built-In Test (IBIT), call naibrd_VR_SetModuleBITEnable() with NAI_VR_TEST_ENABLE_IBIT_D3. When enabled, the module runs self-diagnostics and reports results through the BIT status flags.

check_status(naibrd_VR_SetModuleBITEnable(cardIndex, module,
             NAI_VR_TEST_ENABLE_IBIT_D3, enable));

Power Supply Enable

To enable or disable the module’s power supply, call naibrd_VR_SetPowerSupplyEnable(). Disabling the power supply shuts down the analog front end. This can be used to reduce power consumption when the module is not actively measuring.

check_status(naibrd_VR_SetPowerSupplyEnable(cardIndex, module, enable));

Floating-Point Mode Enable

To enable or disable floating-point register mode, call naibrd_SetFloatingPointModeEnable(). When enabled, configuration and measurement registers use IEEE 754 floating-point format, which simplifies value interpretation. When disabled, values are in the module’s native fixed-point format.

check_status(naibrd_SetFloatingPointModeEnable(cardIndex, module, enable));
Note
The display reads the current state of each setting using naibrd_VR_GetModuleBITEnable(), naibrd_VR_GetPowerSupplyEnable(), and naibrd_GetRunningInFloatingPointMode().
Important

Common Errors

  • BIT status always shows failure after enabling IBIT — allow sufficient time for the self-test to complete before reading results. Consult your module’s manual for the expected IBIT duration.

  • Measurements stop after disabling power supply — this is expected. Re-enable the power supply to resume measurements.

  • NAI_ERROR_NOT_SUPPORTED — floating-point mode may require a minimum FPGA revision. Consult your module’s manual.

Status Monitoring

The Display Monitor/Status submenu starts a background polling thread that reads and displays per-channel status flags. The sample monitors four status categories, each with both realtime ® and latched (L) values:

Status Category Description

BIT

Built-In Test result for the channel

Termination Fault

Input termination circuit fault detected

Signal Loss

No valid signal detected on the channel

Summary

Logical OR of all status conditions

Reading Status

The display function reads each status using naibrd_VR_GetChanMappedStatus():

check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum,
             NAI_VR_CHAN_MAPPED_STATUS_BIT_LATCHED, &bitLatchedStatus));
check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum,
             NAI_VR_CHAN_MAPPED_STATUS_BIT_REALTIME, &bitRealtimeStatus));
check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum,
             NAI_VR_CHAN_MAPPED_STATUS_TERMINATION_FAULT_LATCHED,
             &terminationLatchedStatus));
check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum,
             NAI_VR_CHAN_MAPPED_STATUS_TERMINATION_FAULT_REALTIME,
             &terminationRealtimeStatus));
check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum,
             NAI_VR_CHAN_MAPPED_STATUS_SIGNAL_LOSS_LATCHED,
             &signalLossLatchedStatus));
check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum,
             NAI_VR_CHAN_MAPPED_STATUS_SIGNAL_LOSS_REALTIME,
             &signalLossRealtimeStatus));
check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum,
             NAI_VR_CHAN_MAPPED_STATUS_SUMMARY_LATCHED, &summaryLatchedStatus));
check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum,
             NAI_VR_CHAN_MAPPED_STATUS_SUMMARY_REALTIME,
             &summaryRealtimeStatus));

Realtime status reflects the current state of the channel. Latched status captures any fault that has occurred since the last clear — even if the fault has since resolved. This ensures transient faults are not missed.

Channel Status Enable

To enable or disable status reporting for a channel, call naibrd_VR_SetChanStatusEnable(). When disabled, the module does not update status flags for that channel.

check_status(naibrd_VR_SetChanStatusEnable(cardIndex, module, channel, enable));

Clear Latched Status

To clear a latched status flag, call naibrd_VR_ClearChanMappedStatus() with the appropriate status constant:

Selection Status Cleared

0

NAI_VR_CHAN_MAPPED_STATUS_BIT_LATCHED

1

NAI_VR_CHAN_MAPPED_STATUS_TERMINATION_FAULT_LATCHED

2

NAI_VR_CHAN_MAPPED_STATUS_SIGNAL_LOSS_LATCHED

3

NAI_VR_CHAN_MAPPED_STATUS_SUMMARY_LATCHED

check_status(naibrd_VR_ClearChanMappedStatus(cardIndex, module, channel,
             NAI_VR_CHAN_MAPPED_STATUS_BIT_LATCHED));

Status Polling Controls

Command Action

E

Enable or disable channel status reporting

C

Clear a latched status flag

R

Change the update rate (in milliseconds)

P

Resume polling

S

Stop polling

MM

Return to the main menu

Important

Common Errors

  • Latched status remains set after clearing — a new fault has occurred since the clear. Check the realtime status to see if the condition is ongoing, and resolve the underlying hardware issue.

  • Signal Loss status set on all channels — no signal is reaching the module. Verify sensor connections and that the signal amplitude exceeds the configured minimum amplitude threshold.

  • Status flags not updating — channel status enable may be set to FALSE. Enable it with naibrd_VR_SetChanStatusEnable().

Troubleshooting Reference

Note
This section summarizes errors covered in the preceding sections. Consult your module’s manual for hardware-specific diagnostics.
Error / Symptom Possible Causes Suggested Resolution

No board found

Board not powered; incorrect interface/address in config file

Power on the board; correct the configuration file or delete it to re-run the board menu

Connection timeout

Network/firewall issue; incorrect bus configuration

Verify Ethernet settings or PCI/PCIe configuration

NAI_ERROR_NOT_SUPPORTED

Feature not available on this VR module variant or FPGA revision

Check module ID and consult the module manual for supported features

All measurements read zero

Channel disabled; no signal connected; power supply disabled

Enable the channel; verify wiring; enable the power supply

Erratic or incorrect RPM

Wrong number of teeth configured; monopole/dipole mismatch

Set the correct tooth count; match the sensor type setting

Threshold values rejected

High threshold less than or equal to low threshold; values outside range

Set high threshold above low threshold within the module’s supported range

Signal Loss status set

No signal connected; amplitude below minimum threshold; frequency below minimum

Verify sensor wiring; adjust minimum amplitude and minimum frequency settings

Termination Fault status set

Input termination circuit fault

Check cable connections; consult module manual for hardware diagnostics

Latched status won’t clear

Fault condition is ongoing (realtime status still active)

Resolve the underlying fault before clearing the latch

Cycle count at maximum / overflow

Counter has reached its maximum value

Call naibrd_VR_ResetCycleCount() to reset

BIT test always reports failure

Insufficient time for self-test; hardware fault

Wait for IBIT to complete; consult module manual for expected test duration

Floating-point mode not available

FPGA revision does not support floating-point mode

Update FPGA firmware or use fixed-point register access

Full Source

Full Source — VR_BasicOps.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 "boards/naibrd_gen5.h"
#include "functions/naibrd_vr.h"
#include "advanced/nai_ether_adv.h"
#include "maps/nai_map_vr.h"

#if defined (LINUX)
#include <pthread.h>
#endif
#if defined (__VXWORKS__)
#include "taskLib.h"
#endif

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

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

static nai_status_t VRBasicMenu_ChannelSetupMenu(int32_t paramCount, int32_t* p_params);
static nai_status_t VRBasicMenu_DisplayReadingsMenu(int32_t paramCount, int32_t* p_params);
static nai_status_t VRBasicMenu_SystemTestSetupMenu(int32_t paramCount, int32_t* p_params);
static nai_status_t VRBasicMenu_DisplayMonitorStatusMenu(int32_t paramCount, int32_t* p_params);

static nai_status_t VRChannelMenu_SetNumberOfTeeth(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetMonopoleDipoleSelect(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetChannelEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetVoltageThresholdHigh(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetVoltageThresholdLow(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetAutoThresholdEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetAutoThresholdPercent(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetAutoThresholdHysteresis(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetAutoDownRangeTime(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetRange(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetPolaritySelect(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetACCoupleEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetTerminationEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetAveragingTime(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetZeroTorqueSigPhase(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetZeroTorqueSigPhaseToPhaseReading(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetMaxTorqueSigPhase(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetDebounceTime(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetMinimumAmplitude(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SetMinimumFrequency(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_ResetCycleCount(int32_t paramCount, int32_t* p_params);
static void VRChannelMenu_DisplayChannelSetup(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_SaveSetup(int32_t paramCount, int32_t* p_params);
static nai_status_t VRChannelMenu_LoadSetup(int32_t paramCount, int32_t* p_params);

static void VRReadingsMenu_StartDisplayReadingsThread(int32_t* p_params);
#if defined (WIN32)
static void VRReadingsMenu_RunDisplayReadingsThread(void* p_params);
#elif defined (LINUX)
static void VRReadingsMenu_RunDisplayReadingsThread(void* p_params);
#elif defined (__VXWORKS__)
static void VRReadingsMenu_RunDisplayReadingsThread(int * p_params);
#endif
static void VRReadingsMenu_DisplayChannelReadings(int32_t* p_params);
static nai_status_t VRReadingsMenu_ChangeUpdateRate(int32_t paramCount, int32_t* p_params);
static nai_status_t VRReadingsMenu_ContinuePoll(int32_t paramCount, int32_t* p_params);
static nai_status_t VRReadingsMenu_StopPolling(int32_t paramCount, int32_t* p_params);

static void VRTestMenu_DisplayTestSettings(int32_t paramCount, int32_t* p_params);
static nai_status_t VRTestMenu_SetTestEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t VRTestMenu_SetPowerSupplyEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t VRTestMenu_SetFloatingPointEnable(int32_t paramCount, int32_t* p_params);

static void VRStatusMenu_StartDisplayStatusThread(int32_t* p_params);
#if defined (WIN32)
static void VRStatusMenu_RunDisplayStatusThread(void* p_params);
#elif defined (LINUX)
static void VRStatusMenu_RunDisplayStatusThread(void* p_params);
#elif defined (__VXWORKS__)
static void VRStatusMenu_RunDisplayStatusThread(int * p_params);
#endif
static void VRStatusMenu_DisplayStatuses(int32_t* p_params);
static nai_status_t VRStatusMenu_SetChanStatusEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t VRStatusMenu_ClearStatus(int32_t paramCount, int32_t* p_params);
static nai_status_t VRStatusMenu_ChangeUpdateRate(int32_t paramCount, int32_t* p_params);
static nai_status_t VRStatusMenu_ContinuePoll(int32_t paramCount, int32_t* p_params);
static nai_status_t VRStatusMenu_StopPolling(int32_t paramCount, int32_t* p_params);

static long g_ReadingsUpdateRate;
static long g_StatusUpdateRate;
static bool_t g_stopReadingsUpdateThread;
static bool_t g_stopStatusUpdateThread;
static bool_t g_initialReadingsThreadStarted;
static bool_t g_initialStatusThreadStarted;

/****** Command Table *******/
enum vr_basicOps_commands
{
   VR_BASICMENU_CMD_CHANNEL_SETUP_MENU,
   VR_BASICMENU_CMD_DISPLAY_READINGS_MENU,
   VR_BASICMENU_CMD_SYSTEM_TEST_SETUP_MENU,
   VR_BASICMENU_CMD_DISPLAY_MONITOR_STATUS_MENU,
   VR_BASICMENU_CMD_COUNT
};

enum vr_channel_setup_commands
{
   VR_CHANNELMENU_CMD_SET_NUMBER_OF_TEETH,
   VR_CHANNELMENU_CMD_SET_MONOPOLE_DIPOLE_SELECT,
   VR_CHANNELMENU_CMD_SET_CHANNEL_ENABLE,
   VR_CHANNELMENU_CMD_SET_VOLTAGE_THRESHOLD_HIGH,
   VR_CHANNELMENU_CMD_SET_VOLTAGE_THRESHOLD_LOW,
   VR_CHANNELMENU_CMD_SET_AUTO_THRESHOLD_ENABLE,
   VR_CHANNELMENU_CMD_SET_AUTO_THRESHOLD_PERCENT,
   VR_CHANNELMENU_CMD_SET_AUTO_THRESHOLD_HYSTERESIS,
   VR_CHANNELMENU_CMD_SET_AUTO_DOWN_RANGE_TIME,
   VR_CHANNELMENU_CMD_SET_RANGE_SELECT,
   VR_CHANNELMENU_CMD_SET_POLARITY_SELECT,
   VR_CHANNELMENU_CMD_SET_AC_COUPLE_ENABLE,
   VR_CHANNELMENU_CMD_SET_TERMINATION_ENABLE,
   VR_CHANNELMENU_CMD_SET_AVERAGING_TIME,
   VR_CHANNELMENU_CMD_SET_ZERO_TORQUE_SIG_PHASE,
   VR_CHANNELMENU_CMD_SET_ZERO_TORQUE_SIG_PHASE_TO_PHASE_READING,
   VR_CHANNELMENU_CMD_SET_MAX_TORQUE_SIG_PHASE,
   VR_CHANNELMENU_CMD_SET_DEBOUNCE_TIME,
   VR_CHANNELMENU_CMD_SET_MINIMUM_AMPLITUDE,
   VR_CHANNELMENU_CMD_SET_MINIMUM_FREQUENCY,
   VR_CHANNELMENU_CMD_RESET_CYCLE_COUNT,
   VR_CHANNELMENU_CMD_MAIN_MENU,
   VR_CHANNELMENU_CMD_UPDATE,
   VR_CHANNELMENU_CMD_SAVE_SETUP,
   VR_CHANNELMENU_CMD_LOAD_SETUP,
   VR_CHANNELMENU_CMD_COUNT
};

enum vr_readings_commands
{
   VR_READINGSMENU_CMD_MAIN_MENU,
   VR_READINGSMENU_CMD_CHANGE_UPDATE_RATE,
   VR_READINGSMENU_CMD_CONTINUE_POLL,
   VR_READINGSMENU_CMD_STOP_POLLING,
   VR_READINGSMENU_CMD_COUNT
};

enum vr_test_commands
{
   VR_TESTMENU_CMD_MAIN_MENU,
   VR_TESTMENU_CMD_SET_TEST_ENABLE,
   VR_TESTMENU_CMD_SET_POWER_SUPPLY_ENABLE,
   VR_TESTMENU_CMD_SET_FLOATING_POINT_ENABLE,
   VR_TESTMENU_CMD_COUNT
};

enum vr_status_commands
{
   VR_STATUSMENU_CMD_MAIN_MENU,
   VR_STATUSMENU_CMD_SET_CHAN_STATUS_ENABLE,
   VR_STATUSMENU_CMD_CLEAR_STATUS,
   VR_STATUSMENU_CMD_CHANGE_UPDATE_RATE,
   VR_STATUSMENU_CMD_CONTINUE_POLL,
   VR_STATUSMENU_CMD_STOP_POLLING,
   VR_STATUSMENU_CMD_COUNT
};

naiapp_cmdtbl_params_t VR_BasicOpCmds[] = {
   {"CS",  "Channel Set-Up Menu",         VR_BASICMENU_CMD_CHANNEL_SETUP_MENU,          VRBasicMenu_ChannelSetupMenu},
   {"R",   "Display Readings Menu",       VR_BASICMENU_CMD_DISPLAY_READINGS_MENU,       VRBasicMenu_DisplayReadingsMenu},
   {"T",   "System Test Set-Up Menu",     VR_BASICMENU_CMD_SYSTEM_TEST_SETUP_MENU,      VRBasicMenu_SystemTestSetupMenu},
   {"Mon", "Display Monitor/Status Menu", VR_BASICMENU_CMD_DISPLAY_MONITOR_STATUS_MENU, VRBasicMenu_DisplayMonitorStatusMenu}
};

naiapp_cmdtbl_params_t VR_ChannelSetupMenuCmds[] = {
   {"1",  "Number of Teeth",            VR_CHANNELMENU_CMD_SET_NUMBER_OF_TEETH,                        VRChannelMenu_SetNumberOfTeeth},
   {"2",  "Monopole / Dipole",          VR_CHANNELMENU_CMD_SET_MONOPOLE_DIPOLE_SELECT,                 VRChannelMenu_SetMonopoleDipoleSelect},
   {"3",  "Channel Enable",             VR_CHANNELMENU_CMD_SET_CHANNEL_ENABLE,                         VRChannelMenu_SetChannelEnable},
   {"4",  "Voltage Threshold Hi ( V )", VR_CHANNELMENU_CMD_SET_VOLTAGE_THRESHOLD_HIGH,                 VRChannelMenu_SetVoltageThresholdHigh},
   {"5",  "Voltage Threshold Lo ( V )", VR_CHANNELMENU_CMD_SET_VOLTAGE_THRESHOLD_LOW,                  VRChannelMenu_SetVoltageThresholdLow},
   {"6",  "Auto Threshold Enable",      VR_CHANNELMENU_CMD_SET_AUTO_THRESHOLD_ENABLE,                  VRChannelMenu_SetAutoThresholdEnable},
   {"7",  "Auto Threshold Percent",     VR_CHANNELMENU_CMD_SET_AUTO_THRESHOLD_PERCENT,                 VRChannelMenu_SetAutoThresholdPercent},
   {"8",  "Auto Threshold Hysteresis",  VR_CHANNELMENU_CMD_SET_AUTO_THRESHOLD_HYSTERESIS,              VRChannelMenu_SetAutoThresholdHysteresis},
   {"9",  "Auto Down-Range Time",       VR_CHANNELMENU_CMD_SET_AUTO_DOWN_RANGE_TIME,                   VRChannelMenu_SetAutoDownRangeTime},
   {"10", "Range Select",               VR_CHANNELMENU_CMD_SET_RANGE_SELECT,                           VRChannelMenu_SetRange},
   {"11", "Polarity Select",            VR_CHANNELMENU_CMD_SET_POLARITY_SELECT,                        VRChannelMenu_SetPolaritySelect},
   {"12", "AC Couple Enable",           VR_CHANNELMENU_CMD_SET_AC_COUPLE_ENABLE,                       VRChannelMenu_SetACCoupleEnable},
   {"13", "Termination Enable",         VR_CHANNELMENU_CMD_SET_TERMINATION_ENABLE,                     VRChannelMenu_SetTerminationEnable},
   {"14", "Averaging Time ( Sec )",     VR_CHANNELMENU_CMD_SET_AVERAGING_TIME,                         VRChannelMenu_SetAveragingTime},
   {"15", "Zero Torque Sig Phase",      VR_CHANNELMENU_CMD_SET_ZERO_TORQUE_SIG_PHASE,                  VRChannelMenu_SetZeroTorqueSigPhase},
   {"16", "Set Zero Torque Sig Phase",  VR_CHANNELMENU_CMD_SET_ZERO_TORQUE_SIG_PHASE_TO_PHASE_READING, VRChannelMenu_SetZeroTorqueSigPhaseToPhaseReading},
   {"17", "Max Torque Sig Phase",       VR_CHANNELMENU_CMD_SET_MAX_TORQUE_SIG_PHASE,                   VRChannelMenu_SetMaxTorqueSigPhase},
   {"18", "Debounce Time ( Sec )",      VR_CHANNELMENU_CMD_SET_DEBOUNCE_TIME,                          VRChannelMenu_SetDebounceTime},
   {"19", "Minimum Amplitude ( V )",    VR_CHANNELMENU_CMD_SET_MINIMUM_AMPLITUDE,                      VRChannelMenu_SetMinimumAmplitude},
   {"20", "Minimum Frequency ( Hz )",   VR_CHANNELMENU_CMD_SET_MINIMUM_FREQUENCY,                      VRChannelMenu_SetMinimumFrequency},
   {"R",  "Reset Cycle Count",          VR_CHANNELMENU_CMD_RESET_CYCLE_COUNT,                          VRChannelMenu_ResetCycleCount},
   {"MM", "Return to Main Menu",        VR_CHANNELMENU_CMD_MAIN_MENU,                                  NULL},
   {"UD", "Update",                     VR_CHANNELMENU_CMD_UPDATE,                                     NULL},
   {"S",  "Save Setup",                 VR_CHANNELMENU_CMD_SAVE_SETUP,                                 VRChannelMenu_SaveSetup},
   {"L",  "Load Setup",                 VR_CHANNELMENU_CMD_LOAD_SETUP,                                 VRChannelMenu_LoadSetup}
};

naiapp_cmdtbl_params_t VR_ChannelReadingsMenuCmds[] = {
   {"MM", "Return to Main Menu",                                 VR_READINGSMENU_CMD_MAIN_MENU,          NULL},
   {"R",  "Change Update Rate in milliSeconds [default:1000mS]", VR_READINGSMENU_CMD_CHANGE_UPDATE_RATE, VRReadingsMenu_ChangeUpdateRate},
   {"C",  "Continue Poll",                                       VR_READINGSMENU_CMD_CONTINUE_POLL,      VRReadingsMenu_ContinuePoll},
   {"S",  "Stop Polling",                                        VR_READINGSMENU_CMD_STOP_POLLING,       VRReadingsMenu_StopPolling}
};

naiapp_cmdtbl_params_t VR_TestMenuCmds[] = {
   {"MM", "Return to Main Menu",   VR_TESTMENU_CMD_MAIN_MENU,                 NULL},
   {"TE", "Test Enable",           VR_TESTMENU_CMD_SET_TEST_ENABLE,           VRTestMenu_SetTestEnable},
   {"PS", "Power Supply Enable",   VR_TESTMENU_CMD_SET_POWER_SUPPLY_ENABLE,   VRTestMenu_SetPowerSupplyEnable},
   {"FE", "Floating-Point Enable", VR_TESTMENU_CMD_SET_FLOATING_POINT_ENABLE, VRTestMenu_SetFloatingPointEnable}
};

naiapp_cmdtbl_params_t VR_StatusMenuCmds[] = {
   {"MM", "Return to Main Menu",                                VR_STATUSMENU_CMD_MAIN_MENU,              NULL},
   {"E",  "Channel Status Enable",                              VR_STATUSMENU_CMD_SET_CHAN_STATUS_ENABLE, VRStatusMenu_SetChanStatusEnable},
   {"C",  "Clear Status",                                       VR_STATUSMENU_CMD_CLEAR_STATUS,           VRStatusMenu_ClearStatus},
   {"R",  "Change Update Rate in milliSeconds [default:1000mS]", VR_STATUSMENU_CMD_CHANGE_UPDATE_RATE,     VRStatusMenu_ChangeUpdateRate},
   {"P",  "Continue Poll",                                      VR_STATUSMENU_CMD_CONTINUE_POLL,          VRStatusMenu_ContinuePoll},
   {"S",  "Stop Polling",                                       VR_STATUSMENU_CMD_STOP_POLLING,           VRStatusMenu_StopPolling}
};

/*****************************************************************************/
/**
<summary>
The purpose of the VR_BasicOps is to illustrate the methods to call in the
naibrd library to perform basic operations with the VR 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 VR routines.
 - ConfigDevice
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - CheckModule
</summary>
*/
/*****************************************************************************/
#if defined (__VXWORKS__)
int32_t VR_BasicOps(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;

   g_ReadingsUpdateRate = 1000;
   g_StatusUpdateRate = 1000;
   g_stopReadingsUpdateThread = TRUE;
   g_stopStatusUpdateThread = TRUE;
   g_initialReadingsThreadStarted = FALSE;
   g_initialStatusThreadStarted = FALSE;

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

            /* Query the user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  VRBasicMenu_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>
VRBasicMenu_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 VRBasicMenu_Run(int32_t cardIndex, int32_t module, uint32_t modid)
{
   bool_t bQuit = FALSE;
   bool_t bCmdFound = FALSE;
   int32_t cmd;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   int32_t MAX_CHANNELS = 0;

   naiapp_AppParameters_t  VR_basicOps_params;
   p_naiapp_AppParameters_t p_VR_basicOps_params = &VR_basicOps_params;
   p_VR_basicOps_params->cardIndex = cardIndex;
   p_VR_basicOps_params->module = module;
   p_VR_basicOps_params->modId = modid;
   MAX_CHANNELS = naibrd_VR_GetChannelCount(modid);
   p_VR_basicOps_params->maxChannels = MAX_CHANNELS;

   do
   {
      g_initialReadingsThreadStarted = FALSE;
      g_initialStatusThreadStarted = FALSE;
      g_stopReadingsUpdateThread = TRUE;
      g_stopStatusUpdateThread = TRUE;
      naiapp_utils_LoadParamMenuCommands(VR_BASICMENU_CMD_COUNT, VR_BasicOpCmds);
      naiapp_display_ParamMenuCommands((int8_t*)"VR Basic Operations");
      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))
      {
         bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
         if (bCmdFound)
         {
            VR_BasicOpCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)p_VR_basicOps_params);
         }
         else
         {
            printf(" Invalid command entered\n");
         }
      }
   } while (!bQuit);
   return bQuit;
}

static nai_status_t VRBasicMenu_ChannelSetupMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t bCancelCmd = FALSE;
   bool_t bCmdFound = FALSE;
   int32_t cmd = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt = 0;
   p_naiapp_AppParameters_t p_VR_basicOps_params = (p_naiapp_AppParameters_t)p_params;
   int32_t MAX_CHANNELS = p_VR_basicOps_params->maxChannels;

   do
   {
      naiapp_utils_LoadParamMenuCommands(VR_CHANNELMENU_CMD_COUNT, VR_ChannelSetupMenuCmds);
      VRChannelMenu_DisplayChannelSetup(paramCount, p_params);
      printf("\n>Please Enter Channel Setup Menu command or %c to quit (commands are listed to the left of each option, and numbers are included as commands): ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
         if (bCmdFound)
         {
            if ((cmd != VR_CHANNELMENU_CMD_MAIN_MENU) && (cmd != VR_CHANNELMENU_CMD_UPDATE) && (cmd != VR_CHANNELMENU_CMD_SAVE_SETUP) &&
                (cmd != VR_CHANNELMENU_CMD_LOAD_SETUP))
            {
               printf("\nType 'a' or 'A' to apply command to all channels, or type 's' or 'S' to select a channel: ");
               bCancelCmd = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               if ((!bCancelCmd) && (inputResponseCnt > 0))
               {
                  if ((toupper(inputBuffer[0]) == 'A') || (toupper(inputBuffer[0]) == 'S'))
                  {
                     if (toupper(inputBuffer[0]) == 'A')
                     {
                        p_VR_basicOps_params->channel = 0;
                     }
                     else
                     {
                        naiapp_query_ChannelNumber(MAX_CHANNELS, 1, &(p_VR_basicOps_params->channel));
                     }
                  }
                  else
                  {
                     bCancelCmd = TRUE;
                     printf("\nInvalid option entered\n");
                  }
               }
               else
               {
                  bCancelCmd = TRUE;
               }
            }
            if (cmd == VR_CHANNELMENU_CMD_MAIN_MENU)
            {
               bQuit = TRUE;
            }
            else if (cmd != VR_CHANNELMENU_CMD_UPDATE)
            {
               if (!bCancelCmd)
               {
                  VR_ChannelSetupMenuCmds[cmd].func(paramCount, (int32_t*)p_VR_basicOps_params);
               }
               else
               {
                  bCancelCmd = FALSE;
               }
            }
         }
         else
         {
            printf("Invalid command entered\n");
         }
      }
   } while (!bQuit);

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRBasicMenu_DisplayReadingsMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t bCmdFound = FALSE;
   int32_t cmd = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt = 0;

   do
   {
      naiapp_utils_LoadParamMenuCommands(VR_READINGSMENU_CMD_COUNT, VR_ChannelReadingsMenuCmds);
      if (g_initialReadingsThreadStarted == FALSE)
      {
         VRReadingsMenu_StartDisplayReadingsThread(p_params);
         g_initialReadingsThreadStarted = TRUE;
      }
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
         if (bCmdFound)
         {
            if (cmd == VR_READINGSMENU_CMD_MAIN_MENU)
            {
               g_stopReadingsUpdateThread = TRUE;
               bQuit = TRUE;
            }
            else
            {
               VR_ChannelReadingsMenuCmds[cmd].func(paramCount, p_params);
            }
         }
         else
         {
            printf("Invalid command entered\n");
         }
      }
   } while (!bQuit);

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRBasicMenu_SystemTestSetupMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t bCmdFound = FALSE;
   int32_t cmd = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt = 0;

   do
   {
      naiapp_utils_LoadParamMenuCommands(VR_TESTMENU_CMD_COUNT, VR_TestMenuCmds);
      VRTestMenu_DisplayTestSettings(paramCount, p_params);
      printf("\n>Please Enter Test Menu command or %c to quit : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
         if (bCmdFound)
         {
            if (cmd == VR_TESTMENU_CMD_MAIN_MENU)
            {
               bQuit = TRUE;
            }
            else
            {
               VR_TestMenuCmds[cmd].func(paramCount, p_params);
            }
         }
         else
         {
            printf("Invalid command entered\n");
         }
      }
   } while (!bQuit);

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRBasicMenu_DisplayMonitorStatusMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t bCancelCmd = FALSE;
   bool_t bCmdFound = FALSE;
   int32_t cmd = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt = 0;
   p_naiapp_AppParameters_t p_VR_basicOps_params = (p_naiapp_AppParameters_t)p_params;
   int32_t MAX_CHANNELS = p_VR_basicOps_params->maxChannels;

   do
   {
      naiapp_utils_LoadParamMenuCommands(VR_STATUSMENU_CMD_COUNT, VR_StatusMenuCmds);
      if (g_initialStatusThreadStarted == FALSE)
      {
         VRStatusMenu_StartDisplayStatusThread(p_params);
         g_initialStatusThreadStarted = TRUE;
      }
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
         if (bCmdFound)
         {
            if ((cmd == VR_STATUSMENU_CMD_SET_CHAN_STATUS_ENABLE) || (cmd == VR_STATUSMENU_CMD_CLEAR_STATUS))
            {
               VRStatusMenu_StopPolling(paramCount, p_params);
               printf("\nType 'a' or 'A' to apply command to all channels, or type 's' or 'S' to select a channel: ");
               bCancelCmd = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               if ((!bCancelCmd) && (inputResponseCnt > 0))
               {
                  if ((toupper(inputBuffer[0]) == 'A') || (toupper(inputBuffer[0]) == 'S'))
                  {
                     if (toupper(inputBuffer[0]) == 'A')
                     {
                        p_VR_basicOps_params->channel = 0;
                     }
                     else
                     {
                        naiapp_query_ChannelNumber(MAX_CHANNELS, 1, &(p_VR_basicOps_params->channel));
                     }
                  }
                  else
                  {
                     bCancelCmd = TRUE;
                     printf("\nInvalid option entered\n");
                     VRStatusMenu_ContinuePoll(paramCount, p_params);
                  }
               }
               else
               {
                  bCancelCmd = TRUE;
                  VRStatusMenu_ContinuePoll(paramCount, p_params);
               }
            }
            if (cmd == VR_STATUSMENU_CMD_MAIN_MENU)
            {
               g_stopStatusUpdateThread = TRUE;
               bQuit = TRUE;
            }
            else
            {
               if (!bCancelCmd)
               {
                  VR_StatusMenuCmds[cmd].func(paramCount, (int32_t*)p_VR_basicOps_params);
               }
               else
               {
                  bCancelCmd = FALSE;
               }
            }
         }
         else
         {
            printf("Invalid command entered\n");
         }
      }
   } while (!bQuit);

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}


static nai_status_t VRChannelMenu_SetNumberOfTeeth(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t numberOfTeeth = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Number Of Teeth value to set: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      numberOfTeeth = atof((const char*)inputBuffer);
      if (numberOfTeeth == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_NUMBER_OF_TEETH, numberOfTeeth));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_NUMBER_OF_TEETH, numberOfTeeth));
            }
         }
         else
         {
            printf("\nInvalid Number Of Teeth value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_NUMBER_OF_TEETH, numberOfTeeth));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_NUMBER_OF_TEETH, numberOfTeeth));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetMonopoleDipoleSelect(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enableDipole = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Enter Monopole/Dipole setting to set (0 for monopole, 1 for dipole): ");
   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')
         {
            enableDipole = TRUE;
         }
         else
         {
            enableDipole = FALSE;
         }
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
                                                           NAI_VR_CHAN_MAPPED_CONTROL_DIPOLE_ENABLE, enableDipole));
            }
         }
         else
         {
            check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_DIPOLE_ENABLE,
                                                        enableDipole));
         }
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetChannelEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enable = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   if (channel == 0)
   {
      printf("Do you want to enable or disable all channels? (1 to enable, 0 to disable): ");
   }
   else
   {
      printf("Do you want to enable or disable channel %d? (1 to enable, 0 to disable): ", channel);
   }
   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 = TRUE;
         }
         else
         {
            enable = FALSE;
         }
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_CHANNEL_ENABLE, enable));
            }
         }
         else
         {
            check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_CHANNEL_ENABLE, enable));
         }
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetVoltageThresholdHigh(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t voltThresHigh = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Voltage High Threshold Value to set (in V): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      voltThresHigh = atof((const char*)inputBuffer);
      if (voltThresHigh == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_HIGH, voltThresHigh));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_HIGH, voltThresHigh));
            }
         }
         else
         {
            printf("\nInvalid Voltage High Threshold value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_HIGH, voltThresHigh));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_HIGH, voltThresHigh));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetVoltageThresholdLow(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t voltThresLow = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Voltage Low Threshold Value to set (in V): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      voltThresLow = atof((const char*)inputBuffer);
      if (voltThresLow == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_LOW, voltThresLow));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_LOW, voltThresLow));
            }
         }
         else
         {
            printf("\nInvalid Voltage Low Threshold value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_LOW, voltThresLow));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_LOW, voltThresLow));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetAutoThresholdEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enable = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Do you want to enable or disable automatic threshold levels? (1 to enable, 0 to disable): ");
   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 = TRUE;
         }
         else
         {
            enable = FALSE;
         }
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_AUTO_THRESHOLD_ENABLE,
                                                           enable));
            }
         }
         else
         {
            check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_AUTO_THRESHOLD_ENABLE,
                                                        enable));
         }
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetAutoThresholdPercent(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t autoThresholdPercent = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Automatic Threshold Percent Value to set: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      autoThresholdPercent = atof((const char*)inputBuffer);
      if (autoThresholdPercent == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AUTO_THRESHOLD_PERCENT,
                                                        autoThresholdPercent));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AUTO_THRESHOLD_PERCENT,
                                                     autoThresholdPercent));
            }
         }
         else
         {
            printf("\nInvalid Automatic Threshold Percent value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AUTO_THRESHOLD_PERCENT,
                                                     autoThresholdPercent));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AUTO_THRESHOLD_PERCENT,
                                                  autoThresholdPercent));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetAutoThresholdHysteresis(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t autoThresholdHysteresis = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Automatic Threshold Hysteresis Value to set (%%): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      autoThresholdHysteresis = atof((const char*)inputBuffer);
      if (autoThresholdHysteresis == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AUTO_THRESHOLD_HYSTERESIS,
                                                        autoThresholdHysteresis));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AUTO_THRESHOLD_HYSTERESIS,
                                                     autoThresholdHysteresis));
            }
         }
         else
         {
            printf("\nInvalid Automatic Threshold Hysteresis value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AUTO_THRESHOLD_HYSTERESIS,
                                                     autoThresholdHysteresis));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AUTO_THRESHOLD_HYSTERESIS,
                                                  autoThresholdHysteresis));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetAutoDownRangeTime(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Enter Auto Down-Range Time selection to set (0 for 100ms, 1 for 500ms, 2 for 1s, 3 for 2s, 4 for 5s, 5 for 10s): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      if (channel == 0)
      {
         for (channel = 1; channel <= MAX_CHANNELS; channel++)
         {
            switch (inputBuffer[0])
            {
               case '0':
                  check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_100MS));
               break;
               case '1':
                  check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_500MS));
               break;
               case '2':
                  check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_1S));
               break;
               case '3':
                  check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_2S));
               break;
               case '4':
                  check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_5S));
               break;
               case '5':
                  check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_10S));
               break;
               default:
                  printf("\nInvalid Selection Entered\n");
               break;
            }
         }
      }
      else
      {
         switch (inputBuffer[0])
         {
            case '0':
               check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_100MS));
            break;
            case '1':
               check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_500MS));
            break;
            case '2':
               check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_1S));
            break;
            case '3':
               check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_2S));
            break;
            case '4':
               check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_5S));
            break;
            case '5':
               check_status(naibrd_VR_SetAutoDownRangeTime(cardIndex, module, channel, NAI_VR_AUTO_DOWN_RANGE_TIME_10S));
            break;
            default:
               printf("\nInvalid Selection Entered\n");
            break;
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetRange(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Enter Range selection to set (0 for Auto, 1 for 50mV, 2 for 100mV, 3 for 250mV, 4 for 500mV, ");
   printf("5 for 1V, 6 for 2.5V, 7 for 5V, 8 for 12.5V, 9 for 25V, A for 50V, B for 100V): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      if (channel == 0)
      {
         for (channel = 1; channel <= MAX_CHANNELS; channel++)
         {
            switch (inputBuffer[0])
            {
               case '0':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_AUTO));
               break;
               case '1':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_50mV));
               break;
               case '2':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_100mV));
               break;
               case '3':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_250mV));
               break;
               case '4':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_500mV));
               break;
               case '5':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_1V));
               break;
               case '6':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_2P5V));
               break;
               case '7':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_5V));
               break;
               case '8':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_12P5V));
               break;
               case '9':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_25V));
               break;
               case 'A':
               case 'a':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_50V));
               break;
               case 'B':
               case 'b':
                  check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_100V));
               break;
               default:
                  printf("\nInvalid Selection Entered\n");
               break;
            }
         }
      }
      else
      {
         switch (inputBuffer[0])
         {
            case '0':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_AUTO));
            break;
            case '1':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_50mV));
            break;
            case '2':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_100mV));
            break;
            case '3':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_250mV));
            break;
            case '4':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_500mV));
            break;
            case '5':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_1V));
            break;
            case '6':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_2P5V));
            break;
            case '7':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_5V));
            break;
            case '8':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_12P5V));
            break;
            case '9':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_25V));
            break;
            case 'A':
            case 'a':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_50V));
            break;
            case 'B':
            case 'b':
               check_status(naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_100V));
            break;
            default:
               printf("\nInvalid Selection Entered\n");
            break;
         }
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetPolaritySelect(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enableFallingEdgeMeas = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Enter signal edge on which to take measurements (0 for rising edge, 1 for falling edge): ");
   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')
         {
            enableFallingEdgeMeas = TRUE;
         }
         else
         {
            enableFallingEdgeMeas = FALSE;
         }
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
                                                           NAI_VR_CHAN_MAPPED_CONTROL_FALLING_EDGE_MEASUREMENT_ENABLE,
                                                           enableFallingEdgeMeas));
            }
         }
         else
         {
            check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
                                                        NAI_VR_CHAN_MAPPED_CONTROL_FALLING_EDGE_MEASUREMENT_ENABLE, enableFallingEdgeMeas));
         }
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetACCoupleEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enable = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Do you want to enable or disable AC couple? (1 to enable, 0 to disable): ");
   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 = TRUE;
         }
         else
         {
            enable = FALSE;
         }
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_AC_COUPLE_ENABLE,
                                                           enable));
            }
         }
         else
         {
            check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_AC_COUPLE_ENABLE, enable));
         }
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetTerminationEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enable = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Do you want to enable or disable termination? (1 to enable, 0 to disable): ");
   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 = TRUE;
         }
         else
         {
            enable = FALSE;
         }
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_TERMINATION_ENABLE,
                                                           enable));
            }
         }
         else
         {
            check_status(naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_TERMINATION_ENABLE, enable));
         }
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetAveragingTime(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t averagingTime = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Averaging Time Value to set (in seconds): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      averagingTime = atof((const char*)inputBuffer);
      if (averagingTime == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AVERAGING_TIME, averagingTime));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AVERAGING_TIME, averagingTime));
            }
         }
         else
         {
            printf("\nInvalid Averaging Time value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AVERAGING_TIME, averagingTime));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_AVERAGING_TIME, averagingTime));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetZeroTorqueSigPhase(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t zeroTorqueSigPhase = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Zero Torque Signal Phase Value to set (in degrees): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      zeroTorqueSigPhase = atof((const char*)inputBuffer);
      if (zeroTorqueSigPhase == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_ZERO_TORQUE_SIGNAL_PHASE,
                                                        zeroTorqueSigPhase));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_ZERO_TORQUE_SIGNAL_PHASE,
                                                     zeroTorqueSigPhase));
            }
         }
         else
         {
            printf("\nInvalid Zero Torque Signal Phase value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_ZERO_TORQUE_SIGNAL_PHASE,
                                                     zeroTorqueSigPhase));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_ZERO_TORQUE_SIGNAL_PHASE, zeroTorqueSigPhase));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetZeroTorqueSigPhaseToPhaseReading(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Are you sure you want to set the zero torque signal phase to the current phase reading? (Y for Yes, N for No): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      if ((toupper(inputBuffer[0]) == 'Y') || (toupper(inputBuffer[0]) == 'N'))
      {
         if (toupper(inputBuffer[0]) == 'Y')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetZeroTorqueSignalPhaseToPhaseReading(cardIndex, module, channel));
               }
            }
            else
            {
               check_status(naibrd_VR_SetZeroTorqueSignalPhaseToPhaseReading(cardIndex, module, channel));
            }
         }
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetMaxTorqueSigPhase(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t maxTorqueSigPhase = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Max Torque Signal Phase Value to set (in degrees): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      maxTorqueSigPhase = atof((const char*)inputBuffer);
      if (maxTorqueSigPhase == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MAX_TORQUE_SIGNAL_PHASE,
                                                        maxTorqueSigPhase));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MAX_TORQUE_SIGNAL_PHASE,
                                                     maxTorqueSigPhase));
            }
         }
         else
         {
            printf("\nInvalid Max Torque Signal Phase value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MAX_TORQUE_SIGNAL_PHASE,
                                                     maxTorqueSigPhase));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MAX_TORQUE_SIGNAL_PHASE, maxTorqueSigPhase));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetDebounceTime(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t debounceTime = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Debounce Time Value to set (in seconds): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      debounceTime = atof((const char*)inputBuffer);
      if (debounceTime == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_DEBOUNCE_TIME, debounceTime));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_DEBOUNCE_TIME, debounceTime));
            }
         }
         else
         {
            printf("\nInvalid Debounce Time value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_DEBOUNCE_TIME, debounceTime));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_DEBOUNCE_TIME, debounceTime));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetMinimumAmplitude(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t minAmplitude = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Minimum Amplitude Value to set (in V): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      minAmplitude = atof((const char*)inputBuffer);
      if (minAmplitude == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MINIMUM_AMPLITUDE, minAmplitude));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MINIMUM_AMPLITUDE, minAmplitude));
            }
         }
         else
         {
            printf("\nInvalid Minimum Amplitude value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MINIMUM_AMPLITUDE, minAmplitude));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MINIMUM_AMPLITUDE, minAmplitude));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_SetMinimumFrequency(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t minFreq = 0.0;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Type Minimum Frequency Value to set (in Hz): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      minFreq = atof((const char*)inputBuffer);
      if (minFreq == 0.0)
      {
         if (inputBuffer[0] == '0')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MINIMUM_FREQUENCY, minFreq));
               }
            }
            else
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MINIMUM_FREQUENCY, minFreq));
            }
         }
         else
         {
            printf("\nInvalid Minimum Frequency value entered\n");
         }
      }
      else
      {
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MINIMUM_FREQUENCY, minFreq));
            }
         }
         else
         {
            check_status(naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MINIMUM_FREQUENCY, minFreq));
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_ResetCycleCount(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Are you sure you want to reset the cycle count? (Y for Yes, N for No): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      if ((toupper(inputBuffer[0]) == 'Y') || (toupper(inputBuffer[0]) == 'N'))
      {
         if (toupper(inputBuffer[0]) == 'Y')
         {
            if (channel == 0)
            {
               for (channel = 1; channel <= MAX_CHANNELS; channel++)
               {
                  check_status(naibrd_VR_ResetCycleCount(cardIndex, module, channel));
               }
            }
            else
            {
               check_status(naibrd_VR_ResetCycleCount(cardIndex, module, channel));
            }
         }
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static void VRChannelMenu_DisplayChannelSetup(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_VR_basicOps_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIdx = p_VR_basicOps_params->cardIndex;
   int32_t modNum = p_VR_basicOps_params->module;
   int32_t chanNum = 1;
   int32_t MAX_CHANNELS = p_VR_basicOps_params->maxChannels;
   float64_t numberOfTeeth = 0.0;
   bool_t monopoleDipole = FALSE;
   bool_t channelEnable = FALSE;
   float64_t voltThresHi = 0.0;
   float64_t voltThresLo = 0.0;
   bool_t autoThresholdEnable = FALSE;
   float64_t autoThresholdPercent = 0.0;
   float64_t autoThresholdHysteresis = 0.0;
   nai_vr_auto_down_range_time_type_t autoDownRangeTime = NAI_VR_AUTO_DOWN_RANGE_TIME_100MS;
   nai_vr_range_select_type_t rangeSelect = NAI_VR_RANGE_AUTO;
   bool_t polaritySelect = FALSE;
   bool_t acCoupleEnable = FALSE;
   bool_t terminationEnable = FALSE;
   float64_t averagingTime = 0.0;
   float64_t zeroTorqueSigPhase = 0.0;
   bool_t setZeroTorqueSigPhase = FALSE;
   float64_t maxTorqueSigPhase = 0.0;
   float64_t debounceTime = 0.0;
   float64_t minAmplitude = 0.0;
   float64_t minFreq = 0.0;
   char strMonopoleDipole[10] = "";
   char strChannelEnable[10] = "";
   char strRangeSelect[10] = "";
   char strPolaritySelect[10] = "";
   char strACCoupleEnable[10] = "";
   char strTerminationEnable[10] = "";
   char strSetZeroTorqueSigPhase[10] = "";
   char strAutoThresholdEnable[10] = "";
   char strAutoDownRangeTime[10] = "";

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

   printf("\n    Channel Setup Group Menu           Ch 1          Ch 2          Ch 3          Ch 4          Ch 5          Ch 6          ");
   printf("Ch 7          Ch 8\n\n");
   printf(" 1    Number of Teeth      ");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_NUMBER_OF_TEETH, &numberOfTeeth));
      printf("%14d", (int32_t)(numberOfTeeth + 0.5));
   }
   printf("\n 2    Monopole / Dipole    ");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetChanMappedControl(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_CONTROL_DIPOLE_ENABLE,
                                                  &monopoleDipole));
      switch (monopoleDipole)
      {
         case TRUE:
            sprintf(strMonopoleDipole, "D");
         break;
         case FALSE:
            sprintf(strMonopoleDipole, "M");
         break;
         default:
            sprintf(strMonopoleDipole, "Unknown");
         break;
      }
      printf("%14s", strMonopoleDipole);
   }
   printf("\n 3    Channel Enable       ");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetChanMappedControl(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_CONTROL_CHANNEL_ENABLE, &channelEnable));
      switch (channelEnable)
      {
         case TRUE:
            sprintf(strChannelEnable, "On");
         break;
         case FALSE:
            sprintf(strChannelEnable, "Off");
         break;
         default:
            sprintf(strChannelEnable, "Unknown");
         break;
      }
      printf("%14s", strChannelEnable);
   }
   printf("\n 4    Voltage Threshold Hi ( V )");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_HIGH, &voltThresHi));
      if (chanNum == 1)
      {
         printf("%9.3f", voltThresHi);
      }
      else
      {
         printf("%14.3f", voltThresHi);
      }
   }
   printf("\n 5    Voltage Threshold Lo ( V )");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_VOLTAGE_THRESHOLD_LOW, &voltThresLo));
      if (chanNum == 1)
      {
         printf("%9.3f", voltThresLo);
      }
      else
      {
         printf("%14.3f", voltThresLo);
      }
   }
   printf("\n 6    Auto Threshold Enable");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetChanMappedControl(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_CONTROL_AUTO_THRESHOLD_ENABLE,
                                                  &autoThresholdEnable));
      switch (autoThresholdEnable)
      {
         case TRUE:
            sprintf(strAutoThresholdEnable, "On");
         break;
         case FALSE:
            sprintf(strAutoThresholdEnable, "Off");
         break;
         default:
            sprintf(strAutoThresholdEnable, "Unknown");
         break;
      }
      printf("%14s", strAutoThresholdEnable);
   }
   printf("\n 7    Auto Threshold Percent");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_AUTO_THRESHOLD_PERCENT, &autoThresholdPercent));
      if (chanNum == 1)
      {
         printf("%13.3f", autoThresholdPercent);
      }
      else
      {
         printf("%14.3f", autoThresholdPercent);
      }
   }
   printf("\n 8    Auto Threshold Hysteresis (%%)");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_AUTO_THRESHOLD_HYSTERESIS, &autoThresholdHysteresis));
      if (chanNum == 1)
      {
         printf("%6.3f", autoThresholdHysteresis);
      }
      else
      {
         printf("%14.3f", autoThresholdHysteresis);
      }
   }
   printf("\n 9    Auto Down-Range Time ");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetAutoDownRangeTime(cardIdx, modNum, chanNum, &autoDownRangeTime));
      switch (autoDownRangeTime)
      {
         case NAI_VR_AUTO_DOWN_RANGE_TIME_100MS:
            sprintf(strAutoDownRangeTime, "100ms");
         break;
         case NAI_VR_AUTO_DOWN_RANGE_TIME_500MS:
            sprintf(strAutoDownRangeTime, "500ms");
         break;
         case NAI_VR_AUTO_DOWN_RANGE_TIME_1S:
            sprintf(strAutoDownRangeTime, "1s");
         break;
         case NAI_VR_AUTO_DOWN_RANGE_TIME_2S:
            sprintf(strAutoDownRangeTime, "2s");
         break;
         case NAI_VR_AUTO_DOWN_RANGE_TIME_5S:
            sprintf(strAutoDownRangeTime, "5s");
         break;
         case NAI_VR_AUTO_DOWN_RANGE_TIME_10S:
            sprintf(strAutoDownRangeTime, "10s");
         break;
         case NAI_VR_AUTO_DOWN_RANGE_TIME_TYPE_ENUM_COUNT:
         default:
            sprintf(strAutoDownRangeTime, "Unknown");
         break;
      }
      printf("%14s", strAutoDownRangeTime);
   }
   printf("\n 10   Range Select         ");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetRangeSelect(cardIdx, modNum, chanNum, &rangeSelect));
      switch (rangeSelect)
      {
         case NAI_VR_RANGE_AUTO:
            sprintf(strRangeSelect, "Auto");
         break;
         case NAI_VR_RANGE_50mV:
            sprintf(strRangeSelect, "50mV");
         break;
         case NAI_VR_RANGE_100mV:
            sprintf(strRangeSelect, "100mV");
         break;
         case NAI_VR_RANGE_250mV:
            sprintf(strRangeSelect, "250mV");
         break;
         case NAI_VR_RANGE_500mV:
            sprintf(strRangeSelect, "500mV");
         break;
         case NAI_VR_RANGE_1V:
            sprintf(strRangeSelect, "1V");
         break;
         case NAI_VR_RANGE_2P5V:
            sprintf(strRangeSelect, "2.5V");
         break;
         case NAI_VR_RANGE_5V:
            sprintf(strRangeSelect, "5V");
         break;
         case NAI_VR_RANGE_12P5V:
            sprintf(strRangeSelect, "12.5V");
         break;
         case NAI_VR_RANGE_25V:
            sprintf(strRangeSelect, "25V");
         break;
         case NAI_VR_RANGE_50V:
            sprintf(strRangeSelect, "50V");
         break;
         case NAI_VR_RANGE_100V:
            sprintf(strRangeSelect, "100V");
         break;
         default:
            sprintf(strRangeSelect, "Unknown");
         break;
      }
      printf("%14s", strRangeSelect);
   }
   printf("\n 11   Polarity Select      ");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetChanMappedControl(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_CONTROL_FALLING_EDGE_MEASUREMENT_ENABLE,
                                                  &polaritySelect));
      switch (polaritySelect)
      {
         case TRUE:
            sprintf(strPolaritySelect, "Falling");
         break;
         case FALSE:
            sprintf(strPolaritySelect, "Rising");
         break;
         default:
            sprintf(strPolaritySelect, "Unknown");
         break;
      }
      printf("%14s", strPolaritySelect);
   }
   printf("\n 12   AC Couple Enable     ");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetChanMappedControl(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_CONTROL_AC_COUPLE_ENABLE, &acCoupleEnable));
      switch (acCoupleEnable)
      {
         case TRUE:
            sprintf(strACCoupleEnable, "On");
         break;
         case FALSE:
            sprintf(strACCoupleEnable, "Off");
         break;
         default:
            sprintf(strACCoupleEnable, "Unknown");
         break;
      }
      printf("%14s", strACCoupleEnable);
   }
   printf("\n 13   Termination Enable   ");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetChanMappedControl(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_CONTROL_TERMINATION_ENABLE,
                                                  &terminationEnable));
      switch (terminationEnable)
      {
         case TRUE:
            sprintf(strTerminationEnable, "On");
         break;
         case FALSE:
            sprintf(strTerminationEnable, "Off");
         break;
         default:
            sprintf(strTerminationEnable, "Unknown");
         break;
      }
      printf("%14s", strTerminationEnable);
   }
   printf("\n 14   Averaging Time ( Sec )");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_AVERAGING_TIME, &averagingTime));
      if (chanNum == 1)
      {
         printf("%13.3f", averagingTime);
      }
      else
      {
         printf("%14.3f", averagingTime);
      }
   }
   printf("\n 15   Zero Torque Sig Phase");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_ZERO_TORQUE_SIGNAL_PHASE, &zeroTorqueSigPhase));
      printf("%14.3f", zeroTorqueSigPhase);
   }
   printf("\n 16   Set Zero Torque Sig Phase");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetZeroTorqueSignalPhaseToPhaseReading(cardIdx, modNum, chanNum, &setZeroTorqueSigPhase));
      switch (setZeroTorqueSigPhase)
      {
         case TRUE:
            sprintf(strSetZeroTorqueSigPhase, "Set");
         break;
         case FALSE:
            sprintf(strSetZeroTorqueSigPhase, "Unset");
         break;
         default:
            sprintf(strSetZeroTorqueSigPhase, "Unknown");
         break;
      }
      if (chanNum == 1)
      {
         printf("%10s", strSetZeroTorqueSigPhase);
      }
      else
      {
         printf("%14s", strSetZeroTorqueSigPhase);
      }
   }
   printf("\n 17   Max Torque Sig Phase ");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_MAX_TORQUE_SIGNAL_PHASE, &maxTorqueSigPhase));
      printf("%14.3f", maxTorqueSigPhase);
   }
   printf("\n 18   Debounce Time ( Sec )");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_DEBOUNCE_TIME, &debounceTime));
      printf("%14.2E", debounceTime);
   }
   printf("\n 19   Minimum Amplitude ( V )");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_MINIMUM_AMPLITUDE, &minAmplitude));
      if (chanNum == 1)
      {
         printf("%12.3f", minAmplitude);
      }
      else
      {
         printf("%14.3f", minAmplitude);
      }
   }
   printf("\n 20   Minimum Frequency ( Hz )");
   for (chanNum = 1; chanNum <= MAX_CHANNELS; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_MINIMUM_FREQUENCY, &minFreq));
      if (chanNum == 1)
      {
         printf("%11.3f", minFreq);
      }
      else
      {
         printf("%14.3f", minFreq);
      }
   }
   printf("\n R    Reset Cycle Count");
   printf("\n\n MM   Return to Main Menu");
   printf("\n UD   Update");
   printf("\n S    Save Setup");
   printf("\n L    Load Setup\n");
}

static nai_status_t VRChannelMenu_SaveSetup(int32_t paramCount, int32_t* p_params)
{
   /* Saves all per-channel configuration parameters to a text file.
      See full source for complete implementation. */
   return NAI_SUCCESS;
}

static nai_status_t VRChannelMenu_LoadSetup(int32_t paramCount, int32_t* p_params)
{
   /* Loads all per-channel configuration parameters from a text file.
      See full source for complete implementation. */
   return NAI_SUCCESS;
}

static void VRReadingsMenu_StartDisplayReadingsThread(int32_t* p_params)
{
#if defined (LINUX)
   pthread_t thread1;
#endif

   g_stopReadingsUpdateThread = FALSE;
#if defined (WIN32)
   CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)VRReadingsMenu_RunDisplayReadingsThread, (void*)p_params, 0, 0);
#elif defined (LINUX)
   pthread_create(&thread1, 0, (void *)&VRReadingsMenu_RunDisplayReadingsThread, (void*)p_params);
#elif defined (__VXWORKS__)
   taskSpawn("MonitorRxBuffer", 99, 0, 0x4000, (FUNCPTR)VRReadingsMenu_RunDisplayReadingsThread, (int32_t *)p_params, 0, 0, 0, 0, 0, 0, 0, 0, 0);
#else
   #error Implementation Required.
#endif
}
#if defined (WIN32)
static void VRReadingsMenu_RunDisplayReadingsThread(void* p_params)
{
   int32_t* p_params_int = (int32_t*)p_params;
   while (g_stopReadingsUpdateThread == FALSE)
   {
      system("cls");
      VRReadingsMenu_DisplayChannelReadings(p_params_int);
      nai_msDelay(g_ReadingsUpdateRate);
   }
}
#elif defined (LINUX)
static void VRReadingsMenu_RunDisplayReadingsThread(void* p_params)
{
   int32_t* p_params_int = (int32_t*)p_params;
   while (g_stopReadingsUpdateThread == FALSE)
   {
      printf("\033[H\033[J");
      VRReadingsMenu_DisplayChannelReadings(p_params_int);
      nai_msDelay(g_ReadingsUpdateRate);
   }
}
#elif defined (__VXWORKS__)
static void VRReadingsMenu_RunDisplayReadingsThread(int32_t* p_params)
{
   int32_t* p_params_int = (int32_t*)p_params;
   while (g_stopReadingsUpdateThread == FALSE)
   {
      printf("\033[H\033[J");
      VRReadingsMenu_DisplayChannelReadings(p_params_int);
      nai_msDelay(g_ReadingsUpdateRate);
   }
}
#else
   #error Implementation Required.
#endif

static void VRReadingsMenu_DisplayChannelReadings(int32_t* p_params)
{
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIdx = VR_params->cardIndex;
   int32_t modNum = VR_params->module;
   int32_t chanNum = 1;
   int32_t maxChannel = VR_params->maxChannels;
   float64_t amplitudeMeas = 0.0;
   float64_t freqMeas = 0.0;
   float64_t rpmMeas = 0.0;
   float64_t periodMeas = 0.0;
   float64_t phaseMeas[NAI_VR_GEN5_CHANNELS] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
   float64_t zeroTorqueSigPhase = 0.0;
   float64_t phaseDelta = 0.0;
   float64_t percentTorqueMeas = 0.0;
   float64_t cycleCount = 0.0;

   printf("\n   Readings Group Menu               Ch 1          Ch 2          Ch 3          Ch 4          Ch 5          Ch 6          ");
   printf("Ch 7          Ch 8\n\n");
   printf("   Amplitude ( V )         ");
   for (chanNum = 1; chanNum <= maxChannel; chanNum++)
   {
      check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum, NAI_VR_MEASURED_AMPLITUDE, &amplitudeMeas));
      printf("%14.3f", amplitudeMeas);
   }
   printf("\n   Frequency ( Hz )        ");
   for (chanNum = 1; chanNum <= maxChannel; chanNum++)
   {
      check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum, NAI_VR_MEASURED_FREQUENCY, &freqMeas));
      printf("%14.3f", freqMeas);
   }
   printf("\n   RPM       ( RPM )       ");
   for (chanNum = 1; chanNum <= maxChannel; chanNum++)
   {
      check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum, NAI_VR_MEASURED_RPM, &rpmMeas));
      printf("%14.3f", rpmMeas);
   }
   printf("\n   Period    ( Sec )       ");
   for (chanNum = 1; chanNum <= maxChannel; chanNum++)
   {
      check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum, NAI_VR_MEASURED_PERIOD, &periodMeas));
      printf("%14.2E", periodMeas);
   }
   printf("\n   Phase     ( Deg )       ");
   for (chanNum = 1; chanNum <= maxChannel; chanNum++)
   {
      check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum, NAI_VR_MEASURED_PHASE, &(phaseMeas[chanNum - 1])));
      printf("%14.3f", phaseMeas[chanNum - 1]);
   }

   printf("\n   Phase Delta    ( Deg )  ");
   for (chanNum = 1; chanNum <= maxChannel; chanNum++)
   {
      check_status(naibrd_VR_GetConfigValue(cardIdx, modNum, chanNum, NAI_VR_CONFIG_ZERO_TORQUE_SIGNAL_PHASE, &zeroTorqueSigPhase));
      /* phase delta = NAI_VR_MEASURED_PHASE - trigger phase */
      phaseDelta = phaseMeas[chanNum - 1] - zeroTorqueSigPhase;
      printf("%14.3f", phaseDelta);
   }

   printf("\n   Percent Torque          ");
   for (chanNum = 1; chanNum <= maxChannel; chanNum++)
   {
      check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum, NAI_VR_MEASURED_PERCENT_TORQUE, &percentTorqueMeas));
      printf("%14.3f", percentTorqueMeas);
   }

   printf("\n   Cycle Count             ");
   for (chanNum = 1; chanNum <= maxChannel; chanNum++)
   {
      check_status(naibrd_VR_GetMeasurement(cardIdx, modNum, chanNum, NAI_VR_MEASURED_CYCLE_COUNT, &cycleCount));
      if (cycleCount > 9999999999.0)
      {
         printf("%14.5E", cycleCount);
      }
      else
      {
         printf("%14u", (uint32_t)(cycleCount + 0.5));
      }
   }

   printf("\n\nMM   Return to Main Menu");
   printf("\nR    Change Update Rate in milliSeconds [default:1000mS]");
   printf("\nC    Continue Poll");
   printf("\nS    Stop Polling\n");
   printf("\n>Please Enter Channel Readings Menu command or %c to quit : ", NAI_QUIT_CHAR);
}

static nai_status_t VRReadingsMenu_ChangeUpdateRate(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   long updateRateToSet = 0l;

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

   VRReadingsMenu_StopPolling(paramCount, p_params);
   printf("Enter Update Rate to set in milliSeconds: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      updateRateToSet = (long)(atoi((const char*)inputBuffer));
      if (updateRateToSet > 0l)
      {
         g_ReadingsUpdateRate = updateRateToSet;
      }
   }
   VRReadingsMenu_ContinuePoll(paramCount, p_params);
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRReadingsMenu_ContinuePoll(int32_t paramCount, int32_t* p_params)
{
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
   UNREFERENCED_PARAMETER(p_params);
#endif

   if (g_stopReadingsUpdateThread == TRUE)
   {
      VRReadingsMenu_StartDisplayReadingsThread(p_params);
   }
   return NAI_SUCCESS;
}

static nai_status_t VRReadingsMenu_StopPolling(int32_t paramCount, int32_t* p_params)
{
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
   UNREFERENCED_PARAMETER(p_params);
#endif

   g_stopReadingsUpdateThread = TRUE;
   printf("\n>Please Enter Channel Readings Menu command or %c to quit : ", NAI_QUIT_CHAR);
   return NAI_SUCCESS;
}


static void VRTestMenu_DisplayTestSettings(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_VR_basicOps_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIdx = p_VR_basicOps_params->cardIndex;
   int32_t modNum = p_VR_basicOps_params->module;
   bool_t iBitTestEnabled = FALSE;
   bool_t powerSupplyEnabled = FALSE;
   bool_t floatingPointModeEnabled = FALSE;
   char strIBitTestEnabled[10] = "";
   char strPowerSupplyEnabled[10] = "";
   char strFloatingPointModeEnabled[10] = "";

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

   printf("\n   Test Group Menu\n\n");
   check_status(naibrd_VR_GetModuleBITEnable(cardIdx, modNum, NAI_VR_TEST_ENABLE_IBIT_D3, &iBitTestEnabled));
   switch (iBitTestEnabled)
   {
      case TRUE:
         sprintf(strIBitTestEnabled, "Enabled");
      break;
      case FALSE:
         sprintf(strIBitTestEnabled, "Disabled");
      break;
      default:
         sprintf(strIBitTestEnabled, "Unknown");
      break;
   }
   printf("IBIT (D3) Test State:      %s\n", strIBitTestEnabled);
   check_status(naibrd_VR_GetPowerSupplyEnable(cardIdx, modNum, &powerSupplyEnabled));
   switch (powerSupplyEnabled)
   {
      case TRUE:
         sprintf(strPowerSupplyEnabled, "Enabled");
      break;
      case FALSE:
         sprintf(strPowerSupplyEnabled, "Disabled");
      break;
      default:
         sprintf(strPowerSupplyEnabled, "Unknown");
      break;
   }
   printf("Power Supply State:        %s\n", strPowerSupplyEnabled);
   check_status(naibrd_GetRunningInFloatingPointMode(cardIdx, modNum, &floatingPointModeEnabled));
   switch (floatingPointModeEnabled)
   {
      case TRUE:
         sprintf(strFloatingPointModeEnabled, "Enabled");
      break;
      case FALSE:
         sprintf(strFloatingPointModeEnabled, "Disabled");
      break;
      default:
         sprintf(strFloatingPointModeEnabled, "Unknown");
      break;
   }
   printf("Floating-Point Mode State: %s\n\n", strFloatingPointModeEnabled);
   printf("MM   Return to Main Menu\n");
   printf("TE   Test Enable (IBIT)\n");
   printf("PS   Power Supply Enable\n");
   printf("FE   Floating-Point Enable\n");
}

static nai_status_t VRTestMenu_SetTestEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enable = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Do you want to enable or disable the IBIT (D3) Test? (1 to enable, 0 to disable): ");
   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 = TRUE;
         }
         else
         {
            enable = FALSE;
         }
         check_status(naibrd_VR_SetModuleBITEnable(cardIndex, module, NAI_VR_TEST_ENABLE_IBIT_D3, enable));
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRTestMenu_SetPowerSupplyEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enable = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Do you want to enable or disable the module power supply? (1 to enable, 0 to disable): ");
   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 = TRUE;
         }
         else
         {
            enable = FALSE;
         }
         check_status(naibrd_VR_SetPowerSupplyEnable(cardIndex, module, enable));
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRTestMenu_SetFloatingPointEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enable = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Do you want to enable or disable floating-point mode for the module? (1 to enable, 0 to disable): ");
   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 = TRUE;
         }
         else
         {
            enable = FALSE;
         }
         check_status(naibrd_SetFloatingPointModeEnable(cardIndex, module, enable));
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}


static void VRStatusMenu_StartDisplayStatusThread(int32_t* p_params)
{
#if defined (LINUX)
   pthread_t thread1;
#endif

   g_stopStatusUpdateThread = FALSE;
#if defined (WIN32)
   CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)VRStatusMenu_RunDisplayStatusThread, (void*)p_params, 0, 0);
#elif defined (LINUX)
   pthread_create(&thread1, 0, (void *)&VRStatusMenu_RunDisplayStatusThread, (void*)p_params);
#elif defined (__VXWORKS__)
   taskSpawn("VRStatusMenu_RunDisplayStatusThread", 99, 0, 0x4000, (FUNCPTR)VRStatusMenu_RunDisplayStatusThread,
         (int32_t*)p_params, 0, 0, 0, 0, 0, 0, 0, 0, 0);
#else
   #error Implementation Required.
#endif
}

#if defined (WIN32)
static void VRStatusMenu_RunDisplayStatusThread(void* p_params)
{
   int32_t* p_params_int = (int32_t*)p_params;
   while (g_stopStatusUpdateThread == FALSE)
   {
      system("cls");
      VRStatusMenu_DisplayStatuses(p_params_int);
      nai_msDelay(g_StatusUpdateRate);
   }
}
#elif defined (LINUX)
static void VRStatusMenu_RunDisplayStatusThread(void* p_params)
{
   int32_t* p_params_int = (int32_t*)p_params;
   while (g_stopStatusUpdateThread == FALSE)
   {
      printf("\033[H\033[J");
      VRStatusMenu_DisplayStatuses(p_params_int);
      nai_msDelay(g_StatusUpdateRate);
   }
}
#elif defined (__VXWORKS__)
static void VRStatusMenu_RunDisplayStatusThread(int32_t* p_params)
{
   int32_t* p_params_int = (int32_t*)p_params;
   while (g_stopStatusUpdateThread == FALSE)
   {
      printf("\033[H\033[J");
      VRStatusMenu_DisplayStatuses(p_params_int);
      nai_msDelay(g_StatusUpdateRate);
   }
}
#else
   #error Implementation Required.
#endif

static void VRStatusMenu_DisplayStatuses(int32_t* p_params)
{
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIdx = VR_params->cardIndex;
   int32_t modNum = VR_params->module;
   int32_t chanNum = 1;
   int32_t maxChannel = VR_params->maxChannels;
   nai_status_bit_t bitLatchedStatus = NAI_STATUS_BIT_LO;
   nai_status_bit_t bitRealtimeStatus = NAI_STATUS_BIT_LO;
   nai_status_bit_t terminationLatchedStatus = NAI_STATUS_BIT_LO;
   nai_status_bit_t terminationRealtimeStatus = NAI_STATUS_BIT_LO;
   nai_status_bit_t signalLossLatchedStatus = NAI_STATUS_BIT_LO;
   nai_status_bit_t signalLossRealtimeStatus = NAI_STATUS_BIT_LO;
   nai_status_bit_t summaryLatchedStatus = NAI_STATUS_BIT_LO;
   nai_status_bit_t summaryRealtimeStatus = NAI_STATUS_BIT_LO;
   bool_t chanStatusEnable = FALSE;
   char strChanStatusEnable[10] = "";

   printf("\n  Status Monitoring Group Menu\n\n");
   printf("   Chan   Chan Status    BIT    Termination Fault   Signal Loss   Summary\n");
   printf("            Enable      (R/L)         (R/L)            (R/L)       (R/L)\n");
   printf("=========================================================================\n");
   for (chanNum = 1; chanNum <= maxChannel; chanNum++)
   {
      check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_STATUS_BIT_LATCHED, &bitLatchedStatus));
      check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_STATUS_BIT_REALTIME, &bitRealtimeStatus));
      check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_STATUS_TERMINATION_FAULT_LATCHED, &terminationLatchedStatus));
      check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_STATUS_TERMINATION_FAULT_REALTIME, &terminationRealtimeStatus));
      check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_STATUS_SIGNAL_LOSS_LATCHED, &signalLossLatchedStatus));
      check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_STATUS_SIGNAL_LOSS_REALTIME, &signalLossRealtimeStatus));
      check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_STATUS_SUMMARY_LATCHED, &summaryLatchedStatus));
      check_status(naibrd_VR_GetChanMappedStatus(cardIdx, modNum, chanNum, NAI_VR_CHAN_MAPPED_STATUS_SUMMARY_REALTIME, &summaryRealtimeStatus));
      check_status(naibrd_VR_GetChanStatusEnable(cardIdx, modNum, chanNum, &chanStatusEnable));
      switch (chanStatusEnable)
      {
         case TRUE:
            sprintf(strChanStatusEnable, " Enabled");
         break;
         case FALSE:
            sprintf(strChanStatusEnable, "Disabled");
         break;
         default:
            sprintf(strChanStatusEnable, " Unknown");
         break;
      }
      printf("   %2d      %8s     (%1d/%1d)         (%1d/%1d)            (%1d/%1d)       (%1d/%1d)\n", chanNum, strChanStatusEnable,
             bitRealtimeStatus, bitLatchedStatus, terminationRealtimeStatus, terminationLatchedStatus, signalLossRealtimeStatus,
             signalLossLatchedStatus, summaryRealtimeStatus, summaryLatchedStatus);
   }

   printf("\nMM   Return to Main Menu");
   printf("\nE    Channel Status Enable");
   printf("\nC    Clear Status");
   printf("\nR    Change Update Rate in milliSeconds [default:1000mS]");
   printf("\nP    Continue Poll");
   printf("\nS    Stop Polling");
   printf("\n\n>Please Enter Status Menu command or %c to quit : ", NAI_QUIT_CHAR);
}

static nai_status_t VRStatusMenu_SetChanStatusEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enable = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   if (channel == 0)
   {
      printf("Do you want to enable or disable status reporting for all channels? (1 to enable, 0 to disable): ");
   }
   else
   {
      printf("Do you want to enable or disable status reporting for channel %d? (1 to enable, 0 to disable): ", channel);
   }
   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 = TRUE;
         }
         else
         {
            enable = FALSE;
         }
         if (channel == 0)
         {
            for (channel = 1; channel <= MAX_CHANNELS; channel++)
            {
               check_status(naibrd_VR_SetChanStatusEnable(cardIndex, module, channel, enable));
            }
         }
         else
         {
            check_status(naibrd_VR_SetChanStatusEnable(cardIndex, module, channel, enable));
         }
      }
      else
      {
         printf("\nInvalid Selection Entered\n");
      }
   }
   VRStatusMenu_ContinuePoll(paramCount, p_params);
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRStatusMenu_ClearStatus(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   p_naiapp_AppParameters_t VR_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = VR_params->cardIndex;
   int32_t module = VR_params->module;
   int32_t channel = VR_params->channel;
   int32_t MAX_CHANNELS = VR_params->maxChannels;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Enter Latched Status Type to clear (0 for BIT, 1 for Termination Fault, 2 for Signal Loss, 3 for Summary): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      if (channel == 0)
      {
         for (channel = 1; channel <= MAX_CHANNELS; channel++)
         {
            switch (inputBuffer[0])
            {
               case '0':
                  check_status(naibrd_VR_ClearChanMappedStatus(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_STATUS_BIT_LATCHED));
               break;
               case '1':
                  check_status(naibrd_VR_ClearChanMappedStatus(cardIndex, module, channel,
                                                               NAI_VR_CHAN_MAPPED_STATUS_TERMINATION_FAULT_LATCHED));
               break;
               case '2':
                  check_status(naibrd_VR_ClearChanMappedStatus(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_STATUS_SIGNAL_LOSS_LATCHED));
               break;
               case '3':
                  check_status(naibrd_VR_ClearChanMappedStatus(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_STATUS_SUMMARY_LATCHED));
               break;
               default:
                  printf("\nInvalid Selection Entered\n");
               break;
            }
         }
      }
      else
      {
         switch (inputBuffer[0])
         {
            case '0':
               check_status(naibrd_VR_ClearChanMappedStatus(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_STATUS_BIT_LATCHED));
            break;
            case '1':
               check_status(naibrd_VR_ClearChanMappedStatus(cardIndex, module, channel,
                                                            NAI_VR_CHAN_MAPPED_STATUS_TERMINATION_FAULT_LATCHED));
            break;
            case '2':
               check_status(naibrd_VR_ClearChanMappedStatus(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_STATUS_SIGNAL_LOSS_LATCHED));
            break;
            case '3':
               check_status(naibrd_VR_ClearChanMappedStatus(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_STATUS_SUMMARY_LATCHED));
            break;
            default:
               printf("\nInvalid Selection Entered\n");
            break;
         }
      }
   }
   VRStatusMenu_ContinuePoll(paramCount, p_params);
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRStatusMenu_ChangeUpdateRate(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   long updateRateToSet = 0l;

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

   VRStatusMenu_StopPolling(paramCount, p_params);
   printf("Enter Update Rate to set in milliSeconds: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      updateRateToSet = (long)(atoi((const char*)inputBuffer));
      if (updateRateToSet > 0l)
      {
         g_StatusUpdateRate = updateRateToSet;
      }
   }
   VRStatusMenu_ContinuePoll(paramCount, p_params);
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static nai_status_t VRStatusMenu_ContinuePoll(int32_t paramCount, int32_t* p_params)
{
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
   UNREFERENCED_PARAMETER(p_params);
#endif

   if (g_stopStatusUpdateThread == TRUE)
   {
      VRStatusMenu_StartDisplayStatusThread(p_params);
   }
   return NAI_SUCCESS;
}

static nai_status_t VRStatusMenu_StopPolling(int32_t paramCount, int32_t* p_params)
{
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
   UNREFERENCED_PARAMETER(p_params);
#endif

   g_stopStatusUpdateThread = TRUE;
   printf("\n\n>Please Enter Status Menu command or %c to quit : ", NAI_QUIT_CHAR);
   return NAI_SUCCESS;
}

Help Bot

X