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

AD BasicOps

AD BasicOps Sample Application (SSK 1.x)

Overview

The AD BasicOps sample application demonstrates how to configure and read analog-to-digital channels using the NAI Software Support Kit (SSK 1.x). It covers the core AD operations you will need in your own application: setting range and polarity, configuring filter break frequency, enabling channel status and latch modes, reading channel data, and managing saturation thresholds.

This sample supports the following AD module types: AD1 through AD6 and ADE through ADG. It also works with combination modules that include AD functionality: CME, CMF, and CMG. It serves as a practical API reference — each menu command maps directly to one or more naibrd_AD_*() API calls that you can lift into your own code.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with an AD module installed (AD1–AD6 or ADE–ADG).

  • 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 AD_BasicOps executable from your build output directory. On startup the application looks for a configuration file (default_AD_BasicOps.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, a command menu lets you exercise each AD operation.

Board Connection and Module Selection

Note
This startup sequence is common to all NAI sample applications. The board connection and module selection code shown here is not specific to AD.

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_AD_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 AD variant installed.

#if defined (__VXWORKS__)
int32_t AD_BasicOps(void)
#else
int32_t main(void)
#endif
{
   bool_t bQuit = FALSE;
   int32_t cardIndex = -1;
   int32_t module = 0;
   uint32_t modId = 0u;
   int32_t moduleCount;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (!bQuit)
      {
         naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         naibrd_GetModuleCount(cardIndex, &moduleCount);
         naiapp_query_ModuleNumber(moduleCount, 1, &module);
         modId = naibrd_GetModuleID(cardIndex, module);
         bQuit = ADBasicOps_run(cardIndex, module, modId);
      }

      printf("Type the Enter key to exit the program: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   }

   naiapp_access_CloseAllOpenCards();

   return 0;
}
Important

Common connection errors you may encounter at this stage:

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

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

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

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

Program Structure

Entry Point

On standard platforms the entry point is main(). On VxWorks the entry point is AD_BasicOps() — the SSK 1.x build system selects the correct variant via a preprocessor guard:

#if defined (__VXWORKS__)
int32_t AD_BasicOps(void)
#else
int32_t main(void)
#endif

The startup flow is the same in both cases:

  1. Attempt to load the saved configuration file via naiapp_RunBoardMenu(CONFIG_FILE). If the file does not yet exist, the interactive board menu is presented instead.

  2. Enter a loop that queries for card index and module slot.

  3. Call ADBasicOps_run() to enter the interactive command loop for the selected module.

  4. On exit, close all open board connections with naiapp_access_CloseAllOpenCards().

Application Parameters

The ADBasicOps_run() function populates an naiapp_AppParameters_t struct that is passed to every command handler. Your application will need to track these same values to identify which board, module, and channel you are targeting:

ad_basicOps_params->cardIndex = cardIndex;
ad_basicOps_params->module = module;
ad_basicOps_params->channel = DEFAULT_CHANNEL;
ad_basicOps_params->maxChannels = naibrd_AD_GetChannelCount(modId);
ad_basicOps_params->modId = modId;
ad_basicOps_params->displayHex = FALSE;
  • cardIndex — identifies which board in a multi-board system.

  • module — the slot number where the AD module is installed.

  • channel — the currently selected channel (defaults to 1).

  • maxChannels — total channel count for the detected module, retrieved by calling naibrd_AD_GetChannelCount() with the module ID.

  • modId — the module identifier returned by naibrd_GetModuleID(). API functions use this to apply module-specific behavior.

  • displayHex — toggles between hexadecimal and decimal display of register values.

Command Loop

ADBasicOps_run() drives the interactive command loop. On each iteration it displays the current channel configuration, prints the command menu, and dispatches the user’s selection to the matching handler function:

static bool_t ADBasicOps_run(int32_t cardIndex, int32_t module, uint32_t modId)
{
   bool_t bQuit = FALSE;
   bool_t bCmdFound = FALSE;
   int32_t cmd;
   naiapp_AppParameters_t  ad_basicops_params;
   p_naiapp_AppParameters_t ad_basicOps_params = &ad_basicops_params;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   ad_basicOps_params->cardIndex = cardIndex;
   ad_basicOps_params->module = module;
   ad_basicOps_params->channel = DEFAULT_CHANNEL;
   ad_basicOps_params->maxChannels = naibrd_AD_GetChannelCount(modId);
   ad_basicOps_params->modId = modId;
   ad_basicOps_params->displayHex = FALSE;

   do
   {
      naiapp_utils_LoadParamMenuCommands(AD_BASICOPS_CMD_COUNT, AD_BasicOpsCmds);
      ADBasicOps_displayConfigurations(cardIndex, module, modId, ad_basicOps_params->maxChannels, ad_basicOps_params->displayHex);
      naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_PGM_NAME);
      printf("\n\nPlease enter a command or 'q' to quit:");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
            if (bCmdFound)
            {
               AD_BasicOpsCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)ad_basicOps_params);
            }
            else
            {
               printf("Invalid command entered\n");
            }
         }
      }

   } while (!bQuit);
   return bQuit;
}

The available commands are registered in the AD_BasicOpsCmds[] table:

Command Description

PR

Set AD polarity and range

BRKFRQ

Set AD filter break frequency

M

Set AD voltage/current mode (AD4 only)

L

Set AD latch/unlatch status

AC

Set AD channel active/inactive (AD4 only)

SAT

Open the saturation submenu

D0

Enable, configure, or disable D0 test

FP_MODE

Enable/disable hardware floating-point conversion mode

OFFSET

Set hardware floating-point conversion offset

SCALE

Set hardware floating-point conversion scale factor

CHANSTAT

Channel status enable/disable

PBIT

Check power-on BIT

THRESH

Set BIT error threshold

TND

Toggle numeric display (hex/decimal)

The menu-driven structure is a convenience of the sample application. In your own application, you would call the same underlying naibrd_AD_*() API functions directly — for example, calling naibrd_AD_SetRangePolarity() instead of navigating to the "PR" menu command.

Reading and Configuration

This section covers the API calls used to configure AD channel behavior: setting the input range and polarity, switching between voltage and current mode, latching channel readings, adjusting the low-pass filter break frequency, and enabling or disabling individual channels.

Set Range and Polarity

To configure the input range and polarity on a channel in your own application, call naibrd_AD_SetRange() with the desired polarity and range values.

The sample first retrieves the channel’s current mode (voltage or current) with naibrd_AD_GetMode(), then uses the utility function ADUtils_GetPolarityRange() (defined in nai_ad_utils.c) to prompt for and validate polarity and range values against the module’s supported settings. In your own code, you can skip the utility and pass valid polarity and range values directly.

nai_ad_range_mode_t polarity = NAI_AD_GEN5_D0_RANGE_MODE_UNIPOLAR;
float64_t range = 0.0;
nai_ad_mode_t mode = NAI_AD_MODE_VOLTAGE;

/* Retrieve the current mode so the correct range table is used */
naibrd_AD_GetMode(cardIndex, module, channel, &mode);

/* Set the polarity and range for the specified channel */
naibrd_AD_SetRange(cardIndex, module, channel, polarity, range);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — the channel to configure.

  • polarity — unipolar (NAI_AD_GEN5_D0_RANGE_MODE_UNIPOLAR) or bipolar. The set of valid values depends on the module type.

  • range — the full-scale input range as a floating-point value. Refer to your module’s manual for the list of supported range values per polarity setting.

Note
The valid combinations of polarity and range differ across AD module types. Always consult the module manual for your specific hardware.

Set Mode (Voltage or Current)

To switch a channel between voltage and current measurement mode in your own application, call naibrd_AD_SetMode(). This feature is exclusive to the AD4 module — calling it on any other module type returns NAI_ERROR_NOT_SUPPORTED.

nai_status_t status;

/* Set a single channel to voltage mode */
status = naibrd_AD_SetMode(cardIndex, module, channel, NAI_AD_MODE_VOLTAGE);

/* Set a single channel to current mode */
status = naibrd_AD_SetMode(cardIndex, module, channel, NAI_AD_MODE_CURRENT);

To apply the same mode to every channel on the module, loop over all channels:

for (channel = 1; channel <= maxChannels; channel++)
   status = naibrd_AD_SetMode(cardIndex, module, channel, NAI_AD_MODE_VOLTAGE);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — the channel to configure.

  • The fourth parameter selects the mode: NAI_AD_MODE_VOLTAGE or NAI_AD_MODE_CURRENT.

Note
This function is AD4 only. On all other AD modules the API returns NAI_ERROR_NOT_SUPPORTED.

Set Latch

To latch all channel readings simultaneously in your own application, call naibrd_AD_SetLatch(). When latching is enabled, every channel’s reading is captured at the same instant, which is useful when you need a coherent snapshot across channels. This is a module-wide operation — there is no per-channel latch control.

bool_t latched = TRUE;

/* Latch all channel readings on the module */
naibrd_AD_SetLatch(cardIndex, module, latched);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • latched — TRUE to latch (freeze) all channel readings simultaneously, FALSE to return to free-running mode.

Set Break Frequency

To configure the low-pass filter break frequency on a channel in your own application, call naibrd_AD_SetBreakFrequency(). This controls the cutoff frequency of the per-channel input filter, which determines how much high-frequency noise is attenuated before the signal is digitized.

uint32_t filterBreakFrequency = 100u;

/* Set the filter break frequency for the specified channel */
naibrd_AD_SetBreakFrequency(cardIndex, module, channel, filterBreakFrequency);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — the channel to configure.

  • filterBreakFrequency — the desired cutoff frequency in Hz. Refer to your module’s manual for the set of supported frequency values.

Note
The available break frequency settings vary by module type. Consult the module manual for supported values.

Set Active Channel

To enable or disable individual channels in your own application, call naibrd_AD_SetChannelState(). Disabling a channel powers it down, which can reduce module power consumption. This feature is exclusive to the AD4 module — calling it on any other module type returns NAI_ERROR_NOT_SUPPORTED.

nai_status_t status;

/* Enable a single channel */
status = naibrd_AD_SetChannelState(cardIndex, module, channel, TRUE);

/* Disable a single channel */
status = naibrd_AD_SetChannelState(cardIndex, module, channel, FALSE);

To enable or disable all channels at once, loop over every channel on the module:

for (channel = 1; channel <= maxChannels; channel++)
   status = naibrd_AD_SetChannelState(cardIndex, module, channel, TRUE);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — the channel to enable or disable.

  • The fourth parameter — TRUE to activate the channel, FALSE to deactivate it.

Note
This function is AD4 only. On all other AD modules the API returns NAI_ERROR_NOT_SUPPORTED.
Important

Common Errors

  • NAI_ERROR_NOT_SUPPORTED — Returned when attempting to set mode or active channel state on a non-AD4 module. These features are exclusive to the AD4.

  • Invalid range or polarity — Passing a range or polarity value that the module does not support. Consult your module’s manual for the list of valid range and polarity settings.

Self-Test and Diagnostics

This section covers the built-in self-test and diagnostic features available in the AD BasicOps sample: the D0 test signal, power-on BIT verification, BIT error thresholds, and per-channel status enable control. These features help you verify that the AD conversion path is functioning correctly and detect hardware faults early.

D0 Test Enable and Configuration

To inject a known test signal into the AD conversion path in your own application, call naibrd_AD_SetTestEnable() to turn the D0 test on or off, and naibrd_AD_ConfigureD0Test() to set the test parameters.

The D0 test drives a known voltage (or current) into the converter so you can verify the digitization path end-to-end. The D0 range is always 10V, but the polarity is configurable as unipolar or bipolar. You must also specify a test level — the voltage the D0 source will output.

/* Enable the D0 test */
naibrd_AD_SetTestEnable(cardIndex, module, NAI_AD_D0_TEST, TRUE);

/* Configure D0 test: set polarity, range, and test level */
nai_ad_range_mode_t polarity = NAI_AD_RANGE_MODE_BIPOLAR;
float64_t D0Range = 10.0;
float64_t testLevel = 5.0;
naibrd_AD_ConfigureD0Test(cardIndex, module, polarity, D0Range, testLevel);

To disable the D0 test when you are finished:

naibrd_AD_SetTestEnable(cardIndex, module, NAI_AD_D0_TEST, FALSE);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • NAI_AD_D0_TEST — selects the D0 test type.

  • polarity — NAI_AD_RANGE_MODE_UNIPOLAR or NAI_AD_RANGE_MODE_BIPOLAR.

  • D0Range — the full-scale range for the D0 test (always 10V for voltage-mode modules).

  • testLevel — the voltage level the D0 source will output.

Note
Channels that are not set to the same range and polarity as D0 will not be scaled the same, and will show unexpected readings. On AD3 and ADG modules, the D0 test operates in current mode rather than voltage mode. Consult your module’s manual for hardware-specific D0 test behavior.

Power-On BIT Check

To verify that the module passed its power-on built-in test (PBIT) in your own application, call naibrd_GetModulePBITComplete() to check whether PBIT has run, then iterate over all channels calling naibrd_AD_GetStatus() with NAI_AD_STATUS_BIT_LATCHED to read each channel’s BIT result.

PBIT only executes once, at power-on. If the module has not been power-cycled since it was installed, PBIT may not have completed — this is normal and does not indicate a hardware failure.

bool_t pbitComplete;
nai_status_bit_t bitFailed;
int32_t channelCount = naibrd_AD_GetChannelCount(modId);

/* Step 1: Check whether PBIT has completed */
naibrd_GetModulePBITComplete(cardIndex, module, channel, &pbitComplete);

if (pbitComplete)
{
   /* Step 2: Read BIT status for each channel */
   for (channel = 1; channel <= channelCount; channel++)
   {
      naibrd_AD_GetStatus(cardIndex, module, channel,
         NAI_AD_STATUS_BIT_LATCHED, &bitFailed);
      if (bitFailed)
         printf("Channel %d: BIT FAILED\n", channel);
      else
         printf("Channel %d: BIT Passed\n", channel);
   }
}
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — passed to the PBIT completion check (any valid channel).

  • pbitComplete — set to TRUE if PBIT has finished, FALSE otherwise.

  • NAI_AD_STATUS_BIT_LATCHED — reads the latched BIT status for a channel.

  • bitFailed — non-zero if the channel failed its BIT.

BIT Error Thresholds

To configure how many BIT errors the module tolerates before flagging a failure in your own application, call naibrd_SetModuleBITErrorThreshold(). To read the current threshold, call naibrd_GetModuleBITErrorThreshold(). To reset BIT counters on a per-channel basis, call naibrd_ClearModuleBITLogic().

The default BIT error threshold is 5. This means the module must accumulate more than 5 BIT errors on a channel before it reports a BIT failure for that channel. You can raise or lower this threshold depending on your application’s sensitivity requirements.

uint32_t bitThreshold = 0u;

/* Set BIT error threshold */
naibrd_SetModuleBITErrorThreshold(cardIndex, module, 10);

/* Read back the current threshold */
naibrd_GetModuleBITErrorThreshold(cardIndex, module, &bitThreshold);

/* Clear BIT counters on all channels */
int32_t channelCount = naibrd_AD_GetChannelCount(modId);
for (int32_t ch = 1; ch <= channelCount; ch++)
   naibrd_ClearModuleBITLogic(cardIndex, module, ch);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • bitThreshold — the number of BIT errors before a failure is reported. Default is 5.

  • naibrd_ClearModuleBITLogic() resets the BIT error counter for a single channel.

Channel Status Enable

To enable or disable status reporting on a per-channel basis in your own application, call naibrd_AD_SetChanStatusEnable(). When channel status is disabled, the module will not report status conditions for that channel and status-based interrupts will not assert.

/* Enable status reporting on a channel */
naibrd_AD_SetChanStatusEnable(cardIndex, module, channel, TRUE);

/* Disable status reporting on a channel */
naibrd_AD_SetChanStatusEnable(cardIndex, module, channel, FALSE);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — the channel to enable or disable status reporting on.

  • The fourth parameter — TRUE to enable status reporting, FALSE to disable it.

Note
Disabling channel status also suppresses any interrupts that would be triggered by status conditions on that channel. Re-enable channel status before relying on status-based interrupt handling.
Important

Common Errors

  • PBIT not complete — The power-on BIT test only runs when the module is first powered on. If the module has not been power-cycled, naibrd_GetModulePBITComplete() will report that PBIT has not completed. This is not a hardware failure.

  • D0 test shows unexpected readings — The D0 test requires that polarity, range, and test level all be configured. Missing any one of these will produce inaccurate results. Additionally, channels not set to the same range and polarity as D0 will show unexpected readings.

  • BIT failure on a channel — A BIT failure can indicate an open input, a hardware fault, or an incorrect range setting. Consult your module’s manual for diagnostic procedures.

Floating-Point Conversion

Some AD modules support hardware floating-point conversion, which applies an offset and scale factor to raw ADC values directly in hardware. If your application needs engineering-unit readings with a custom offset or gain applied, enabling floating-point mode lets the hardware handle this rather than doing it in software. The three functions in this section work together: first verify that the module supports the feature, then configure the offset and scale factor, and finally enable the mode.

Enable Floating-Point Mode

To enable or disable hardware floating-point conversion on a module, call naibrd_SetFloatingPointModeEnable(). Before doing so, always check whether the module supports the feature by calling naibrd_GetFloatingPointModeCapability(). Not all AD modules have floating-point conversion hardware, and calling the enable function on an unsupported module will fail.

bool_t fpCapable = FALSE;
nai_status_t status;

/* Step 1: Check whether the module supports floating-point conversion */
naibrd_GetFloatingPointModeCapability(cardIndex, module, &fpCapable);

if (fpCapable)
{
   /* Step 2: Enable floating-point mode on the module */
   status = naibrd_SetFloatingPointModeEnable(cardIndex, module, 0x1);
}
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • fpCapable — set to TRUE if the module supports floating-point conversion, FALSE otherwise.

  • The third parameter to naibrd_SetFloatingPointModeEnable() — 0x1 to enable, 0x0 to disable.

When enabled, the module applies the configured offset and scale factor to every raw ADC value before it is returned, so subsequent reads produce a calibrated or scaled result directly.

Set Floating-Point Offset

To set the floating-point offset on a per-channel basis, call naibrd_AD_SetFloatingPointOffset(). The offset is added to each raw ADC reading when floating-point mode is enabled. As with enabling the mode itself, always verify floating-point capability first.

bool_t fpCapable = FALSE;
float64_t offset = 1.25;
nai_status_t status;

naibrd_GetFloatingPointModeCapability(cardIndex, module, &fpCapable);

if (fpCapable)
{
   /* Set the floating-point offset for a specific channel */
   status = naibrd_AD_SetFloatingPointOffset(cardIndex, module, channel, offset);
}
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — the channel to configure.

  • offset — the offset value to apply. This is a float64_t and can be positive or negative.

Set Floating-Point Scale Factor

To set the floating-point scale factor on a per-channel basis, call naibrd_AD_SetFloatingPointScaleFactor(). The scale factor is multiplied against each raw ADC reading when floating-point mode is enabled. As with the other floating-point functions, always verify capability first.

bool_t fpCapable = FALSE;
float64_t scale = 2.0;
nai_status_t status;

naibrd_GetFloatingPointModeCapability(cardIndex, module, &fpCapable);

if (fpCapable)
{
   /* Set the floating-point scale factor for a specific channel */
   status = naibrd_AD_SetFloatingPointScaleFactor(cardIndex, module, channel, scale);
}
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — the channel to configure.

  • scale — the scale factor to apply. This is a float64_t.

Important

Common Errors

  • Unexpected readings after enabling floating-point mode — The offset and scale factor must be set to the desired values before enabling floating-point mode. If the mode is enabled without configuring these parameters, the default values may not match your expectations.

  • Offset and scale factor have no effect — These parameters are stored but only applied when floating-point mode is enabled. Verify that naibrd_SetFloatingPointModeEnable() has been called with a nonzero value.

  • "This feature is not supported by this module" — The module does not have floating-point conversion capability. Call naibrd_GetFloatingPointModeCapability() to check before attempting to enable it.

Saturation Control

Saturation control lets you define low and high voltage thresholds on a per-channel basis. When a channel reading exceeds either bound, the hardware flags the condition. This is useful for monitoring whether input signals stay within an expected operating window — for example, detecting an over-voltage or under-voltage condition without polling channel readings in software.

Checking Saturation Availability

Saturation control is not available on all FPGA revisions. Before entering the saturation submenu, the sample calls naibrd_GetModuleRev() to retrieve the module’s FPGA revision and compares it against a minimum threshold that varies by module family (AD1-AD3, AD4-AD6, or ADE-ADG).

uint32_t fpgaRev = 0u;
uint32_t modprocrev;
bool_t satAvailable = FALSE;

/* Retrieve the module's FPGA revision */
naibrd_GetModuleRev(cardIndex, module, &modprocrev, &fpgaRev);

/* Compare fpgaRev against the minimum revision for your module family */
if (fpgaRev >= minimumSupportedRev)
   satAvailable = TRUE;
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • fpgaRev — the FPGA revision reported by the module.

  • The minimum supported revision differs by module family. Consult your module’s manual for the specific FPGA revision required to enable saturation control.

If the FPGA revision does not meet the minimum, the sample reports "Saturation is not supported by this module" and does not enter the saturation submenu.

Set Saturation Levels

To define the low and high saturation thresholds on a channel, call naibrd_AD_SetSaturationLevel() with the appropriate control selector. Each channel has independent low and high threshold settings.

float64_t lowThreshold = -5.0;
float64_t highThreshold = 5.0;

/* Set the low saturation threshold for a channel */
naibrd_AD_SetSaturationLevel(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_LOW, lowThreshold);

/* Set the high saturation threshold for a channel */
naibrd_AD_SetSaturationLevel(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_HIGH, highThreshold);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — the channel to configure.

  • The fourth parameter selects which threshold to set: NAI_AD_SATURATION_CONTROL_LOW or NAI_AD_SATURATION_CONTROL_HIGH.

  • The fifth parameter is the threshold voltage as a float64_t.

Enable Saturation Detection

Setting a threshold level alone does not activate saturation detection. You must also enable detection for each threshold independently by calling naibrd_AD_SetSaturationControl(). Both the threshold level and the enable flag must be configured for detection to work.

/* Enable low-level saturation detection on a channel */
naibrd_AD_SetSaturationControl(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_LOW, TRUE);

/* Enable high-level saturation detection on a channel */
naibrd_AD_SetSaturationControl(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_HIGH, TRUE);

To disable detection, pass FALSE instead of TRUE:

/* Disable low-level saturation detection */
naibrd_AD_SetSaturationControl(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_LOW, FALSE);

/* Disable high-level saturation detection */
naibrd_AD_SetSaturationControl(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_HIGH, FALSE);
  • cardIndex — identifies the board.

  • module — the slot containing the AD module.

  • channel — the channel to configure.

  • The fourth parameter selects which threshold to enable or disable: NAI_AD_SATURATION_CONTROL_LOW or NAI_AD_SATURATION_CONTROL_HIGH.

  • The fifth parameter — TRUE to enable detection, FALSE to disable it.

Reading Saturation Configuration

To read back the current saturation configuration for a channel, call naibrd_AD_GetSaturationLevel() and naibrd_AD_GetSaturationControl() for both the low and high thresholds. This lets you verify the configured thresholds and whether detection is active.

float64_t satLowLevel = 0.0;
float64_t satHighLevel = 0.0;
bool_t satLowEnable = FALSE;
bool_t satHighEnable = FALSE;

/* Read saturation threshold levels */
naibrd_AD_GetSaturationLevel(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_LOW, &satLowLevel);
naibrd_AD_GetSaturationLevel(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_HIGH, &satHighLevel);

/* Read saturation enable states */
naibrd_AD_GetSaturationControl(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_LOW, &satLowEnable);
naibrd_AD_GetSaturationControl(cardIndex, module, channel,
   NAI_AD_SATURATION_CONTROL_HIGH, &satHighEnable);
  • satLowLevel / satHighLevel — the configured threshold voltages.

  • satLowEnable / satHighEnable — TRUE if detection is active for that threshold, FALSE otherwise.

To display the saturation configuration for all channels on a module, loop over each channel and call these four functions, as the sample does in ADBasicOps_displaySaturationConfig().

Important

Common Errors

  • Saturation commands unavailable — Saturation control requires a minimum FPGA revision that varies by module family. If the feature is not available, the sample will report "Saturation is not supported by this module." Consult your module’s manual for the required FPGA revision.

  • Thresholds set but detection not working — Both the threshold level and the enable flag must be configured. Setting a threshold without enabling detection (or vice versa) will not produce the expected behavior.

Display Functions

The display functions in this sample demonstrate the full set of naibrd_AD_Get* read-back APIs. These are the same calls you would use in your own application to retrieve channel data, configuration, and status. The sample calls them on every iteration of the command loop to show a live view of the module state, but in your own code you can call them whenever you need to read back a value.

Reading Channel Data

To read back channel voltages in your own application, call naibrd_AD_GetVoltage(). To read raw register values instead, call naibrd_AD_GetChannelRaw(). The ADBasicOps_displayConfigurations() function demonstrates these calls along with the other per-channel read-back APIs. For each channel it retrieves the current reading, range and polarity, filter break frequency, and measurement mode:

float64_t data = 0;
uint32_t rawData = 0u;
float64_t range = 0;
nai_ad_range_mode_t polarity = NAI_AD_GEN5_D0_RANGE_MODE_UNIPOLAR;
uint32_t filterBreakFreq = 0u;
nai_ad_mode_t data_mode = NAI_AD_MODE_VOLTAGE;

for (channel = 1; channel <= maxChannels; channel++)
{
   naibrd_AD_GetVoltage(cardIndex, module, channel, &data);
   naibrd_AD_GetChannelRaw(cardIndex, module, channel, NAI_AD_CHAN_RAW_DATA, &rawData);
   naibrd_AD_GetRange(cardIndex, module, channel, &polarity, &range);
   naibrd_AD_GetBreakFrequency(cardIndex, module, channel, &filterBreakFreq);
   naibrd_AD_GetMode(cardIndex, module, channel, &data_mode);
}

On AD4 modules, the display function also retrieves the channel active/inactive state:

nai_ad_state_t channelActive = NAI_AD_STATE_INACTIVE;
naibrd_AD_GetChannelState(cardIndex, module, channel, &channelActive);

If the module supports hardware floating-point conversion, the function reads back the per-channel offset and scale factor:

float64_t offset = 0.0;
float64_t scale = 0.0;
naibrd_AD_GetFloatingPointOffset(cardIndex, module, channel, &offset);
naibrd_AD_GetFloatingPointScaleFactor(cardIndex, module, channel, &scale);
  • naibrd_AD_GetVoltage() — returns the channel reading in engineering units (volts or amps depending on the mode).

  • naibrd_AD_GetChannelRaw() — returns the raw register value as an unsigned integer.

  • naibrd_AD_GetRange() — returns both the polarity and the full-scale range for the channel.

  • naibrd_AD_GetBreakFrequency() — returns the configured low-pass filter cutoff frequency in Hz.

  • naibrd_AD_GetMode() — returns the measurement mode (voltage or current).

  • naibrd_AD_GetChannelState() — returns the channel active/inactive state (AD4 only).

  • naibrd_AD_GetFloatingPointOffset() / naibrd_AD_GetFloatingPointScaleFactor() — return the hardware floating-point offset and scale factor for the channel.

Reading Channel Status

To read channel status in your own application, call naibrd_AD_GetChanStatusEnable() to check whether status reporting is active, then call naibrd_AD_GetStatus() with the appropriate status type to retrieve real-time and latched values. The ADBasicOps_displayStatus() function demonstrates the complete set of status read-back calls:

nai_status_bit_t chanStatusEnabled;
nai_status_bit_t bitStatusRT, bitStatusLT;
nai_status_bit_t openStatusRT, openStatusLT;
nai_status_bit_t summaryStatusRT, summaryStatusLT;

naibrd_AD_GetChanStatusEnable(cardIndex, module, channel, &chanStatusEnabled);

naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_BIT_REALTIME, &bitStatusRT);
naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_BIT_LATCHED, &bitStatusLT);

naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_OPEN_OVERVOLT_REALTIME, &openStatusRT);
naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_OPEN_OVERVOLT_LATCHED, &openStatusLT);

naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_SUMMARY_REALTIME, &summaryStatusRT);
naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_SUMMARY_LATCHED, &summaryStatusLT);

The sample displays each status pair in R/L (real-time / latched) format. Here is how to interpret the values:

  • R/L — the first digit is the real-time status, the second is the latched status. Real-time reflects the current condition; latched holds the value until explicitly cleared.

  • 0 = normal/pass, 1 = fail/detected — a zero means the condition is not present, a one means it has been detected.

  • BIT status — tests the AD conversion path. A failure indicates that the converter is not producing expected results for a known reference input.

  • Open/overvoltage — detects open-circuit or overvoltage conditions on the channel input. A detection typically means the input is disconnected or exceeds the configured range.

  • Summary — an aggregate of all error conditions for the channel. If any individual status is in a fail state, the summary status will also report a fail.

Hex vs. Voltage Toggle

The ADBasicOps_toggleNumDisplay() function switches the displayHex flag, which controls whether the display functions call naibrd_AD_GetVoltage() or naibrd_AD_GetChannelRaw():

if (displayHex)
{
   naibrd_AD_GetChannelRaw(cardIndex, module, channel, NAI_AD_CHAN_RAW_DATA, &rawData);
   /* Display as hex: 0x00000000 */
}
else
{
   naibrd_AD_GetVoltage(cardIndex, module, channel, &data);
   /* Display in engineering units: voltage or current */
}

Both calls read the same underlying channel data, but present it differently:

  • naibrd_AD_GetVoltage() returns a float64_t in engineering units (volts or amps). Use this in your application logic when you need calibrated measurements — for example, comparing a reading against a threshold or logging sensor data.

  • naibrd_AD_GetChannelRaw() returns the raw register value as a uint32_t displayed in hexadecimal. Use this for register-level debugging — for example, verifying that a specific bit pattern is present in the data register or diagnosing a calibration issue where the scaled value looks wrong.

Troubleshooting Reference

This table summarizes common errors and symptoms covered in the sections above. For detailed context on each entry, refer to the relevant section. Consult your module’s manual for hardware-specific diagnostic procedures.

Error / Symptom Possible Causes Suggested Resolution

No board found or connection timeout

Board not powered, incorrect or missing configuration file, network issue

Verify hardware is powered and connected. If default_AD_BasicOps.txt exists, check that it lists the correct interface and address. If it does not exist, the board menu will appear — configure and save your connection settings.

Module not detected at selected slot

No module installed at the specified slot, incorrect module number entered

Verify hardware configuration and module slot assignment

NAI_ERROR_NOT_SUPPORTED

Feature not available for this module type (e.g., mode switching on non-AD4) or FPGA revision too old for the requested feature

Check your module type. Consult your module’s manual for supported features and required FPGA revisions.

NAI_ERROR_INVALID_VALUE

Invalid parameter passed to an API call (e.g., out-of-range value, unsupported polarity)

Verify input values against your module’s manual specifications

NAI_ERROR_UNKNOWN

Generic failure during an API call

Check board connection, verify module is powered and responsive

PBIT not complete

Module has not been power-cycled since last boot

Power-cycle the module and re-run the PBIT check

Unexpected voltage readings

Range or polarity misconfigured, floating-point offset/scale incorrect, D0 test still enabled

Verify channel configuration. Disable D0 test if not needed. Check floating-point parameters.

BIT failure on a channel

Open input, hardware fault, or incorrect range setting

Check input wiring. Consult your module’s manual for diagnostic procedures.

Saturation commands unavailable

FPGA revision below the minimum required for saturation support

Consult your module’s manual for the required FPGA revision

D0 test produces unexpected results

Polarity, range, or test level not fully configured — all three must be set

Ensure naibrd_AD_SetTestEnable() and naibrd_AD_ConfigureD0Test() are both called with valid parameters

Floating-point mode readings incorrect

Offset/scale set but mode not enabled, or mode enabled without setting offset/scale

Enable floating-point mode AND set both offset and scale factor parameters

Full Source

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

Full Source — AD_BasicOps.c (SSK 1.x)
#include <stdint.h>
#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"
#include "nai_ad_utils.h"

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_ad.h"
#include "advanced/nai_ether_adv.h"
#include "boards/naibrd_gen5.h"

static const int8_t *SAMPLE_PGM_NAME = (const int8_t *)"AD Module Basic Operation Program";
static const int8_t *CONFIG_FILE = (const int8_t *)"default_AD_BasicOps.txt";

#define NAIAPPS_AD123_SATURATION_SUPPORT_FPGA_REV 0x00020001u
#define NAIAPPS_AD456_SATURATION_SUPPORT_FPGA_REV 0x0007000Cu
#define NAIAPPS_ADEFG_SATURATION_SUPPORT_FPGA_REV 0x00010007u
static const int8_t *SATURATION_MENU = (const int8_t *)"AD Module Saturation Menu";

#define DEFAULT_CHANNEL 1

/* Function prototypes */
static bool_t ADBasicOps_run(int32_t cardIndex, int32_t module, uint32_t modid);
static void ADBasicOps_displayConfigurations(int32_t cardIndex, int32_t module, uint32_t modId, int32_t maxChannels, bool_t displayHex);
static void ADBasicOps_displaySaturationConfig(int32_t cardIndex, int32_t module, uint32_t modId, int32_t maxChannels, bool_t displayHex);

/* AD Basic Ops Command Functions */
static nai_status_t ADBasicOps_setRangePolarity(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_setLatch(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_setMode(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_setBreakFreq(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_setActiveChannel(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_saturationMenu(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_setD0TestEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_FloatingPointMode(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_FloatingPointOffset(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_FloatingPointScaleFactor(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_ChannelStatusEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_CheckPowerOnBIT(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_BITThresholds(int32_t paramCount, int32_t* p_paramas);
static nai_status_t ADBasicOps_toggleNumDisplay(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_setSaturationLow(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_setSaturationHigh(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_enableSaturationLow(int32_t paramCount, int32_t* p_params);
static nai_status_t ADBasicOps_enableSaturationHigh(int32_t paramCount, int32_t* p_params);
static bool_t ADBasicOps_SaturationAvailable(int32_t paramCount, int32_t* p_params);

/* Additional Helper Functions */
static void ADBasicOps_displayStatus(int cardIndex, int module, int channel);

/****** Command Table *******/
/* Invariant: enumeration of cmd table starts from 0 and increments by 1 */
enum ad_basicOps_commands
{
   AD_BASICOPS_CMD_SET_POL_RNG,
   AD_BASICOPS_CMD_SET_BREAK_FREQ,
   AD_BASICOPS_CMD_SET_LATCH,
   AD_BASICOPS_CMD_SET_MODE,
   AD_BASICOPS_CMD_SET_CHANNEL_ACTIVE,
   AD_BASICOPS_CMD_SATURATION_MENU,
   AD_BASICOPS_CMD_SET_D0_TEST_ENABLE,
   AD_BASICOPS_CMD_FLOATING_POINT_MODE,
   AD_BASICOPS_CMD_FLOATING_POINT_OFFSET,
   AD_BASICOPS_CMD_FLOATING_POINT_SCALE_FACTOR,
   AD_BASICOPS_CMD_CHANNEL_STATUS_ENABLE,
   AD_BASICOPS_CMD_PBIT,
   AD_BASICOPS_CMD_BIT_THRESHOLD,
   AD_BASICOPS_CMD_TOGGLE_NUMERIC_DISPLAY,
   AD_BASICOPS_CMD_COUNT
};

enum ad_basicOps_Saturation_commands
{
   AD_BASICOPS_SATURATION_CMD_SET_LOW,
   AD_BASICOPS_SATURATION_CMD_SET_HIGH,
   AD_BASICOPS_SATURATION_CMD_ENABLE_LOW,
   AD_BASICOPS_SATURATION_CMD_ENABLE_HIGH,
   AD_BASICOPS_SATURATION_CMD_COUNT
};

naiapp_cmdtbl_params_t AD_BasicOpsCmds[] =
{
   {"PR",      "Set AD Polarity and Range",                   AD_BASICOPS_CMD_SET_POL_RNG,                              ADBasicOps_setRangePolarity },
   {"BRKFRQ",  "Set AD Filter Break Frequency",               AD_BASICOPS_CMD_SET_BREAK_FREQ,                           ADBasicOps_setBreakFreq     },
   {"M",       "Set AD Voltage/Current Mode (AD4 ONLY)",      AD_BASICOPS_CMD_SET_MODE,                                 ADBasicOps_setMode          },
   {"L",       "Set AD Latch/Unlatch Status",                 AD_BASICOPS_CMD_SET_LATCH,                                ADBasicOps_setLatch         },
   {"AC",      "Set AD Channel Active/Inactive (AD4 ONLY)",   AD_BASICOPS_CMD_SET_CHANNEL_ACTIVE,                       ADBasicOps_setActiveChannel },
   {"SAT",     "Saturation Menu",                             AD_BASICOPS_CMD_SATURATION_MENU,                          ADBasicOps_saturationMenu   },
   {"D0",      "Enable/Configure/Disable D0 Test",            AD_BASICOPS_CMD_SET_D0_TEST_ENABLE,                       ADBasicOps_setD0TestEnable  },
   {"FP_MODE", "Enable/Disable Hardware Floating-Point Conversion Mode",   AD_BASICOPS_CMD_FLOATING_POINT_MODE,         ADBasicOps_FloatingPointMode},
   {"OFFSET",  "Set Hardware Floating-Point Conversion Mode Offset",       AD_BASICOPS_CMD_FLOATING_POINT_OFFSET,       ADBasicOps_FloatingPointOffset},
   {"SCALE",   "Set Hardware Floating-Point Conversion Mode Scale Factor", AD_BASICOPS_CMD_FLOATING_POINT_SCALE_FACTOR, ADBasicOps_FloatingPointScaleFactor},
   {"CHANSTAT","Channel Status Enable/Disable",                            AD_BASICOPS_CMD_CHANNEL_STATUS_ENABLE,       ADBasicOps_ChannelStatusEnable},
   {"PBIT",    "Check Power-On BIT",                          AD_BASICOPS_CMD_PBIT,                                     ADBasicOps_CheckPowerOnBIT  },
   {"THRESH",  "Set BIT Error Threshold",                     AD_BASICOPS_CMD_BIT_THRESHOLD,                            ADBasicOps_BITThresholds    },
   {"TND",     "Toggle Numeric Display",                      AD_BASICOPS_CMD_TOGGLE_NUMERIC_DISPLAY,                   ADBasicOps_toggleNumDisplay } };

naiapp_cmdtbl_params_t AD_BasicOps_SaturationCmds[] =
{
   {"SL",    "Set Saturation Low value",                    AD_BASICOPS_SATURATION_CMD_SET_LOW,        ADBasicOps_setSaturationLow },
   {"SH",    "Set Saturation High value",                   AD_BASICOPS_SATURATION_CMD_SET_HIGH,       ADBasicOps_setSaturationHigh },
   {"EL",    "Enable/Disable Saturation Low",               AD_BASICOPS_SATURATION_CMD_ENABLE_LOW,     ADBasicOps_enableSaturationLow },
   {"EH",    "Enable/Disable Saturation High",              AD_BASICOPS_SATURATION_CMD_ENABLE_LOW,     ADBasicOps_enableSaturationHigh },
};

/*****************************************************************************/
/**
 * <summary>
 * The purpose of the AD_BasicOps is to illustrate the methods to call in the
 * naibrd library to perform basic operations with the AD modules for
 * configuration setup and reading the channels.
 *
 * The following system configuration routines from the nai_sys_cfg.c file are
 * called to assist with the configuration setup for this program prior to
 * calling the naibrd AD routines.
 * - ConfigDevice
 * - DisplayDeviceCfg
 * - GetBoardSNModCfg
 * - CheckModule
 * </summary>
 */
 /*****************************************************************************/
#if defined (__VXWORKS__)
int32_t AD_BasicOps(void)
#else
int32_t main(void)
#endif
{
   bool_t bQuit = FALSE;
   int32_t cardIndex = -1;
   int32_t module = 0;
   uint32_t modId = 0u;
   int32_t moduleCount;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (!bQuit)
      {
         naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         naibrd_GetModuleCount(cardIndex, &moduleCount);
         naiapp_query_ModuleNumber(moduleCount, 1, &module);
         modId = naibrd_GetModuleID(cardIndex, module);
         bQuit = ADBasicOps_run(cardIndex, module, modId);
      }

      printf("Type the Enter key to exit the program: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   }

   naiapp_access_CloseAllOpenCards();

   return 0;
}
/*****************************************************************************/
/**
 * <summary>
 * ADBasicOps_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 ADBasicOps_run(int32_t cardIndex, int32_t module, uint32_t modId)
{
   bool_t bQuit = FALSE;
   bool_t bCmdFound = FALSE;
   int32_t cmd;
   naiapp_AppParameters_t  ad_basicops_params;
   p_naiapp_AppParameters_t ad_basicOps_params = &ad_basicops_params;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   ad_basicOps_params->cardIndex = cardIndex;
   ad_basicOps_params->module = module;
   ad_basicOps_params->channel = DEFAULT_CHANNEL;
   ad_basicOps_params->maxChannels = naibrd_AD_GetChannelCount(modId);
   ad_basicOps_params->modId = modId;
   ad_basicOps_params->displayHex = FALSE;

   do
   {
      naiapp_utils_LoadParamMenuCommands(AD_BASICOPS_CMD_COUNT, AD_BasicOpsCmds);
      ADBasicOps_displayConfigurations(cardIndex, module, modId, ad_basicOps_params->maxChannels, ad_basicOps_params->displayHex);
      naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_PGM_NAME);
      printf("\n\nPlease enter a command or 'q' to quit:");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
            if (bCmdFound)
            {
               AD_BasicOpsCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)ad_basicOps_params);
            }
            else
            {
               printf("Invalid command entered\n");
            }
         }
      }

   } while (!bQuit);
   return bQuit;
}
/*****************************************************************************/
/**
 * <summary>
 * ADBasicOps_displayConfigurations illustrates the methods to call in the naibrd library
 * to retrieve the basic operation configuration states and status states
 * as well as the current voltage reading for all channels.
 * </summary>
 */
 /*****************************************************************************/
static void ADBasicOps_displayConfigurations(int32_t cardIndex, int32_t module, uint32_t modId, int32_t maxChannels, bool_t displayHex)
{
   int32_t channel;
   float64_t data = 0;
   float64_t range = 0;
   uint32_t rawData = 0u;
   nai_ad_range_mode_t polarity = NAI_AD_GEN5_D0_RANGE_MODE_UNIPOLAR;
   nai_ad_mode_t data_mode = NAI_AD_MODE_VOLTAGE;
   nai_ad_state_t channelActive = NAI_AD_STATE_INACTIVE;
   char* sChannelState = "";
   bool_t latched = FALSE;
   bool_t d0TestEnable = FALSE;
   nai_ad_range_mode_t d0Polarity = NAI_AD_GEN5_D0_RANGE_MODE_UNIPOLAR;
   uint32_t filterBreakFreq = 0u;
   float64_t d0Range = 0.0;
   float64_t d0TestLevel = 0.0;
   uint32_t rawD0TestEnable = 0u;
   uint32_t rawD0Polarity = 0u;
   uint32_t rawD0TestLevel = 0u;
   float64_t offset = 0.0;
   float64_t scale = 0.0;
   bool_t fpCapable = FALSE;
   bool_t floatMode = FALSE;

   if (modId == NAI_MODULE_ID_AD4)
   {
      printf("\n\n =================================================================================================================================\n");
      printf(" Chan  Chan     Mode      Volt/Curr  Range     Polarity    Break   Chan   BIT Status   Open Status  Summary Status   FP       FP\n");
      printf("       State                                               Freq   Status    (R/L)         (R/L)          (R/L)     Offset    Scale\n");
      printf(" ---------------------------------------------------------------------------------------------------------------------------------\n");
   }
   else
   {
      printf("\n\n ====================================================================================================================\n");
      printf(" Chan       Voltage       Range     Polarity    Break   Chan   BIT Status   Open Status  Summary Status   FP       FP\n");
      printf("                                                Freq   Status    (R/L)         (R/L)          (R/L)     Offset    Scale\n");
      printf(" ----------------------------------------------------------------------------------------------------------------------\n");
   }

   for (channel = 1; channel <= maxChannels; channel++)
   {
      /*** Acquire values stored in selected channel ***/
      check_status(naibrd_AD_GetMode(cardIndex, module, channel, &data_mode));

      printf("  %2d  ", channel);

      if (modId == NAI_MODULE_ID_AD4)
      {
         check_status(naibrd_AD_GetChannelState(cardIndex, module, channel, &channelActive));

         if (FALSE == channelActive)
         {
            sChannelState = "INACTIVE";
         }
         else
         {
            sChannelState = " ACTIVE ";
         }
         printf("%8s ", sChannelState);
      }

      if (displayHex)
      {
         check_status(naibrd_AD_GetChannelRaw(cardIndex, module, channel, NAI_AD_CHAN_RAW_DATA, &rawData));
         if (modId == NAI_MODULE_ID_AD4 && data_mode == NAI_AD_MODE_CURRENT)
         {
            printf("Current   0x%08X ", rawData);
         }
         else if (modId == NAI_MODULE_ID_AD4 && data_mode == NAI_AD_MODE_VOLTAGE)
         {
            printf("Voltage   0x%08X ", rawData);
         }
         else
         {
            printf("0x%08X ", rawData);
         }
      }
      else
      {
         check_status(naibrd_AD_GetVoltage(cardIndex, module, channel, &data));
         if (modId == NAI_MODULE_ID_AD4 && data_mode == NAI_AD_MODE_CURRENT)
         {
            printf("Current  %10.6fA ", data);
         }
         else
         {
            if (modId == NAI_MODULE_ID_AD4 && data_mode == NAI_AD_MODE_VOLTAGE)
               printf("Voltage  %10.6fV ", data);
            else
               printf("%10.6fV     ", data);
         }
      }

      check_status(naibrd_AD_GetRange(cardIndex, module, channel, &polarity, &range));
      printf("%6.2f     ", range);

      if (polarity == NAI_AD_RANGE_MODE_UNIPOLAR)
         printf("UNIPOLAR");
      else if (polarity == NAI_AD_RANGE_MODE_BIPOLAR)
         printf("BIPOLAR ");
      else
         printf("ERROR   ");

      check_status(naibrd_AD_GetBreakFrequency(cardIndex, module, channel, &filterBreakFreq));
      printf("%6u   ", filterBreakFreq);

      ADBasicOps_displayStatus(cardIndex, module, channel);

      check_status(naibrd_GetFloatingPointModeCapability(cardIndex, module, &fpCapable));
      if (fpCapable == TRUE)
      {
         check_status(naibrd_AD_GetFloatingPointOffset(cardIndex, module, channel, &offset));
         check_status(naibrd_AD_GetFloatingPointScaleFactor(cardIndex, module, channel, &scale));
         printf("    %7.3f   %7.3f", offset, scale);
      }
      else
      {
         printf("     N/A         N/A");
      }
      printf("\n");
   }

   printf("\n\nLatch Status (all channels): ");
   check_status(naibrd_AD_GetLatch(cardIndex, module, &latched));
   if (FALSE == latched)
   {
      printf("UNLATCHED\n");
   }
   else
   {
      printf("LATCHED\n");
   }

   if (fpCapable == TRUE)
   {
      check_status(naibrd_GetRunningInFloatingPointMode(cardIndex, module, &floatMode));
      if (floatMode == TRUE)
      {
         printf("Floating-Point Mode: ENABLED\n");
      }
      else
      {
         printf("Floating-Point Mode: DISABLED\n");
      }
   }

   if (displayHex)
   {
      printf("D0 Test (all channels): Internal Test Enable: ");
      check_status(naibrd_AD_GetRaw(cardIndex, module, NAI_AD_RAW_TEST_ENABLE, &rawD0TestEnable));
      check_status(naibrd_AD_GetRaw(cardIndex, module, NAI_AD_RAW_D0_RANGE_POLARITY, &rawD0Polarity));
      check_status(naibrd_AD_GetRaw(cardIndex, module, NAI_AD_RAW_D0_TEST_VALUE, &rawD0TestLevel));
      printf("0x%02X, Range/Polarity: 0x%02X, ", rawD0TestEnable, rawD0Polarity);
      printf("Voltage Level: 0x%08X\n", rawD0TestLevel);
   }
   else
   {
      printf("D0 Test (all channels): ");
      check_status(naibrd_AD_GetTestEnable(cardIndex, module, NAI_AD_D0_TEST, &d0TestEnable));
      if (FALSE == d0TestEnable)
      {
         printf("DISABLED\n");
      }
      else
      {
         check_status(naibrd_AD_GetD0TestSettings(cardIndex, module, &d0Polarity, &d0Range, &d0TestLevel));
         printf("ENABLED, Range:%6.2lfV, Mode: ", d0Range);
         if (NAI_AD_GEN5_D0_RANGE_MODE_UNIPOLAR == d0Polarity)
         {
            printf("UNIPOLAR");
         }
         else
         {
            printf("BIPOLAR");
         }
         printf(", Voltage Level:%10.6lfV\n", d0TestLevel);
      }
   }
}
/*****************************************************************************/
/**
 * <summary>
 * ADBasicOps_setRangePolarity handles the user request to set the configuration states
 * of Range and Polarity for the selected channel.
 * </summary>
 */
 /*****************************************************************************/
static nai_status_t ADBasicOps_setRangePolarity(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   float64_t range = 0.0;
   nai_ad_range_mode_t polarity = NAI_AD_GEN5_D0_RANGE_MODE_UNIPOLAR;
   bool_t bQuit = FALSE;
   nai_ad_mode_t mode = NAI_AD_MODE_VOLTAGE;
   nai_status_t status = NAI_ERROR_UNKNOWN;

   if (APP_PARAM_COUNT == paramCount)
   {
      bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));

      if (!bQuit)
      {
         naibrd_AD_GetMode(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, &mode);

         if (FALSE == p_ad_params->displayHex)
         {
            ADUtils_GetPolarityRange(p_ad_params->cardIndex, p_ad_params->module, mode, &polarity, &range);
            naibrd_AD_SetRange(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, polarity, range);
         }
         else
         {
            ADModule_GetHexPolarityRange(p_ad_params->cardIndex, p_ad_params->module, &mode, &range);
            naibrd_AD_SetRange(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, polarity, range);
         }
      }

      status = NAI_SUCCESS;
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}
/*****************************************************************************/
/**
 * <summary>
 * ADBasicOps_setLatch handles the user request to set the latch on all channel readings.
 * </summary>
 */
 /*****************************************************************************/
static nai_status_t ADBasicOps_setLatch(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t latched = FALSE;
   bool_t bQuit = FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      printf("Type 'L' to LATCH, or press any other key to UNLATCH all channels:\n>>");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (toupper(inputBuffer[0]) == 'L')
            latched = TRUE;
         else
            latched = FALSE;

         check_status(naibrd_AD_SetLatch(p_ad_params->cardIndex, p_ad_params->module, latched));
      }
      status = NAI_SUCCESS;
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}
/*****************************************************************************/
/**
 * <summary>
 * ADBasicOps_setMode handles the user request to set the configuration states
 * of Mode for the selected channel.
 * </summary>
 */
 /*****************************************************************************/
static nai_status_t ADBasicOps_setMode(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   int channel;
   nai_status_t status = NAI_SUCCESS;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      if (p_ad_params->modId == NAI_MODULE_ID_AD4)
      {
         printf("\nType   'V' for voltage mode\n");
         printf("       'C' for current mode\n");
         printf("       'VA' to set all chan to voltage mode\n");
         printf("       'CA' to set all chan to current mode\n>>");

         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (toupper(inputBuffer[0]) == 'V')
            {
               if (toupper(inputBuffer[1]) == 'A')
               {
                  for (channel = 1; channel <= p_ad_params->maxChannels; channel++)
                     status = naibrd_AD_SetMode(p_ad_params->cardIndex, p_ad_params->module, channel, NAI_AD_MODE_VOLTAGE);
               }
               else
               {
                  bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
                  if (!bQuit)
                  {
                     status = naibrd_AD_SetMode(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, NAI_AD_MODE_VOLTAGE);
                  }
               }
            }
            else if (toupper(inputBuffer[0]) == 'C')
            {
               if (toupper(inputBuffer[1]) == 'A')
               {
                  for (channel = 1; channel <= p_ad_params->maxChannels; channel++)
                     status = naibrd_AD_SetMode(p_ad_params->cardIndex, p_ad_params->module, channel, NAI_AD_MODE_CURRENT);
               }
               else
               {
                  bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
                  if (!bQuit)
                  {
                     status = naibrd_AD_SetMode(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, NAI_AD_MODE_CURRENT);
                  }
               }
            }

            printf("Returned status %s\n", nai_GetStatusString(status));
         }
      }
      else
      {
         printf("Mode selection only available for AD4\n");
         status = NAI_ERROR_NOT_SUPPORTED;
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/*****************************************************************************/
/**
 * <summary>
 * ADBasicOps_setBreakFreq handles the user request to set the
 * filter break frequency for the selected channel.
 * </summary>
 */
 /*****************************************************************************/
static nai_status_t ADBasicOps_setBreakFreq(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   uint32_t filterBreakFrequency = 0u;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));

      printf("Enter new Filter Break Frequency: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         sscanf((const char*)inputBuffer, "%u", &filterBreakFrequency);
         check_status(naibrd_AD_SetBreakFrequency(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel,
            filterBreakFrequency));
      }
   }

   return NAI_SUCCESS;
}

/*****************************************************************************/
/**
 * <summary>
 * ADBasicOps_setActiveChannel handles the user request to set the
 * active/inactive state for the selected channel.
 * </summary>
 */
 /*****************************************************************************/
static nai_status_t ADBasicOps_setActiveChannel(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   int32_t channel = 0;
   nai_status_t status = NAI_SUCCESS;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      printf("\nType 'A' to set channel to ACTIVE\n");
      printf("Type 'I' to set channel to INACTIVE\n");
      printf("Type 'CA' to set all channels to ACTIVE\n");
      printf("Type 'CI' to set all channels to INACTIVE\n");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if ((!bQuit) && (inputResponseCnt > 0))
      {
         if (toupper(inputBuffer[0]) == 'A')
         {
            bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
            if (!bQuit)
            {
               status = naibrd_AD_SetChannelState(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, TRUE);
            }
         }
         else if (toupper(inputBuffer[0]) == 'I')
         {
            bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
            if (!bQuit)
            {
               status = naibrd_AD_SetChannelState(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, FALSE);
            }
         }
         else if (toupper(inputBuffer[0]) == 'C')
         {
            if (toupper(inputBuffer[1]) == 'A')
            {
               for (channel = 1; channel <= p_ad_params->maxChannels; channel++)
               {
                  if (status == NAI_SUCCESS)
                  {
                     status = naibrd_AD_SetChannelState(p_ad_params->cardIndex, p_ad_params->module, channel, TRUE);
                  }
                  else
                  {
                     naibrd_AD_SetChannelState(p_ad_params->cardIndex, p_ad_params->module, channel, TRUE);
                  }
               }
            }
            else if (toupper(inputBuffer[1]) == 'I')
            {
               for (channel = 1; channel <= p_ad_params->maxChannels; channel++)
               {
                  if (status == NAI_SUCCESS)
                  {
                     status = naibrd_AD_SetChannelState(p_ad_params->cardIndex, p_ad_params->module, channel, FALSE);
                  }
                  else
                  {
                     naibrd_AD_SetChannelState(p_ad_params->cardIndex, p_ad_params->module, channel, FALSE);
                  }
               }
            }
            else
            {
               status = NAI_ERROR_INVALID_VALUE;
            }
         }
         else
         {
            status = NAI_ERROR_INVALID_VALUE;
         }
         printf("Returned status %s\n", nai_GetStatusString(status));
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/*****************************************************************************/
/**
 * <summary>
 * ADBasicOps_setD0TestEnable handles the user request to set the D0 Test
 * Enabled/Disabled State and configure the D0 Test Settings. The only range
 * available is the 10V range. Valid range modes are unipolar and bipolar.
 * The D0 Test Level can also be set.
 * </summary>
 */
 /*****************************************************************************/
static nai_status_t ADBasicOps_setD0TestEnable(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   nai_ad_range_mode_t polarity = NAI_AD_RANGE_MODE_UNIPOLAR;
   nai_ad_mode_t D0mode;
   float64_t testLevel = 0.0;
   float64_t D0Range = 0.0;
   uint32_t rawD0RangePolarity = 0u;
   uint32_t rawD0TestLevel = 0u;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      printf("Type 'D' to DISABLE the D0 Test, or press any other key to ENABLE the D0 Test:\n>>");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if ((inputResponseCnt > 0) && (toupper(inputBuffer[0]) == 'D'))
         {
            check_status(naibrd_AD_SetTestEnable(p_ad_params->cardIndex, p_ad_params->module, NAI_AD_D0_TEST, FALSE));
         }
         else
         {
            check_status(naibrd_AD_SetTestEnable(p_ad_params->cardIndex, p_ad_params->module, NAI_AD_D0_TEST, TRUE));
            printf("\n\nConfigure the D0 test Polarity and Voltage level.\n");
            printf("**NOTE: Channels that are not set to the same Range and Polarity as D0 will not be scaled the same,\n");
            printf("  and will show unexpected readings.\n");
            printf("D0 range is always 10V, but the Polarity is configurable.\n");

            if (p_ad_params->displayHex)
            {
               printf("\nType Raw D0 Test Range/Polarity Mode to set:\n>>");
               bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               if ((!bQuit) && (inputResponseCnt > 0))
               {
                  sscanf((const char*)inputBuffer, "%X", &rawD0RangePolarity);
                  check_status(naibrd_AD_SetRaw(p_ad_params->cardIndex, p_ad_params->module, NAI_AD_RAW_D0_RANGE_POLARITY,
                     rawD0RangePolarity));
                  printf("\nType Raw D0 Test Voltage Level to set:\n>>");
                  bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
                  if ((!bQuit) && (inputResponseCnt > 0))
                  {
                     sscanf((const char*)inputBuffer, "%X", &rawD0TestLevel);
                     check_status(naibrd_AD_SetRaw(p_ad_params->cardIndex, p_ad_params->module, NAI_AD_RAW_D0_TEST_VALUE,
                        rawD0TestLevel));
                  }
               }
            }
            else
            {
               printf("Type 'U' to set the D0 Test Polarity to UNIPOLAR, or press any other key for BIPOLAR:\n>>");
               bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               if (!bQuit)
               {
                  if ((inputResponseCnt > 0) && (toupper(inputBuffer[0]) == 'U'))
                  {
                     polarity = NAI_AD_RANGE_MODE_UNIPOLAR;
                     rawD0RangePolarity = (uint32_t)NAI_AD_GEN5_D0_RANGE_MODE_UNIPOLAR;
                  }
                  else
                  {
                     polarity = NAI_AD_RANGE_MODE_BIPOLAR;
                     rawD0RangePolarity = (uint32_t)NAI_AD_GEN5_D0_RANGE_MODE_BIPOLAR;
                  }
                  printf("Type the D0 Test Voltage Level you want to set:\n>>");
                  bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
                  if ((!bQuit) && (inputResponseCnt > 0))
                  {
                     sscanf((const char*)inputBuffer, "%lf", &testLevel);
                     if ((p_ad_params->modId == NAI_MODULE_ID_AD3) || (p_ad_params->modId == NAI_MODULE_ID_ADG))
                     {
                        D0mode = NAI_AD_MODE_CURRENT;
                     }
                     else
                     {
                        D0mode = NAI_AD_MODE_VOLTAGE;
                     }
                     naibrd_AD_ConvertToVoltageRange(p_ad_params->modId, rawD0RangePolarity, &D0mode, &D0Range);
                     check_status(naibrd_AD_ConfigureD0Test(p_ad_params->cardIndex, p_ad_params->module, polarity, D0Range, testLevel));
                  }
               }
            }
         }
      }

      status = NAI_SUCCESS;
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/*****************************************************************************/
/**
 * <summary>
 * ADBasicOps_displayStatus prints to stdin the range mode, BIT status, and Open Status in
 * a format thats fits the table produced in displayChannelCfg.
 * </summary>
 */
 /*****************************************************************************/
static void ADBasicOps_displayStatus(int cardIndex, int module, int channel)
{
   nai_status_bit_t bitStatusRT, bitStatusLT;
   nai_status_bit_t openStatusRT, openStatusLT;
   nai_status_bit_t summaryStatusRT, summaryStatusLT;
   nai_status_bit_t chanStatusEnabled;

   check_status(naibrd_AD_GetChanStatusEnable(cardIndex, module, channel, &chanStatusEnabled));
   printf("   %s  ", (chanStatusEnabled == FALSE) ? "NO " : "YES");

   check_status(naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_BIT_REALTIME, &bitStatusRT));
   check_status(naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_BIT_LATCHED, &bitStatusLT));
   printf("     %d/%d", (bitStatusRT == NAI_STATUS_BIT_HI ? 1 : 0), (bitStatusLT == NAI_STATUS_BIT_HI ? 1 : 0));

   check_status(naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_OPEN_OVERVOLT_REALTIME, &openStatusRT));
   check_status(naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_OPEN_OVERVOLT_LATCHED, &openStatusLT));
   printf("           %d/%d", (openStatusRT == NAI_STATUS_BIT_HI ? 1 : 0), (openStatusLT == NAI_STATUS_BIT_HI ? 1 : 0));

   check_status(naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_SUMMARY_REALTIME, &summaryStatusRT));
   check_status(naibrd_AD_GetStatus(cardIndex, module, channel, NAI_AD_STATUS_SUMMARY_LATCHED, &summaryStatusLT));
   printf("            %d/%d", (summaryStatusRT == NAI_STATUS_BIT_HI ? 1 : 0), (summaryStatusLT == NAI_STATUS_BIT_HI ? 1 : 0));
}

static nai_status_t ADBasicOps_toggleNumDisplay(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   nai_status_t status = NAI_ERROR_UNKNOWN;

   if (APP_PARAM_COUNT == paramCount)
   {
      if (FALSE == p_ad_params->displayHex)
      {
         p_ad_params->displayHex = TRUE;
      }
      else
      {
         p_ad_params->displayHex = FALSE;
      }

      status = NAI_SUCCESS;
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * ADBasicOps_CheckPowerOnBIT() Checks to see if the power-on BIT test
 * has been run on the module. If the PBIT test has run, it checks the result
 * of the test and reports it back.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t ADBasicOps_CheckPowerOnBIT(int32_t paramCount, int32_t* p_params)
{
   nai_status_t status = NAI_ERROR_UNKNOWN;
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t channelCount = 0, channel = 0;
   bool_t pbitComplete;
   nai_status_bit_t bitFailed;

   if (APP_PARAM_COUNT == paramCount)
   {
      switch (p_ad_params->modId)
      {
         case NAI_MODULE_ID_AD1:
         case NAI_MODULE_ID_AD2:
         case NAI_MODULE_ID_AD3:
         case NAI_MODULE_ID_AD4:
         case NAI_MODULE_ID_AD5:
         case NAI_MODULE_ID_AD6:
         case NAI_MODULE_ID_ADE:
         case NAI_MODULE_ID_ADF:
         case NAI_MODULE_ID_ADG:
         {
            channelCount = naibrd_AD_GetChannelCount(p_ad_params->modId);

            /* Check to see if PBIT ran for the module. */
            printf("Checking if the Power-On BIT test has run...\n");
            status = naibrd_GetModulePBITComplete(p_ad_params->cardIndex, p_ad_params->module,p_ad_params->channel, &pbitComplete);
            printf("PBIT Complete: %s", (pbitComplete) ? "COMPLETED\n" : "NOT COMPLETED\n");

            if (pbitComplete)
            {
               /* Read the BIT status */
               printf("Checking the result of the Power-on BIT test...\n");
               for (channel = 1; channel <= channelCount; channel++)
               {
                  status = naibrd_AD_GetStatus(p_ad_params->cardIndex, p_ad_params->module, channel, NAI_AD_STATUS_BIT_LATCHED,
                     &bitFailed);
                  printf("Ch. %d: %s", channel, bitFailed ? "BIT FAILED\n" : "BIT Passed\n");
               }
            }
         }
         break;
      default:
         printf("\n\n****************************************************\n");
         printf("*** This feature is not supported by this module.***\n");
         printf("****************************************************\n");
         status = NAI_ERROR_NOT_SUPPORTED;
         break;
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * ADBasicOps_BITThresholds() allows the user to set and get the BIT error thresholds.
 * This is an advanced feature.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t ADBasicOps_BITThresholds(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   uint32_t bitThreshold = 0u;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      switch (p_ad_params->modId)
      {
         case NAI_MODULE_ID_AD1:
         case NAI_MODULE_ID_AD2:
         case NAI_MODULE_ID_AD3:
         case NAI_MODULE_ID_AD4:
         case NAI_MODULE_ID_AD5:
         case NAI_MODULE_ID_AD6:
         case NAI_MODULE_ID_ADE:
         case NAI_MODULE_ID_ADF:
         case NAI_MODULE_ID_ADG:
         {
            printf("Set or Get BIT Error Threshold? ('S' = Set, 'G' = Get, 'C' = Clear BIT Counter): ");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if (bQuit != FALSE)
            {
               if (inputBuffer[0] == 'S')
               {
                  printf("\nType the desired BIT Error Threshold (Default = 5): ");
                  bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
                  if (bQuit != FALSE)
                  {
                     printf("\n");
                     bitThreshold = atoi((const char*)inputBuffer);
                     status = naibrd_SetModuleBITErrorThreshold(p_ad_params->cardIndex, p_ad_params->module, bitThreshold);
                  }
               }
               else if (inputBuffer[0] == 'G')
               {
                  status = naibrd_GetModuleBITErrorThreshold(p_ad_params->cardIndex, p_ad_params->module, &bitThreshold);
                  printf("\nBIT Error threshold: %d", bitThreshold);
               }
               else if (inputBuffer[0] == 'C')
               {
                  int32_t ch;
                  int32_t channels = naibrd_AD_GetChannelCount(p_ad_params->modId);

                  printf("\nClearing BIT counters on all channels.\n");
                  for (ch = 1; ch <= channels; ch++)
                     status = naibrd_ClearModuleBITLogic(p_ad_params->cardIndex, p_ad_params->module, ch);
               }
               else
               {
                  printf("\nSelection not recognized.\n");
               }
            }
         }
         break;
      default:
         printf("\n\n****************************************************\n");
         printf("*** This feature is not supported by this module.***\n");
         printf("****************************************************\n");
         status = NAI_ERROR_NOT_SUPPORTED;
         break;
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function enables/disables the hardware floating-point conversion mode of the DA module, as specified
 * by the user.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t ADBasicOps_FloatingPointMode(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   bool_t fpCapable = FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      naibrd_GetFloatingPointModeCapability(p_ad_params->cardIndex, p_ad_params->module, &fpCapable);
      if (fpCapable == TRUE)
      {
         printf("Select Floating-Point Mode to set ('0' for DISABLED, '1' for ENABLED)(default:DISABLED): ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if ((!bQuit) && (inputResponseCnt > 0))
         {
            if (inputBuffer[0] == '0')
            {
               status = check_status(naibrd_SetFloatingPointModeEnable(p_ad_params->cardIndex, p_ad_params->module, 0x0));
            }
            else if (inputBuffer[0] == '1')
            {
               status = check_status(naibrd_SetFloatingPointModeEnable(p_ad_params->cardIndex, p_ad_params->module, 0x1));
            }
         }
      }
      else
      {
         printf("\n\n****************************************************\n");
         printf("*** This feature is not supported by this module.***\n");
         printf("****************************************************\n");
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }
   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function sets the hardware floating-point conversion mode offset for the DA channel specified by the
 * user. This function is only applicable when the hardware floating-point conversion mode for the module is
 * enabled.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t ADBasicOps_FloatingPointOffset(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   float64_t offset = 0.0;
   bool_t fpCapable = FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      naibrd_GetFloatingPointModeCapability(p_ad_params->cardIndex, p_ad_params->module, &fpCapable);
      if (fpCapable == TRUE)
      {
         bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
         if (!bQuit)
         {
            printf("Type Hardware Floating-Point Conversion Mode Offset setting to set: ");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if ((!bQuit) && (inputResponseCnt > 0))
            {
               sscanf((const char*)inputBuffer, "%lf", &offset);
               status = check_status(naibrd_AD_SetFloatingPointOffset(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, offset));
            }
         }
      }
      else
      {
         printf("\n\n****************************************************\n");
         printf("*** This feature is not supported by this module.***\n");
         printf("****************************************************\n");
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function sets the hardware floating-point conversion mode scale factor for the DA channel specified by
 * the user. This function is only applicable when the hardware floating-point conversion mode for the module
 * is enabled.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t ADBasicOps_FloatingPointScaleFactor(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   float64_t scale = 0.0;
   bool_t fpCapable = FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      naibrd_GetFloatingPointModeCapability(p_ad_params->cardIndex, p_ad_params->module, &fpCapable);
      if (fpCapable == TRUE)
      {
         bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
         if (!bQuit)
         {
            printf("Type Hardware Floating-Point Conversion Mode Scale Factor setting to set: ");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if ((!bQuit) && (inputResponseCnt > 0))
            {
               sscanf((const char*)inputBuffer, "%lf", &scale);
               status = check_status(naibrd_AD_SetFloatingPointScaleFactor(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, scale));
            }
         }
      }
      else
      {
         printf("\n\n****************************************************\n");
         printf("*** This feature is not supported by this module.***\n");
         printf("****************************************************\n");
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function Enables\Disables the reporting of the Channel Status. When enabled, the user will get status
 * updates. When disabled, the statuses will not report and status-based interrupts will not assert.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t ADBasicOps_ChannelStatusEnable(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      bQuit = naiapp_query_ChannelNumber(ad_params->maxChannels, ad_params->channel, &(ad_params->channel));
      if (!bQuit)
      {
         printf("Enable Channel Status (Y = YES, [any other key] = NO: ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            status = check_status(naibrd_AD_SetChanStatusEnable(ad_params->cardIndex, ad_params->module, ad_params->channel,
               ((inputResponseCnt > 0) && (inputBuffer[0] == 'Y' || inputBuffer[0] == 'y')) ? TRUE : FALSE));
         }
      }
   }

   return status;
}

static void ADBasicOps_displaySaturationConfig(int32_t cardIndex, int32_t module, uint32_t modId, int32_t maxChannels, bool_t displayHex)
{
   int32_t channel;
   float64_t satLowLevel = 0.0;
   float64_t satHighLevel = 0.0;
   bool_t satLowEnable = FALSE;
   bool_t satHighEnable = FALSE;
   char* sChannelState = "";

   /* Unused params */
   modId = 0;
   displayHex = 0;

   printf("\n\n ============================================================================\n");
   printf(" Chan     Saturation Low   Low Enabled |   Saturation High   High Enabled\n");
   printf(" --------------------------------------------------------------------------------\n");

   for (channel = 1; channel <= maxChannels; channel++)
   {
      /*** Acquire values stored in selected channel ***/
      check_status(naibrd_AD_GetSaturationLevel(cardIndex, module, channel, NAI_AD_SATURATION_CONTROL_LOW, &satLowLevel));
      check_status(naibrd_AD_GetSaturationLevel(cardIndex, module, channel, NAI_AD_SATURATION_CONTROL_HIGH, &satHighLevel));
      check_status(naibrd_AD_GetSaturationControl(cardIndex, module, channel, NAI_AD_SATURATION_CONTROL_LOW, &satLowEnable));
      check_status(naibrd_AD_GetSaturationControl(cardIndex, module, channel, NAI_AD_SATURATION_CONTROL_HIGH, &satHighEnable));

      printf("  %2d     ", channel);

      printf("%10.6fV       ", satLowLevel);
      if (FALSE == satLowEnable)
      {
         sChannelState = "  INACTIVE  ";
      }
      else
      {
         sChannelState = "   ACTIVE   ";
      }
      printf("%12s", sChannelState);

      printf("|  %10.6fV       ", satHighLevel);
      if (FALSE == satHighEnable)
      {
         sChannelState = "  INACTIVE  ";
      }
      else
      {
         sChannelState = "   ACTIVE   ";
      }
      printf("%12s\n", sChannelState);
   }
}

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

   if (TRUE == ADBasicOps_SaturationAvailable(paramCount, p_params))
   {
      if (APP_PARAM_COUNT == paramCount)
      {
         naiapp_utils_LoadParamMenuCommands(AD_BASICOPS_SATURATION_CMD_COUNT, AD_BasicOps_SaturationCmds);
         do
         {
            ADBasicOps_displaySaturationConfig(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->modId, p_ad_params->maxChannels, p_ad_params->displayHex);
            naiapp_display_ParamMenuCommands((int8_t*)SATURATION_MENU);
            printf("\n\nPlease enter a command or 'q' to quit:");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if (!bQuit)
            {
               if (inputResponseCnt > 0)
               {
                  bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
                  if (bCmdFound)
                  {
                     AD_BasicOps_SaturationCmds[cmd].func(APP_PARAM_COUNT, p_params);
                  }
                  else
                  {
                     printf("Invalid command entered\n");
                  }
               }
            }
         } while (!bQuit);
         status = NAI_SUCCESS;
      }
      else
      {
         status = NAI_ERROR_INVALID_VALUE;
      }
   }
   else
   {
      printf("\n\n***Saturation is not supported by this module.***\n");
   }

   return status;
}

static nai_status_t ADBasicOps_setSaturationLow(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit;
   int8_t userInput[15];
   float64_t satLevel = 0.0;
   nai_status_t status = NAI_ERROR_UNKNOWN;

   if (APP_PARAM_COUNT == paramCount)
   {
      bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
      if (!bQuit)
      {
         printf("Enter Saturation Low value:");

         memset(userInput, 0x00, sizeof(userInput));
         naiapp_fgets_stdin(userInput, sizeof(userInput));

         sscanf((const char*)userInput, "%lf", &satLevel);

         status = naibrd_AD_SetSaturationLevel(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, NAI_AD_SATURATION_CONTROL_LOW,
            satLevel);
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

static nai_status_t ADBasicOps_setSaturationHigh(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit;
   int8_t userInput[15];
   float64_t satLevel = 0.0;
   nai_status_t status = NAI_ERROR_UNKNOWN;

   if (APP_PARAM_COUNT == paramCount)
   {
      bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
      if (!bQuit)
      {
         printf("Enter Saturation High value:");

         memset(userInput, 0x00, sizeof(userInput));
         naiapp_fgets_stdin(userInput, sizeof(userInput));

         sscanf((const char*)userInput, "%lf", &satLevel);

         status = naibrd_AD_SetSaturationLevel(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel, NAI_AD_SATURATION_CONTROL_HIGH,
            satLevel);
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

static nai_status_t ADBasicOps_enableSaturationLow(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
      if (!bQuit)
      {
         printf("Type 'E' to ENABLE Low-Level Saturation, or press any other key to DISABLE it:\n>>");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if ((!bQuit) && (inputResponseCnt > 0))
         {
            if (toupper(inputBuffer[0]) == 'E')
            {
               check_status(naibrd_AD_SetSaturationControl(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel,
                  NAI_AD_SATURATION_CONTROL_LOW, TRUE));
            }
            else
            {
               check_status(naibrd_AD_SetSaturationControl(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel,
                  NAI_AD_SATURATION_CONTROL_LOW, FALSE));
            }
         }
      }
      status = NAI_SUCCESS;
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

static nai_status_t ADBasicOps_enableSaturationHigh(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   bool_t bQuit = FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      bQuit = naiapp_query_ChannelNumber(p_ad_params->maxChannels, p_ad_params->channel, &(p_ad_params->channel));
      if (!bQuit)
      {
         printf("Type 'E' to ENABLE High-Level Saturation, or press any other key to DISABLE it:\n>>");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if ((!bQuit) && (inputResponseCnt > 0))
         {
            if (toupper(inputBuffer[0]) == 'E')
            {
               check_status(naibrd_AD_SetSaturationControl(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel,
                  NAI_AD_SATURATION_CONTROL_HIGH, TRUE));
            }
            else
            {
               check_status(naibrd_AD_SetSaturationControl(p_ad_params->cardIndex, p_ad_params->module, p_ad_params->channel,
                  NAI_AD_SATURATION_CONTROL_HIGH, FALSE));
            }
         }
      }
      status = NAI_SUCCESS;
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

static bool_t ADBasicOps_SaturationAvailable(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   uint32_t fpgaRev = 0u;
   uint32_t supportedRev = 0xFFFFFFFFu;
   bool_t retVal = FALSE;
   uint32_t modprocrev;

   check_status(naibrd_GetModuleRev(p_ad_params->cardIndex, p_ad_params->module, &modprocrev, &fpgaRev));

   /* Unused params */
   paramCount = 0;

   switch (p_ad_params->modId)
   {
   case NAI_MODULE_ID_AD1:
   case NAI_MODULE_ID_AD2:
   case NAI_MODULE_ID_AD3:
      supportedRev = NAIAPPS_AD123_SATURATION_SUPPORT_FPGA_REV;
      retVal = TRUE;
      break;
   case NAI_MODULE_ID_AD4:
   case NAI_MODULE_ID_AD5:
   case NAI_MODULE_ID_AD6:
      supportedRev = NAIAPPS_AD456_SATURATION_SUPPORT_FPGA_REV;
      retVal = TRUE;
      break;
   case NAI_MODULE_ID_ADE:
   case NAI_MODULE_ID_ADF:
   case NAI_MODULE_ID_ADG:
      supportedRev = NAIAPPS_ADEFG_SATURATION_SUPPORT_FPGA_REV;
      retVal = TRUE;
      break;
   default:
      retVal = FALSE;
      break;
   }

   if ((retVal == TRUE) && (fpgaRev < supportedRev))
   {
      retVal = FALSE;
   }

   return retVal;
}

Help Bot

X