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

DA BasicOps

DA BasicOps Sample Application (SSK 1.x)

Overview

The DA BasicOps sample application demonstrates how to configure and drive digital-to-analog output channels using the NAI Software Support Kit (SSK 1.x). It covers the core DA operations you will need in your own application: setting output voltage or current data, configuring range and polarity, selecting the operating mode (voltage or current), enabling D3 self-test, managing floating-point conversion mode, controlling the power supply, strobing the watchdog timer, and reading BIT diagnostics.

This sample supports a wide range of DA module types across two hardware generations:

  • Gen3 modules: F1, F3, F5, J3, J5, J8 — these modules expose 6 basic commands (data, range, polarity, clear status, clear all statuses, reset to zero).

  • Gen5 modules: DA1, DA2, DA3, DA4, DA5 — these modules expose up to 16 commands, adding operating mode selection, power supply control, floating-point conversion, D3 self-test, BIT thresholds, channel status enable, and watchdog timer management.

  • Combination (CM) modules: CME, CMF, and CMG include DA functionality and are supported by the same naibrd_DA_*() API calls.

This guide serves as a practical API reference — each menu command maps directly to one or more naibrd_DA_*() API calls that you can lift into your own code.

Note
For DA waveform generation via FIFO playback, see the DA FunctionGenerator guide. This guide covers static output configuration only.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a DA module installed (F1, F3, F5, J3, J5, J8, DA1—​DA5, or a CM module with DA functionality: CME, CMF, CMG).

  • 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 DA_BasicOps executable from your build output directory. On startup the application looks for a configuration file (default_DA_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 DA 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 DA. For details on board connection configuration, see the First Time Setup Guide.

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

  1. Call naiapp_RunBoardMenu() to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_DA_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 DA variant installed.

#if defined (__VXWORKS__)
int32_t DA_BasicOps(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

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

   naiapp_access_CloseAllOpenCards();
   return 0;
}
Important

Common connection errors you may encounter at this stage:

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

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

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

  • Module not present at selected slot — the slot you selected does not contain a DA 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 DA_BasicOps() — the SSK 1.x build system selects the correct variant via a preprocessor guard:

#if defined (__VXWORKS__)
int32_t DA_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 Run_DA_BasicOps() 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 Run_DA_BasicOps() 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:

da_basicops_params->cardIndex = cardIndex;
da_basicops_params->module = module;
da_basicops_params->modId = modId;
da_basicops_params->maxChannels = naibrd_DA_GetChannelCount(modId);
da_basicops_params->channel = DEF_DA_CHANNEL;
naibrd_GetBoardGen(cardIndex, &generation);
  • cardIndex — identifies which board in a multi-board system.

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

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

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

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

  • generation — the board generation (Gen3 or Gen5), retrieved by naibrd_GetBoardGen(). This determines which command table is loaded.

Module Detection and Command Tables

A key feature of this sample is that it detects the specific DA module variant and loads the appropriate command table. The sample supports five distinct command tables:

switch (modId)
{
   case NAI_MODULE_ID_F1:
   case NAI_MODULE_ID_F3:
   case NAI_MODULE_ID_F5:
   case NAI_MODULE_ID_J3:
   case NAI_MODULE_ID_J5:
   case NAI_MODULE_ID_J8:
      cmdtbl_params = DA_Gen3_StandardOpMenuCmds;
      cmdCount = DA_GEN3_STANDARDOP_CMD_COUNT;
      break;
   case NAI_MODULE_ID_DA1:
   case NAI_MODULE_ID_DA3:
      cmdtbl_params = DA_Gen5_DA1_DA3_StandardOpMenuCmds;
      cmdCount = DA_GEN5_DA1_DA3_STANDARDOP_CMD_COUNT;
      break;
   case NAI_MODULE_ID_DA2:
      cmdtbl_params = DA_Gen5_DA2_StandardOpMenuCmds;
      cmdCount = DA_GEN5_DA2_STANDARDOP_CMD_COUNT;
      break;
   case NAI_MODULE_ID_DA4:
      cmdtbl_params = DA_Gen5_DA4_StandardOpMenuCmds;
      cmdCount = DA_GEN5_DA4_STANDARDOP_CMD_COUNT;
      break;
   case NAI_MODULE_ID_DA5:
      cmdtbl_params = DA_Gen5_DA5_StandardOpMenuCmds;
      cmdCount = DA_GEN5_DA5_STANDARDOP_CMD_COUNT;
      break;
}

Gen3 Command Table (F1, F3, F5, J3, J5, J8)

Gen3 modules support 6 basic commands:

Command Description

DATA

Set voltage data

RANGE

Set voltage range

POLARITY

Set range polarity mode (unipolar/bipolar)

CLEAR

Clear DA statuses for a single channel

ALL CLEAR

Clear DA statuses for all channels

SET

Reset all channel outputs to zero

Gen5 Command Table (DA1, DA3)

Gen5 DA1/DA3 modules support 16 commands. Commands marked (Gen5) are not available on Gen3 modules:

Command Description

DATA

Set voltage/current data

RANGE

Set voltage/current range

POLARITY

Set range polarity mode

OPMODE

Set voltage/current operating mode (Gen5)

CLEAR

Clear DA statuses

ALL CLEAR

Clear DA statuses for all channels

SET

Reset all channel outputs to zero

ENABLE

Enable/disable power supply (Gen5)

FLOAT

Enable/disable floating-point mode (Gen5)

OFFSET

Set floating-point offset (Gen5)

SCALE

Set floating-point scale factor (Gen5)

CHANSTAT

Channel status enable/disable (Gen5)

PBIT

Check power-on BIT (Gen5)

THRESH

Get/set BIT error threshold (Gen5)

D3

Enable/disable D3 test (Gen5)

WDT

Watchdog timer submenu (Gen5)

The DA2, DA4, and DA5 tables are similar but differ in which features each variant supports. For example, DA2 and DA5 have Output Enable instead of Operating Mode, DA5 adds Bridge Mode, and DA1/DA5 have module-level power supply control while DA3/DA4 have per-channel power supply control.

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

Output Configuration

This section covers the API calls used to configure DA output behavior: setting the output data value (voltage or current), selecting the full-scale range, choosing unipolar or bipolar polarity, and switching between voltage and current operating mode. These parameters work together — the range and polarity define the output window, and the data value specifies where within that window the output drives.

Set Data (Voltage or Current)

To set the output value on a DA channel in your own application, call naibrd_DA_SetData() with the data type (voltage or current) and the desired output level.

On Gen3 modules and voltage-only Gen5 modules (DA2, DA4), the data type is always NAI_DA_DATA_VOLTAGE. On Gen5 modules that support dual-mode output (DA1, DA3, DA5), the sample first checks the current operating mode with naibrd_DA_GetOpMode() and then sets the data value in the appropriate mode:

nai_da_data_type_t opmode;
float64_t data = 2.0;

/* For DA1/DA3: check the operating mode first */
naibrd_DA_GetOpMode(cardIndex, module, channel, &opmode);

if (opmode == NAI_DA_DATA_VOLTAGE)
{
   /* Set voltage output in volts */
   naibrd_DA_SetData(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE, data);
}
else if (opmode == NAI_DA_DATA_CURRENT)
{
   /* Set current output in milliamps */
   naibrd_DA_SetData(cardIndex, module, channel, NAI_DA_DATA_CURRENT, data);
}

For Gen3 modules or voltage-only Gen5 modules, you can call directly:

/* Voltage-only modules: always pass NAI_DA_DATA_VOLTAGE */
naibrd_DA_SetData(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE, 2.0);
  • cardIndex — identifies the board.

  • module — the slot containing the DA module.

  • channel — the channel to drive.

  • The fourth parameter — NAI_DA_DATA_VOLTAGE or NAI_DA_DATA_CURRENT. On Gen3 and DA2/DA4 modules, only NAI_DA_DATA_VOLTAGE is valid.

  • data — the output value. For voltage mode this is in volts; for current mode this is in milliamps. The valid range depends on the configured range and polarity.

Set Range

To configure the output range on a channel in your own application, call naibrd_DA_SetRange(). The valid range values differ significantly across module types.

The sample preserves the current polarity when changing the range by first reading the existing configuration with naibrd_DA_GetRange():

nai_da_range_t range = 10.0;
nai_da_range_t tempRange;
nai_da_range_mode_t mode;

/* Read the current polarity so we preserve it */
naibrd_DA_GetRange(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE, &mode, &tempRange);

/* Set the new range while keeping the existing polarity */
naibrd_DA_SetRange(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE, mode, range);

On DA1 and DA3 modules, the range can be set independently for voltage and current:

/* Set voltage range on a DA1 */
naibrd_DA_SetRange(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE, mode, 5.0);

/* Set current range on a DA1 */
naibrd_DA_SetRange(cardIndex, module, channel, NAI_DA_DATA_CURRENT, mode, 12.5);
  • cardIndex — identifies the board.

  • module — the slot containing the DA module.

  • channel — the channel to configure.

  • The fourth parameter — NAI_DA_DATA_VOLTAGE or NAI_DA_DATA_CURRENT.

  • mode — the polarity setting (NAI_DA_GEN5_RANGE_MODE_UNIPOLAR or NAI_DA_GEN5_RANGE_MODE_BIPOLAR for Gen5; NAI_DA_GEN3_RANGE_MODE_UNIPOLAR or NAI_DA_GEN3_RANGE_MODE_BIPOLAR for Gen3).

  • range — the full-scale range value. Consult your module’s manual for the list of supported range values.

The following table summarizes the range values supported by each module type as demonstrated in the sample:

Module Voltage Ranges Current Ranges

F1/F3/F5/J3/J5/J8

5V, 10V, 15V, 20V, 25V

N/A (voltage only)

DA1

1.25V, 2.5V, 5V, 10V

3.125mA, 6.25mA, 12.5mA, 25mA

DA2

2.5V, 5V, 10V

N/A (voltage only)

DA3

10V, 20V, 40V

25mA, 50mA, 100mA

DA4

25V, 50V, 100V

N/A (voltage only)

Note
Always consult your module’s manual for the definitive list of supported range values and their precision specifications.

Set Polarity Mode

To configure the polarity mode (unipolar or bipolar) on a channel in your own application, call naibrd_DA_SetRange() with the desired polarity while preserving the current range value.

The polarity determines how the output range maps to output values. In bipolar mode, the output swings from negative full-scale to positive full-scale (e.g., -10V to +10V). In unipolar mode, the output ranges from zero to positive full-scale (e.g., 0V to +10V).

nai_da_range_mode_t polarity = NAI_DA_GEN5_RANGE_MODE_BIPOLAR;
nai_da_range_t rangeRead;
nai_da_range_mode_t tempMode;

/* Read the current range so we preserve it */
naibrd_DA_GetRange(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE, &tempMode, &rangeRead);

/* Set bipolar mode while keeping the existing range */
naibrd_DA_SetRange(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE, polarity, rangeRead);

On DA1 and DA3 modules, polarity can be set independently for voltage and current modes:

/* Set voltage polarity */
naibrd_DA_SetRange(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE,
   NAI_DA_GEN5_RANGE_MODE_BIPOLAR, rangeRead);

/* Set current polarity */
naibrd_DA_SetRange(cardIndex, module, channel, NAI_DA_DATA_CURRENT,
   NAI_DA_GEN5_RANGE_MODE_UNIPOLAR, rangeRead);

For Gen3 modules, the polarity constants are different:

/* Gen3: '4' for Unipolar, '0' for Bipolar */
naibrd_DA_SetRange(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE,
   NAI_DA_GEN3_RANGE_MODE_BIPOLAR, rangeRead);
  • NAI_DA_GEN5_RANGE_MODE_UNIPOLAR (0) / NAI_DA_GEN5_RANGE_MODE_BIPOLAR (1) — Gen5 polarity constants.

  • NAI_DA_GEN3_RANGE_MODE_BIPOLAR (0) / NAI_DA_GEN3_RANGE_MODE_UNIPOLAR (4) — Gen3 polarity constants.

Note
The polarity constant values differ between Gen3 and Gen5. Using the wrong constant set for your module generation will produce unexpected behavior. Always use the generation-appropriate constants.

Set Operating Mode (Gen5 — DA1, DA3, DA5)

To switch a channel between voltage and current output mode in your own application, call naibrd_DA_SetOpMode(). This feature is exclusive to Gen5 modules that support dual-mode output (DA1, DA3, and DA5). Calling it on DA2, DA4, or any Gen3 module prints "This feature is not supported by this module."

nai_da_data_type_t mode = NAI_DA_DATA_VOLTAGE;

/* Set a channel to voltage output mode */
naibrd_DA_SetOpMode(cardIndex, module, channel, NAI_DA_DATA_VOLTAGE);

/* Set a channel to current output mode */
naibrd_DA_SetOpMode(cardIndex, module, channel, NAI_DA_DATA_CURRENT);
  • cardIndex — identifies the board.

  • module — the slot containing the DA module.

  • channel — the channel to configure.

  • The fourth parameter — NAI_DA_DATA_VOLTAGE (0) or NAI_DA_DATA_CURRENT (1).

When you switch operating mode, the range and polarity settings for the new mode take effect. You should configure the range and polarity for both modes before switching, or reconfigure them after switching, to ensure the output behaves as expected.

Output Enable (Gen5 — DA2, DA5)

To enable or disable the output driver on a specific channel, call naibrd_DA_SetOutputEnable(). This feature is exclusive to DA2 and DA5 modules. When the output is disabled, the channel does not drive any signal regardless of the configured data value.

/* Enable channel output */
naibrd_DA_SetOutputEnable(cardIndex, module, channel, NAI_DA_ENABLE_OUTPUT);

/* Disable channel output */
naibrd_DA_SetOutputEnable(cardIndex, module, channel, NAI_DA_DISABLE_OUTPUT);
  • NAI_DA_ENABLE_OUTPUT (1) — activates the output driver.

  • NAI_DA_DISABLE_OUTPUT (0) — deactivates the output driver.

Bridge Mode (Gen5 — DA5)

To enable or disable full-bridge mode on a DA5 channel, call naibrd_DA_SetFullBridgeMode(). This feature is exclusive to the DA5 module.

/* Enable bridge mode on a channel */
naibrd_DA_SetFullBridgeMode(cardIndex, module, channel, TRUE);

/* Disable bridge mode */
naibrd_DA_SetFullBridgeMode(cardIndex, module, channel, FALSE);

Consult the DA5 module manual for details on how bridge mode affects the output topology and which channel pairs are linked.

Important

Common Errors

  • Output not changing — Verify that the data value you are setting falls within the configured range and polarity window. For example, setting a positive voltage value on a channel configured for unipolar mode with a 5V range will only accept values from 0 to 5V.

  • NAI_ERROR_NOT_SUPPORTED — Returned when attempting to set operating mode on DA2/DA4 or Gen3 modules, output enable on non-DA2/DA5 modules, or bridge mode on non-DA5 modules.

  • Invalid range value — The API validates range values against the module’s supported set. Passing an unsupported range (e.g., 15V on a DA2) will produce an error.

  • Wrong polarity constant — Gen3 and Gen5 use different numeric values for unipolar and bipolar. Using NAI_DA_GEN3_RANGE_MODE_UNIPOLAR (4) on a Gen5 module will fail validation.

Self-Test and Diagnostics

This section covers the built-in self-test and diagnostic features available in the DA BasicOps sample: the D3 test, power-on BIT verification, BIT error thresholds, per-channel status enable, status clearing, and reset-to-zero. These features help you verify that the DA output path is functioning correctly and detect hardware faults early. All features in this section except Clear Status and Reset to Zero are Gen5-only.

D3 Test Enable/Disable (Gen5)

To inject a known test signal into the DA output path in your own application, call naibrd_DA_SetModuleBITEnable() with NAI_DA_D3_TEST to enable or disable the D3 test. The D3 test is analogous to the D0 test on AD modules — it drives a known signal through the conversion path so you can verify end-to-end accuracy by reading back the wrap voltage or current measurement.

/* Enable the D3 test */
naibrd_DA_SetModuleBITEnable(cardIndex, module, NAI_DA_D3_TEST, TRUE);

/* Disable the D3 test */
naibrd_DA_SetModuleBITEnable(cardIndex, module, NAI_DA_D3_TEST, FALSE);
  • cardIndex — identifies the board.

  • module — the slot containing the DA module.

  • NAI_DA_D3_TEST — selects the D3 test type.

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

Note
While the D3 test is active, the module drives a test signal on the output channels. This will override your configured output values. Always disable the D3 test before resuming normal output operations.

Power-On BIT Check (Gen5)

To verify that the module passed its power-on built-in test (PBIT) in your own application, call naibrd_DA_CheckPowerOnBITComplete() to check whether PBIT has run, then iterate over all channels calling naibrd_DA_GetStatus() with NAI_DA_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_DA_GetChannelCount(modId);

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

if (pbitComplete)
{
   /* Step 2: Read BIT status for each channel */
   for (channel = 1; channel <= channelCount; channel++)
   {
      naibrd_DA_GetStatus(cardIndex, module, channel,
         NAI_DA_STATUS_BIT_LATCHED, &bitFailed);
      if (bitFailed)
         printf("Channel %d: BIT FAILED\n", channel);
      else
         printf("Channel %d: BIT Passed\n", channel);
   }
}
  • pbitComplete — set to TRUE if PBIT has finished, FALSE otherwise.

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

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

BIT Error Thresholds (Gen5)

To configure how many BIT errors the module tolerates before flagging a failure in your own application, call naibrd_DA_SetModuleBITErrorThreshold(). To read the current threshold, call naibrd_DA_GetModuleBITErrorThreshold(). To reset BIT counters on a per-channel basis, call naibrd_DA_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_DA_SetModuleBITErrorThreshold(cardIndex, module, 10);

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

/* Clear BIT counters on all channels */
int32_t channelCount = naibrd_DA_GetChannelCount(modId);
for (int32_t ch = 1; ch <= channelCount; ch++)
   naibrd_DA_ClearModuleBITLogic(cardIndex, module, ch);
  • bitThreshold — the number of BIT errors before a failure is reported. Default is 5.

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

Channel Status Enable (Gen5)

To enable or disable status reporting on a per-channel basis in your own application, call naibrd_DA_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_DA_SetChanStatusEnable(cardIndex, module, channel, TRUE);

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

  • module — the slot containing the DA 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.

Clear Status

To clear latched status flags on a single channel in your own application, call naibrd_DA_ClearStatus() on Gen5 modules or naibrd_DA_ClearStatusRaw() on Gen3 modules. The clearable status types are BIT, Overcurrent, and (on Gen5) Summary.

On Gen5 modules:

/* Clear BIT latched status for a single channel */
naibrd_DA_ClearStatus(cardIndex, module, channel, NAI_DA_STATUS_BIT_LATCHED);

/* Clear overcurrent latched status for a single channel */
naibrd_DA_ClearStatus(cardIndex, module, channel, NAI_DA_STATUS_OVERCURRENT_LATCHED);

/* Clear summary latched status for a single channel */
naibrd_DA_ClearStatus(cardIndex, module, channel, NAI_DA_STATUS_SUMMARY_LATCHED);

On Gen3 modules, use the raw variant with a bitmask:

uint32_t mask = 0x1u;
uint32_t shift = channel - 1;

/* Clear BIT latched status for a single channel (Gen3) */
naibrd_DA_ClearStatusRaw(cardIndex, module, NAI_DA_STATUS_BIT_LATCHED, (mask << shift));

Clear Status All Channels

To clear latched status flags on all channels at once, loop over all channels and call the appropriate clear function. On Gen5, the sample also calls naibrd_DA_ResetOverload() when clearing overcurrent statuses:

/* Gen5: clear all status types on all channels */
for (chan = 1; chan <= maxChannels; chan++)
{
   naibrd_DA_ClearStatus(cardIndex, module, chan, NAI_DA_STATUS_BIT_LATCHED);
   naibrd_DA_ClearStatus(cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_LATCHED);
   naibrd_DA_ClearStatus(cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_LATCHED);
}
naibrd_DA_ResetOverload(cardIndex, module);
  • naibrd_DA_ResetOverload() — resets the overcurrent protection logic on the module. This is necessary after clearing overcurrent status flags on Gen5 modules to fully recover from an overcurrent condition.

Reset to Zero (Gen5)

To set all channel outputs on the module to zero in a single call, use naibrd_DA_ResetToZero(). This is a module-wide operation that immediately drives every channel to 0V (or 0mA in current mode).

naibrd_DA_ResetToZero(cardIndex, module);

This function is available on Gen5 modules only. It is useful for safely returning all outputs to a known state — for example, during shutdown or error recovery.

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_DA_CheckPowerOnBITComplete() will report that PBIT has not completed. This is not a hardware failure.

  • D3 test interfering with output — The D3 test overrides the configured output values while active. If your output appears stuck at an unexpected value, check whether D3 is still enabled and disable it with naibrd_DA_SetModuleBITEnable(cardIndex, module, NAI_DA_D3_TEST, FALSE).

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

  • Gen5 commands on Gen3 module — Functions like naibrd_DA_ClearStatus(), naibrd_DA_ResetToZero(), and all BIT/D3/channel-status functions are Gen5-only. On Gen3, use naibrd_DA_ClearStatusRaw() for status clearing and set each channel’s data to 0 individually for a reset-to-zero equivalent.

Floating-Point Conversion

Some DA modules support hardware floating-point conversion, which applies an offset and scale factor to output data values directly in hardware. If your application needs to output calibrated or scaled values with a custom offset or gain applied, enabling floating-point mode lets the hardware handle this transformation rather than doing it in software. The three functions in this section work together: first enable the mode, then configure the offset and scale factor per channel. All three are Gen5-only.

Enable Floating-Point Mode (Gen5)

To enable or disable hardware floating-point conversion on a module, call naibrd_SetFloatingPointModeEnable(). This is a module-wide setting that affects all channels.

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

/* Disable floating-point mode */
naibrd_SetFloatingPointModeEnable(cardIndex, module, FALSE);
  • cardIndex — identifies the board.

  • module — the slot containing the DA module.

  • The third parameter — TRUE (or 0x1) to enable, FALSE (or 0x0) to disable.

When enabled, the module applies the configured offset and scale factor to every output data value before driving the DAC, so the actual output is (data * scale) + offset.

Set Floating-Point Offset (Gen5)

To set the floating-point offset on a per-channel basis, call naibrd_DA_SetFloatingPointOffset(). The offset is added to the scaled output data value when floating-point mode is enabled.

float64_t offset = 1.25;

/* Set the floating-point offset for a specific channel */
naibrd_DA_SetFloatingPointOffset(cardIndex, module, channel, offset);
  • cardIndex — identifies the board.

  • module — the slot containing the DA 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 (Gen5)

To set the floating-point scale factor on a per-channel basis, call naibrd_DA_SetFloatingPointScaleFactor(). The scale factor is multiplied against the output data value when floating-point mode is enabled.

float64_t scaleFactor = 2.0;

/* Set the floating-point scale factor for a specific channel */
naibrd_DA_SetFloatingPointScaleFactor(cardIndex, module, channel, scaleFactor);
  • cardIndex — identifies the board.

  • module — the slot containing the DA module.

  • channel — the channel to configure.

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

Important

Common Errors

  • Unexpected output after enabling floating-point mode — The offset and scale factor must be set to the desired values before or immediately after enabling floating-point mode. If the mode is enabled without configuring these parameters, the default values (typically 0.0 for offset, 1.0 for scale) will apply.

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

  • Floating-point functions not available — These functions require Gen5 hardware. On Gen3 modules, the sample will not display these commands.

Power Supply and Watchdog

This section covers power supply control and watchdog timer management. Both features are Gen5-only. The power supply control enables or disables the analog output stage, while the watchdog timer provides a hardware safety mechanism that automatically shuts down outputs if the controlling software stops responding.

Power Supply Enable/Disable (Gen5)

To control the power supply on a DA module in your own application, use either naibrd_DA_SetPowerSupplyEnable() (for module-level control on DA1 and DA5) or naibrd_DA_SetChannelPowerSupplyEnable() (for per-channel control on DA3 and DA4).

Disabling the power supply shuts down the output stage. The channel’s data register retains its configured value, but no signal is driven on the output. This is useful for power management or as a safety mechanism to ensure outputs are off until your application is ready.

For DA1 and DA5 (module-level power supply):

/* Enable the module power supply */
naibrd_DA_SetPowerSupplyEnable(cardIndex, module, NAI_DA_POWERSUPPLY_CTRL_ENABLE);

/* Disable the module power supply */
naibrd_DA_SetPowerSupplyEnable(cardIndex, module, NAI_DA_POWERSUPPLY_CTRL_DISABLE);

For DA3 and DA4 (per-channel power supply):

/* Enable a specific channel's power supply */
naibrd_DA_SetChannelPowerSupplyEnable(cardIndex, module, channel,
   NAI_DA_POWERSUPPLY_CTRL_ENABLE);

/* Disable a specific channel's power supply */
naibrd_DA_SetChannelPowerSupplyEnable(cardIndex, module, channel,
   NAI_DA_POWERSUPPLY_CTRL_DISABLE);
  • NAI_DA_POWERSUPPLY_CTRL_ENABLE (1) — turns on the power supply.

  • NAI_DA_POWERSUPPLY_CTRL_DISABLE (0) — turns off the power supply.

Note
On DA1 and DA5, naibrd_DA_SetPowerSupplyEnable() controls a single module-wide power supply — all channels are affected simultaneously. On DA3 and DA4, naibrd_DA_SetChannelPowerSupplyEnable() controls individual channel power supplies independently.

Watchdog Timer (Gen5)

The watchdog timer is a hardware safety mechanism that monitors whether the controlling application is actively communicating with the module. If the watchdog is not strobed within the configured time window, the module automatically shuts down all outputs and enters a fault state.

The watchdog submenu in the sample provides four operations:

Command Description

TIME QUIET

Set the watchdog quiet time (ms)

WINDOW

Set the watchdog window time (ms)

STROBE

Start a background thread that continuously strobes the watchdog

KILL

Stop the watchdog strobing thread

Set Quiet Time

The quiet time defines how long the module waits after a strobe before it begins monitoring for the next strobe. To set the quiet time, call naibrd_DA_SetWatchdogQuietTime(). The API accepts the value in microseconds, so the sample multiplies the user-entered millisecond value by 1000:

uint32_t quietTime_ms = 500;

/* Set watchdog quiet time (API expects microseconds) */
naibrd_DA_SetWatchdogQuietTime(cardIndex, module, quietTime_ms * 1000);

Set Window Time

The window time defines how long after the quiet period the module will accept a strobe. If no strobe arrives within this window, a watchdog fault is triggered. To set the window time, call naibrd_DA_SetWatchdogWindow():

uint32_t windowTime_ms = 500;

/* Set watchdog window time (API expects microseconds) */
naibrd_DA_SetWatchdogWindow(cardIndex, module, windowTime_ms * 1000);

Strobe the Watchdog

To keep the watchdog alive, your application must periodically call naibrd_DA_WatchdogStrobe(). The strobe must arrive within the configured window (after the quiet time has elapsed). The sample spawns a background thread that computes the optimal strobe interval as quietTime + (windowTime / 2) and continuously strobes at that rate:

/* Strobe the watchdog once */
naibrd_DA_WatchdogStrobe(cardIndex, module);

In your own application, you would typically strobe the watchdog from a periodic timer or a dedicated thread, timed to land within the window after the quiet period.

Reading Watchdog Status

To check the current watchdog configuration and fault status, call the corresponding get functions:

uint32_t quietTime = 0u;
uint32_t windowTime = 0u;
nai_status_bit_t wdStatLatched = 0u;
nai_status_bit_t wdStatRT = 0u;

naibrd_DA_GetWatchdogQuietTime(cardIndex, module, &quietTime);
naibrd_DA_GetWatchdogWindow(cardIndex, module, &windowTime);

naibrd_DA_GetStatus(cardIndex, module, channel,
   NAI_DA_STATUS_WATCHDOG_TIMER_FAULT_LATCHED, &wdStatLatched);
naibrd_DA_GetStatus(cardIndex, module, channel,
   NAI_DA_STATUS_WATCHDOG_TIMER_FAULT_REALTIME, &wdStatRT);
  • quietTime / windowTime — returned in microseconds. Divide by 1000 for milliseconds.

  • wdStatLatched — non-zero if a watchdog fault has occurred and been latched.

  • wdStatRT — non-zero if a watchdog fault is currently active.

Important

Common Errors

  • Watchdog timeout shutting down outputs — If the watchdog is armed and your application stops strobing (e.g., due to a crash or delay), the module will automatically shut down all outputs. After a watchdog fault, the module may need to be power-cycled to resume operation. The sample warns about this: "When this thread/application exits, the module will shut off all outputs and will need to be power cycled."

  • Strobe arriving outside the window — The strobe must arrive after the quiet time has elapsed but before the window time expires. If your strobe interval is too short (arriving during the quiet period) or too long (missing the window), a fault will trigger. A recommended interval is quietTime + (windowTime / 2).

  • Power supply disabled, no output — If the power supply is disabled, channels will not drive any output even though data, range, and polarity are configured correctly. Verify the power supply state with naibrd_DA_GetPowerSupplyEnable() or naibrd_DA_GetChannelPowerSupplyEnable().

Display Functions

The display function in this sample demonstrates the full set of naibrd_DA_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 DA_DisplayOpData() on every iteration of the command loop to show a live view of the module state.

The display adapts its output format based on the detected module type. The following read-back APIs are used across all Gen5 variants:

float64_t data;
nai_da_range_t voltRange;
nai_da_range_mode_t voltPolarity;
float64_t wrapVolt;
float64_t measuredCurrent;
nai_status_bit_t bitStatLatched, bitStatRealtime;
nai_status_bit_t overCurrentStatLatched, overCurrentStatRealtime;
nai_status_bit_t summaryStatusLatched, summaryStatusRealtime;
float64_t fpOffset, fpScale;

for (chan = 1; chan <= maxchan; chan++)
{
   naibrd_DA_GetData(cardIndex, module, chan, NAI_DA_DATA_VOLTAGE, &data);
   naibrd_DA_GetRange(cardIndex, module, chan, NAI_DA_DATA_VOLTAGE,
      &voltPolarity, &voltRange);
   naibrd_DA_GetWrapVoltage(cardIndex, module, chan, &wrapVolt);
   naibrd_DA_GetCurrentMeasurement(cardIndex, module, chan, &measuredCurrent);

   naibrd_DA_GetStatus(cardIndex, module, chan,
      NAI_DA_STATUS_BIT_LATCHED, &bitStatLatched);
   naibrd_DA_GetStatus(cardIndex, module, chan,
      NAI_DA_STATUS_BIT_REALTIME, &bitStatRealtime);
   naibrd_DA_GetStatus(cardIndex, module, chan,
      NAI_DA_STATUS_OVERCURRENT_LATCHED, &overCurrentStatLatched);
   naibrd_DA_GetStatus(cardIndex, module, chan,
      NAI_DA_STATUS_OVERCURRENT_REALTIME, &overCurrentStatRealtime);

   naibrd_DA_GetFloatingPointOffset(cardIndex, module, chan, &fpOffset);
   naibrd_DA_GetFloatingPointScaleFactor(cardIndex, module, chan, &fpScale);
}

Additional module-specific read-back APIs:

  • DA1/DA3 — naibrd_DA_GetOpMode() returns the current voltage/current operating mode. naibrd_DA_GetRange() with NAI_DA_DATA_CURRENT returns the current-mode range and polarity. DA3 also calls naibrd_DA_GetChannelPowerSupplyEnable() for per-channel power supply state.

  • DA2 — naibrd_DA_GetOutputEnable() returns the channel output enable state. naibrd_DA_GetInternalVoltage() returns the internal reference voltage.

  • DA4 — naibrd_DA_GetChannelPowerSupplyEnable() returns per-channel power supply state.

  • DA5 — naibrd_DA_GetOutputEnable(), naibrd_DA_GetFullBridgeMode(), naibrd_DA_GetExtPowerMeasurement() for external power supply voltages, and naibrd_DA_GetPowerSupplyEnable() for module-level power supply state.

  • Gen3 — Only basic read-back: naibrd_DA_GetData(), naibrd_DA_GetRange(), naibrd_DA_GetWrapVoltage(), naibrd_DA_GetCurrentMeasurement(), and BIT/overcurrent status (no summary status on Gen3).

The status values are displayed in L/R (latched/real-time) format. Real-time reflects the current condition; latched holds the value until explicitly cleared. 0 = normal/pass, 1 = fail/detected.

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

Output not changing after setting data

Data value outside the configured range/polarity window, power supply disabled, output enable off (DA2/DA5)

Verify the range and polarity match the desired output value. Check that the power supply is enabled. On DA2/DA5, verify output enable is active.

Wrong polarity constant values

Using Gen3 polarity constants on Gen5 module or vice versa (the numeric values differ)

Use NAI_DA_GEN5_RANGE_MODE_* constants on Gen5 modules and NAI_DA_GEN3_RANGE_MODE_* on Gen3 modules.

Invalid range value error

Passing a range value not supported by the module variant (e.g., 15V on DA2, 40V on DA1)

Consult the range table above or your module’s manual for supported range values per module type.

D3 test interfering with output

D3 test still enabled — it overrides configured output values with a test signal

Disable the D3 test: naibrd_DA_SetModuleBITEnable(cardIndex, module, NAI_DA_D3_TEST, FALSE).

NAI_ERROR_NOT_SUPPORTED

Feature not available for this module type (e.g., operating mode on DA2/DA4, output enable on DA1/DA3, bridge mode on non-DA5)

Check your module type. Each DA variant supports a different subset of features as listed in the command tables above.

Floating-point mode output 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. The output formula is (data * scale) + offset.

PBIT not complete

Module has not been power-cycled since last boot

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

Watchdog fault shutting down outputs

Application stopped strobing the watchdog, strobe arriving outside the valid window

Verify strobe timing: strobe must arrive after quiet time elapses but before window time expires. Recommended interval: quietTime + (windowTime / 2). Module may require power cycle after fault.

Gen5 command not appearing in menu

Gen3 module detected — Gen3 modules load a reduced command table with only 6 basic commands

Gen5-only features (floating-point, watchdog, D3 test, PBIT, power supply control, operating mode) require a Gen5 DA module (DA1—​DA5).

Power supply disabled, no output

Power supply disabled via naibrd_DA_SetPowerSupplyEnable() or naibrd_DA_SetChannelPowerSupplyEnable()

Check power supply state and re-enable it. On DA1/DA5 this is module-level; on DA3/DA4 it is per-channel.

Full Source

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

Full Source — DA_BasicOps.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#if defined (LINUX)
#include <pthread.h>
#endif

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

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

#define DEF_VOLTAGE           2.0
#define DEF_RANGE             10.0
#define DEF_OUTPUT_TRIGGER    0
#define DEF_SIGNAL_MODE       1
#define DEF_STATUS            0
#define DEF_WRAP_VOLTAGE      0.0
#define DEF_CURRENT           0.0

#define BACK_CHAR 'B'

static const int8_t *CONFIG_FILE = (const int8_t *)"default_DA_BasicOps.txt";
static const int8_t *SAMPLE_WD_PGM_NAME = (const int8_t*)"DA Watchdog Operations";
static bool_t terminateThread;

/* Function prototypes */
static bool_t Run_DA_BasicOps( int32_t cardIndex, int32_t module, int32_t ModuleID );

static nai_status_t Handle_DA_Data(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_ClearStatus(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_ClearStatusAllChannels(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_ResetToZero(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_PowerSupplyEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_Range(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_Polarity(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_OpMode(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_OutputEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_BridgeMode(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_FloatingPointMode(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_FloatingPointOffset(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_FloatingPointScaleFactor(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_ChannelStatusEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_CheckPowerOnBIT(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_SetD3TestEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_BITThresholds(int32_t paramCount, int32_t* p_params);

static nai_status_t Handle_DA_WatchdogShowMenu(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_WatchDogQuietTime(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_WatchDogWindowTime(int32_t paramCount, int32_t* p_params);
static bool_t Handle_DA_DisplayWatchdog(int32_t cardIndex, int32_t module, int32_t chan);
static nai_status_t Handle_DA_StrobeWatchdog(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_kill_WDStrobe_Thread(int32_t paramCount, int32_t* p_params);
static void naiapp_kill_WDStrobe_Thread();
#if defined (WIN32)
DWORD WINAPI WD_Strobe_ThreadEntryPoint(LPVOID param);
#elif defined (LINUX)
void* WD_Strobe_ThreadEntryPoint(void* arg);
#elif defined (__VXWORKS__)
static int WD_Strobe_ThreadEntryPoint(int32_t nParam);
#else
#error Unsupported OS
#endif
/* TX Thread */
#if defined (WIN32)
static HANDLE thread = NULL;
#elif defined (LINUX)
static pthread_t thread;
#elif defined (__VXWORKS__)
static int thread;
#else
#error Unsupported OS
#endif

static void DA_DisplayOpData( int32_t cardIndex, int32_t module, int32_t maxchan, uint32_t damodid );

static const int32_t DEF_DA_CHANNEL       = 1;

static uint32_t generation; /* generation of the board/module */

/****** Command Tables *******/
enum da_gen3_standardop_commands
{
   DA_GEN3_STANDARDOP_CMD_DATA,
   DA_GEN3_STANDARDOP_CMD_RANGE,
   DA_GEN3_STANDARDOP_CMD_POLARITY,
   DA_GEN3_STANDARDOP_CMD_CLEAR_STATUS,
   DA_GEN3_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,
   DA_GEN3_STANDARDOP_CMD_RESET_TO_ZERO,
   DA_GEN3_STANDARDOP_CMD_COUNT
};

enum da_gen5_da1_da3_standardop_commands
{
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_DATA,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_RANGE,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_POLARITY,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_OPMODE,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_CLEAR_STATUS,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_RESET_TO_ZERO,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_POWER_SUPPLY_ENABLE,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_FLOATING_POINT_MODE,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_FLOATING_OFFSET,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_FLOATING_SCALE,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_PBIT,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_BIT_THRESHOLD,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_D3,
   DA_GEN5_BASICOP_CMD_WATCHDOG_MENU,
   DA_GEN5_DA1_DA3_STANDARDOP_CMD_COUNT
};

enum da_gen5_da2_standardop_commands
{
   DA_GEN5_DA2_STANDARDOP_CMD_DATA,
   DA_GEN5_DA2_STANDARDOP_CMD_RANGE,
   DA_GEN5_DA2_STANDARDOP_CMD_POLARITY,
   DA_GEN5_DA2_STANDARDOP_CMD_CLEAR_STATUS,
   DA_GEN5_DA2_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,
   DA_GEN5_DA2_STANDARDOP_CMD_RESET_TO_ZERO,
   DA_GEN5_DA2_STANDARDOP_CMD_OUTPUT_ENABLE,
   DA_GEN5_DA2_STANDARDOP_CMD_FLOATING_POINT_MODE,
   DA_GEN5_DA2_STANDARDOP_CMD_FLOATING_OFFSET,
   DA_GEN5_DA2_STANDARDOP_CMD_FLOATING_SCALE,
   DA_GEN5_DA2_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,
   DA_GEN5_DA2_STANDARDOP_CMD_PBIT,
   DA_GEN5_DA2_STANDARDOP_CMD_BIT_THRESHOLD,
   DA_GEN5_DA2_STANDARDOP_CMD_D3,
   DA_GEN5_DA2_BASICOP_CMD_WATCHDOG_MENU,
   DA_GEN5_DA2_STANDARDOP_CMD_COUNT
};

enum da_gen5_da4_standardop_commands
{
   DA_GEN5_DA4_STANDARDOP_CMD_DATA,
   DA_GEN5_DA4_STANDARDOP_CMD_RANGE,
   DA_GEN5_DA4_STANDARDOP_CMD_POLARITY,
   DA_GEN5_DA4_STANDARDOP_CMD_CLEAR_STATUS,
   DA_GEN5_DA4_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,
   DA_GEN5_DA4_STANDARDOP_CMD_RESET_TO_ZERO,
   DA_GEN5_DA4_STANDARDOP_CMD_POWER_SUPPLY_ENABLE,
   DA_GEN5_DA4_STANDARDOP_CMD_FLOATING_POINT_MODE,
   DA_GEN5_DA4_STANDARDOP_CMD_FLOATING_OFFSET,
   DA_GEN5_DA4_STANDARDOP_CMD_FLOATING_SCALE,
   DA_GEN5_DA4_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,
   DA_GEN5_DA4_STANDARDOP_CMD_PBIT,
   DA_GEN5_DA4_STANDARDOP_CMD_BIT_THRESHOLD,
   DA_GEN5_DA4_STANDARDOP_CMD_D3,
   DA_GEN5_DA4_BASICOP_CMD_WATCHDOG_MENU,
   DA_GEN5_DA4_STANDARDOP_CMD_COUNT
};

enum da_gen5_da5_standardop_commands
{
   DA_GEN5_DA5_STANDARDOP_CMD_DATA,
   DA_GEN5_DA5_STANDARDOP_CMD_POWER_SUPPLY_ENABLE,
   DA_GEN5_DA5_STANDARDOP_CMD_OUTPUT_ENABLE,
   DA_GEN5_DA5_STANDARDOP_CMD_BRIDGE_ENABLE,
   DA_GEN5_DA5_STANDARDOP_CMD_CLEAR_STATUS,
   DA_GEN5_DA5_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,
   DA_GEN5_DA5_STANDARDOP_CMD_FLOATING_POINT_MODE,
   DA_GEN5_DA5_STANDARDOP_CMD_FLOATING_OFFSET,
   DA_GEN5_DA5_STANDARDOP_CMD_FLOATING_SCALE,
   DA_GEN5_DA5_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,
   DA_GEN5_DA5_STANDARDOP_CMD_PBIT,
   DA_GEN5_DA5_STANDARDOP_CMD_BIT_THRESHOLD,
   DA_GEN5_DA5_STANDARDOP_CMD_D3,
   DA_GEN5_DA5_BASICOP_CMD_WATCHDOG_MENU,
   DA_GEN5_DA5_STANDARDOP_CMD_COUNT
};
enum da_watchdog_commands
{
   DA_WD_CMD_QUIETTIME,
   DA_WD_CMD_WINDOWTIME,
   DA_WD_CMD_STROBE,
   DA_WD_CMD_KILL,
   DA_WD_CMD_BACK,
   DA_WD_CMD_COUNT
};

/****** Command Tables *******/
naiapp_cmdtbl_params_t DA_Gen3_StandardOpMenuCmds[] =
{
   {"DATA",      "Set Voltage Data",                       DA_GEN3_STANDARDOP_CMD_DATA,                    Handle_DA_Data},
   {"RANGE",     "Set Voltage Range",                      DA_GEN3_STANDARDOP_CMD_RANGE,                   Handle_DA_Range},
   {"POLARITY",  "Set Range Polarity Mode",                DA_GEN3_STANDARDOP_CMD_POLARITY,                Handle_DA_Polarity},
   {"CLEAR",     "Clear DA Statuses",                      DA_GEN3_STANDARDOP_CMD_CLEAR_STATUS,            Handle_DA_ClearStatus},
   {"ALL CLEAR", "Clear DA Statuses All Channels",         DA_GEN3_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,  Handle_DA_ClearStatusAllChannels},
   {"SET",       "Reset All Channel Outputs To Zero",      DA_GEN3_STANDARDOP_CMD_RESET_TO_ZERO,           Handle_DA_ResetToZero}
};

naiapp_cmdtbl_params_t DA_Gen5_DA1_DA3_StandardOpMenuCmds[] =
{
   {"DATA",      "Set Voltage/Current Data",                                  DA_GEN5_DA1_DA3_STANDARDOP_CMD_DATA,                        Handle_DA_Data},
   {"RANGE",     "Set Voltage/Current Range",                                 DA_GEN5_DA1_DA3_STANDARDOP_CMD_RANGE,                       Handle_DA_Range},
   {"POLARITY",  "Set Range Polarity Mode",                                   DA_GEN5_DA1_DA3_STANDARDOP_CMD_POLARITY,                    Handle_DA_Polarity},
   {"OPMODE",    "Set Voltage/Current Op Mode",                               DA_GEN5_DA1_DA3_STANDARDOP_CMD_OPMODE,                      Handle_DA_OpMode},
   {"CLEAR",     "Clear DA Statuses",                                         DA_GEN5_DA1_DA3_STANDARDOP_CMD_CLEAR_STATUS,                Handle_DA_ClearStatus},
   {"ALL CLEAR", "Clear DA Statuses All Channels",                            DA_GEN5_DA1_DA3_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,      Handle_DA_ClearStatusAllChannels},
   {"SET",       "Reset All Channel Outputs To Zero",                         DA_GEN5_DA1_DA3_STANDARDOP_CMD_RESET_TO_ZERO,               Handle_DA_ResetToZero},
   {"ENABLE",    "Enable/Disable Power Supply",                               DA_GEN5_DA1_DA3_STANDARDOP_CMD_POWER_SUPPLY_ENABLE,         Handle_DA_PowerSupplyEnable},
   {"FLOAT",     "Enable/Disable Floating-Point Mode",                        DA_GEN5_DA1_DA3_STANDARDOP_CMD_FLOATING_POINT_MODE,         Handle_DA_FloatingPointMode},
   {"OFFSET",    "Set Hardware Floating-Point Conversion Mode Offset",        DA_GEN5_DA1_DA3_STANDARDOP_CMD_FLOATING_OFFSET,             Handle_DA_FloatingPointOffset},
   {"SCALE",     "Set Hardware Floating-Point Conversion Mode Scale Factor",  DA_GEN5_DA1_DA3_STANDARDOP_CMD_FLOATING_SCALE,              Handle_DA_FloatingPointScaleFactor},
   {"CHANSTAT",  "Channel Status Enable/Disable",                             DA_GEN5_DA1_DA3_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,       Handle_DA_ChannelStatusEnable},
   {"PBIT",      "Check Power-On BIT",                                        DA_GEN5_DA1_DA3_STANDARDOP_CMD_PBIT,                        Handle_DA_CheckPowerOnBIT},
   {"THRESH",    "Get/Set BIT Error Threshold",                               DA_GEN5_DA1_DA3_STANDARDOP_CMD_BIT_THRESHOLD,               Handle_DA_BITThresholds},
   {"D3",        "Enable/Disable D3 Test",                                    DA_GEN5_DA1_DA3_STANDARDOP_CMD_D3,                          Handle_DA_SetD3TestEnable},
   {"WDT",      "Show Watchdog Menu Options",                                 DA_GEN5_BASICOP_CMD_WATCHDOG_MENU,                          Handle_DA_WatchdogShowMenu}

};

naiapp_cmdtbl_params_t DA_Gen5_DA2_StandardOpMenuCmds[] =
{
   {"DATA",      "Set Voltage Data",                                          DA_GEN5_DA2_STANDARDOP_CMD_DATA,                        Handle_DA_Data},
   {"RANGE",     "Set Voltage Range",                                         DA_GEN5_DA2_STANDARDOP_CMD_RANGE,                       Handle_DA_Range},
   {"POLARITY",  "Set Voltage Range Polarity Mode",                           DA_GEN5_DA2_STANDARDOP_CMD_POLARITY,                    Handle_DA_Polarity},
   {"CLEAR",     "Clear DA Statuses",                                         DA_GEN5_DA2_STANDARDOP_CMD_CLEAR_STATUS,                Handle_DA_ClearStatus},
   {"ALL CLEAR", "Clear DA Statuses All Channels",                            DA_GEN5_DA2_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,      Handle_DA_ClearStatusAllChannels},
   {"ZERO",      "Reset All Channel Outputs To Zero",                         DA_GEN5_DA2_STANDARDOP_CMD_RESET_TO_ZERO,               Handle_DA_ResetToZero},
   {"OUTPUT_ENABLE","Enable/Disable Channel Output",                          DA_GEN5_DA2_STANDARDOP_CMD_OUTPUT_ENABLE,               Handle_DA_OutputEnable},
   {"FLOAT",     "Enable/Disable Floating-Point Mode",                        DA_GEN5_DA2_STANDARDOP_CMD_FLOATING_POINT_MODE,         Handle_DA_FloatingPointMode},
   {"OFFSET",    "Set Hardware Floating-Point Conversion Mode Offset",        DA_GEN5_DA2_STANDARDOP_CMD_FLOATING_OFFSET,             Handle_DA_FloatingPointOffset},
   {"SCALE",     "Set Hardware Floating-Point Conversion Mode Scale Factor",  DA_GEN5_DA2_STANDARDOP_CMD_FLOATING_SCALE,              Handle_DA_FloatingPointScaleFactor},
   {"CHANSTAT",  "Channel Status Enable/Disable",                             DA_GEN5_DA2_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,       Handle_DA_ChannelStatusEnable},
   {"PBIT",      "Check Power-On BIT",                                        DA_GEN5_DA2_STANDARDOP_CMD_PBIT,                        Handle_DA_CheckPowerOnBIT},
   {"THRESH",    "Get/Set BIT Error Threshold",                               DA_GEN5_DA2_STANDARDOP_CMD_BIT_THRESHOLD,               Handle_DA_BITThresholds},
   {"D3",        "Enable/Disable D3 Test",                                    DA_GEN5_DA2_STANDARDOP_CMD_D3,                          Handle_DA_SetD3TestEnable},
   {"WDT",      "Show Watchdog Menu Options",                                 DA_GEN5_BASICOP_CMD_WATCHDOG_MENU,                      Handle_DA_WatchdogShowMenu}

};

naiapp_cmdtbl_params_t DA_Gen5_DA4_StandardOpMenuCmds[] =
{
   {"DATA",      "Set Voltage Data",                                          DA_GEN5_DA4_STANDARDOP_CMD_DATA,                        Handle_DA_Data},
   {"RANGE",     "Set Voltage Range",                                         DA_GEN5_DA4_STANDARDOP_CMD_RANGE,                       Handle_DA_Range},
   {"POLARITY",  "Set Voltage Range Polarity Mode",                           DA_GEN5_DA4_STANDARDOP_CMD_POLARITY,                    Handle_DA_Polarity},
   {"CLEAR",     "Clear DA Statuses",                                         DA_GEN5_DA4_STANDARDOP_CMD_CLEAR_STATUS,                Handle_DA_ClearStatus},
   {"ALL CLEAR", "Clear DA Statuses All Channels",                            DA_GEN5_DA4_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,      Handle_DA_ClearStatusAllChannels},
   {"ZERO",      "Reset All Channel Outputs To Zero",                         DA_GEN5_DA4_STANDARDOP_CMD_RESET_TO_ZERO,               Handle_DA_ResetToZero},
   {"ENABLE",    "Enable/Disable Power Supply",                               DA_GEN5_DA4_STANDARDOP_CMD_POWER_SUPPLY_ENABLE,         Handle_DA_PowerSupplyEnable},
   {"FLOAT",     "Enable/Disable Floating-Point Mode",                        DA_GEN5_DA4_STANDARDOP_CMD_FLOATING_POINT_MODE,         Handle_DA_FloatingPointMode},
   {"OFFSET",    "Set Hardware Floating-Point Conversion Mode Offset",        DA_GEN5_DA4_STANDARDOP_CMD_FLOATING_OFFSET,             Handle_DA_FloatingPointOffset},
   {"SCALE",     "Set Hardware Floating-Point Conversion Mode Scale Factor",  DA_GEN5_DA4_STANDARDOP_CMD_FLOATING_SCALE,              Handle_DA_FloatingPointScaleFactor},
   {"CHANSTAT",  "Channel Status Enable/Disable",                             DA_GEN5_DA4_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,       Handle_DA_ChannelStatusEnable},
   {"PBIT",      "Check Power-On BIT",                                        DA_GEN5_DA4_STANDARDOP_CMD_PBIT,                        Handle_DA_CheckPowerOnBIT},
   {"THRESH",    "Get/Set BIT Error Threshold",                               DA_GEN5_DA4_STANDARDOP_CMD_BIT_THRESHOLD,               Handle_DA_BITThresholds},
   {"D3",        "Enable/Disable D3 Test",                                    DA_GEN5_DA4_STANDARDOP_CMD_D3,                          Handle_DA_SetD3TestEnable},
   {"WDT",      "Show Watchdog Menu Options",                                 DA_GEN5_BASICOP_CMD_WATCHDOG_MENU,                      Handle_DA_WatchdogShowMenu}

};

naiapp_cmdtbl_params_t DA_Gen5_DA5_StandardOpMenuCmds[] =
{
   {"DATA",       "Set Voltage Data",                                         DA_GEN5_DA5_STANDARDOP_CMD_DATA,                        Handle_DA_Data},
   {"PS_ENABLE",  "Enable/Disable Power Supply",                              DA_GEN5_DA5_STANDARDOP_CMD_POWER_SUPPLY_ENABLE,         Handle_DA_PowerSupplyEnable},
   {"OUTPUT_ENABLE","Enable/Disable Channel Output",                          DA_GEN5_DA5_STANDARDOP_CMD_OUTPUT_ENABLE,               Handle_DA_OutputEnable},
   {"BRIDGE_ENABLE","Enable/Disable Channel Bridge",                          DA_GEN5_DA5_STANDARDOP_CMD_BRIDGE_ENABLE,               Handle_DA_BridgeMode},
   {"CLEAR",      "Clear DA Statuses",                                        DA_GEN5_DA5_STANDARDOP_CMD_CLEAR_STATUS,                Handle_DA_ClearStatus},
   {"ALL CLEAR",  "Clear DA Statuses All Channels",                           DA_GEN5_DA5_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,      Handle_DA_ClearStatusAllChannels},
   {"FLOAT",      "Enable/Disable Floating-Point Mode",                       DA_GEN5_DA5_STANDARDOP_CMD_FLOATING_POINT_MODE,         Handle_DA_FloatingPointMode},
   {"OFFSET",     "Set Hardware Floating-Point Conversion Mode Offset",       DA_GEN5_DA5_STANDARDOP_CMD_FLOATING_OFFSET,             Handle_DA_FloatingPointOffset},
   {"SCALE",      "Set Hardware Floating-Point Conversion Mode Scale Factor", DA_GEN5_DA5_STANDARDOP_CMD_FLOATING_SCALE,              Handle_DA_FloatingPointScaleFactor},
   {"CHANSTAT",   "Channel Status Enable/Disable",                            DA_GEN5_DA5_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,       Handle_DA_ChannelStatusEnable},
   {"PBIT",       "Check Power-On BIT",                                       DA_GEN5_DA5_STANDARDOP_CMD_PBIT,                        Handle_DA_CheckPowerOnBIT},
   {"THRESH",     "Get/Set BIT Error Threshold",                              DA_GEN5_DA5_STANDARDOP_CMD_BIT_THRESHOLD,               Handle_DA_BITThresholds},
   {"D3",         "Enable/Disable D3 Test",                                   DA_GEN5_DA5_STANDARDOP_CMD_D3,                          Handle_DA_SetD3TestEnable},
   {"WDT",      "Show Watchdog Menu Options",                                 DA_GEN5_BASICOP_CMD_WATCHDOG_MENU,                      Handle_DA_WatchdogShowMenu}
};

naiapp_cmdtbl_params_t DA_WatchdogOpMenuCmds[DA_WD_CMD_COUNT] =
{
   {"BACK",           "Back to Main Menu",                             DA_WD_CMD_BACK,          NULL},
   {"TIME QUIET",     "Set Watchdog Quiet Time",                       DA_WD_CMD_QUIETTIME,     Handle_DA_WatchDogQuietTime},
   {"WINDOW",         "Set Watchdog Window Time",                      DA_WD_CMD_WINDOWTIME,    Handle_DA_WatchDogWindowTime},
   {"STROBE",         "Start thread to continuously strobe watchdog",  DA_WD_CMD_STROBE,        Handle_DA_StrobeWatchdog},
   {"KILL",           "Kill Watchdog strobing thread",                 DA_WD_CMD_KILL,          Handle_DA_kill_WDStrobe_Thread}
};

/**************************************************************************************************************/
/**
<summary>
The purpose of the DA_BasicOps is to illustrate the methods to call in the naibrd library to perform basic
operations with the DA modules for configuration setup, controlling the drive outputs, 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 DA routines.
 - ConfigDevice
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - CheckModule
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t DA_BasicOps(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

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

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

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

   return 0;
}

/**************************************************************************************************************/
/**
<summary>
This function runs the basic operations DA program.  It controls the top level menu of the DA_BasicOps
program and calls Handle_DA_Configuration or Handle_DA_StandardOps, depending on what the user specifies.
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_DA_BasicOps(int32_t cardIndex, int32_t module, int32_t modId)
{
   naiapp_AppParameters_t  da_params;
   p_naiapp_AppParameters_t da_basicops_params = &da_params;
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   bool_t bCmdFound = FALSE;
   int32_t cmd;
   naiapp_cmdtbl_params_t *cmdtbl_params = NULL;
   int32_t cmdCount = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   da_basicops_params->cardIndex = cardIndex;
   da_basicops_params->module = module;
   da_basicops_params->modId = modId;
   /* Get the Maximum DA Channels */
   da_basicops_params->maxChannels = naibrd_DA_GetChannelCount( modId );
   da_basicops_params->channel = DEF_DA_CHANNEL;
   /* Get the generation of the board and module */
   naibrd_GetBoardGen( cardIndex, &generation );

   switch (modId)
   {
      case NAI_MODULE_ID_F1:
      case NAI_MODULE_ID_F3:
      case NAI_MODULE_ID_F5:
      case NAI_MODULE_ID_J3:
      case NAI_MODULE_ID_J5:
      case NAI_MODULE_ID_J8:
         cmdtbl_params = DA_Gen3_StandardOpMenuCmds;
         cmdCount = DA_GEN3_STANDARDOP_CMD_COUNT;
         break;

      case NAI_MODULE_ID_DA1:
      case NAI_MODULE_ID_DA3:
         cmdtbl_params = DA_Gen5_DA1_DA3_StandardOpMenuCmds;
         cmdCount = DA_GEN5_DA1_DA3_STANDARDOP_CMD_COUNT;
         break;

      case NAI_MODULE_ID_DA2:
         cmdtbl_params = DA_Gen5_DA2_StandardOpMenuCmds;
         cmdCount = DA_GEN5_DA2_STANDARDOP_CMD_COUNT;
         break;

      case NAI_MODULE_ID_DA4:
         cmdtbl_params = DA_Gen5_DA4_StandardOpMenuCmds;
         cmdCount = DA_GEN5_DA4_STANDARDOP_CMD_COUNT;
         break;

      case NAI_MODULE_ID_DA5:
         cmdtbl_params = DA_Gen5_DA5_StandardOpMenuCmds;
         cmdCount = DA_GEN5_DA5_STANDARDOP_CMD_COUNT;
         break;

      default:
         printf("Module ID: %u not supported!\n", modId);
         break;
   }

   while (bContinue)
   {
      naiapp_utils_LoadParamMenuCommands( cmdCount, cmdtbl_params );
      while (bContinue)
      {
         DA_DisplayOpData( cardIndex, module, da_basicops_params->maxChannels, modId );
         naiapp_display_ParamMenuCommands( (int8_t *)"DA Standard Operations Menu" );
         printf( "\nType DA command or %c to go back >", BACK_CHAR );
         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), BACK_CHAR, inputBuffer, &inputResponseCnt );
         if (!bQuit)
         {
            if ( inputResponseCnt > 0 )
            {
               bCmdFound = naiapp_utils_GetParamMenuCmdNum( inputResponseCnt, inputBuffer, &cmd );
               if (bCmdFound)
                  cmdtbl_params[cmd].func(APP_PARAM_COUNT, (int32_t*)da_basicops_params);
               else
                  printf( "Invalid command entered\n" );
            }
            else
               printf( "Invalid command entered\n" );
         }
         else
            bContinue = FALSE;
      }
   }
   return TRUE;
}

/**************************************************************************************************************/
/**
<summary>
This function sets the contents of the data register of the channel specified by the user to the value
specified by the user.  For Gen5 modules, the voltage or current will be set based on the current value in
the op mode register.  Voltage will be set if the op mode is set to voltage mode, whereas current will be
set if the op mode is set to current mode.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_Data(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   uint32_t modId = da_basicops_params->modId;
   bool_t bQuit = FALSE;
   float64_t data;
   nai_da_data_type_t opmode;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
   if (!bQuit)
   {
      if ( (generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount) )
      {
         if (modId == NAI_MODULE_ID_DA2 || modId == NAI_MODULE_ID_DA4)
         {
            printf("Type Voltage value to set in V: ");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if (!bQuit)
            {
               if (inputResponseCnt > 0)
               {
                  data = atof((const char *)inputBuffer);
                  check_status(naibrd_DA_SetData(cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, data));
               }
            }
         }
         else
         {
            check_status( naibrd_DA_GetOpMode( cardIndex, module, da_basicops_params->channel, &opmode ) );
            if ( opmode == NAI_DA_DATA_VOLTAGE )
            {
               printf( "Type Voltage value to set in V: " );
            }
            else if ( opmode == NAI_DA_DATA_CURRENT )
            {
               printf( "Type Current value to set in mA: " );
            }
            bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
            if (!bQuit)
            {
               if ( inputResponseCnt > 0 )
               {
                  data = atof( (const char *)inputBuffer );
                  check_status( naibrd_DA_SetData( cardIndex, module, da_basicops_params->channel, opmode, data ) );
               }
            }
         }
      }
      else
      {
         printf( "Type Voltage value to set in V: " );
         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
         if (!bQuit)
         {
            if ( inputResponseCnt > 0 )
            {
               data = atof( (const char *)inputBuffer );
               check_status( naibrd_DA_SetData( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, data ) );
            }
         }
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function clears the status(es) of the channel specified by the user.  Clearing the status of a channel
sets the latched status bit of the given status corresponding to the given channel to 0.  Statuses that can
be cleared are BIT and Overcurrent statuses.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_ClearStatus(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   uint32_t statnum;
   uint32_t mask = 0x1u;
   uint32_t shift = 0;
   nai_da_status_type_t type;
   bool_t bQuit = FALSE;
   bool_t errFlag = FALSE;
   bool_t clearAllFlag = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      if (generation == NAI_XILINX_GEN5_ID)
      {
         printf( "Type Status type to be cleared ('0' = BIT, '1' = Overcurrent, '2' = Summary, '3' = All Statuses): " );
         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
         statnum = atoi( (const char *)inputBuffer );
         switch (statnum)
         {
            case 0:
               type = NAI_DA_STATUS_BIT_LATCHED;
               break;
            case 1:
               type = NAI_DA_STATUS_OVERCURRENT_LATCHED;
               break;
            case 2:
               type = NAI_DA_STATUS_SUMMARY_LATCHED;
               break;
            case 3:
               clearAllFlag = TRUE;
               type = NAI_DA_STATUS_BIT_REALTIME; /* Set type equal to something arbitrary */
               break;
            default:
               errFlag = TRUE;
               type = NAI_DA_STATUS_BIT_REALTIME; /* Set type equal to something arbitrary */
               if (!bQuit)
               {
                  printf( "\nError! Invalid Status Type\n" );
               }
               break;
         }

         if ( ( !bQuit ) && ( inputResponseCnt > 0 ) && ( errFlag == FALSE ) && ( clearAllFlag == FALSE ) )
         {
            bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
            if (!bQuit)
            {
               check_status( naibrd_DA_ClearStatus( cardIndex, module, da_basicops_params->channel, type ) );
               printf( "\nStatus Cleared!\n" );
            }
         }
         else if ( ( !bQuit ) && ( inputResponseCnt > 0 ) && ( errFlag == FALSE ) && ( clearAllFlag == TRUE ) )
         {
            bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
            if (!bQuit)
            {
               check_status( naibrd_DA_ClearStatus( cardIndex, module, da_basicops_params->channel, NAI_DA_STATUS_BIT_LATCHED ) );
               check_status( naibrd_DA_ClearStatus( cardIndex, module, da_basicops_params->channel, NAI_DA_STATUS_OVERCURRENT_LATCHED ) );
               check_status( naibrd_DA_ClearStatus( cardIndex, module, da_basicops_params->channel, NAI_DA_STATUS_SUMMARY_LATCHED ) );
               printf( "\nStatuses Cleared!\n" );
            }
         }
         else
         {
            printf( "Type Status type to be cleared ('0' = BIT, '1' = Overcurrent, '2' = All Statuses): " );
            bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
            statnum = atoi( (const char *)inputBuffer );
            switch (statnum)
            {
               case 0:
                  type = NAI_DA_STATUS_BIT_LATCHED;
                  break;
               case 1:
                  type = NAI_DA_STATUS_OVERCURRENT_LATCHED;
                  break;
               case 2:
                  clearAllFlag = TRUE;
                  type = NAI_DA_STATUS_BIT_REALTIME; /* Set type equal to something arbitrary */
                  break;
               default:
                  errFlag = TRUE;
                  type = NAI_DA_STATUS_BIT_REALTIME; /* Set type equal to something arbitrary */
                  if (!bQuit)
                  {
                     printf( "\nError! Invalid Status Type\n" );
                  }
                  break;
            }

            if ( ( !bQuit ) && ( inputResponseCnt > 0 ) && ( errFlag == FALSE ) && ( clearAllFlag == FALSE ) )
            {
               bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
               shift = da_basicops_params->channel-1;
               if (!bQuit)
               {
                  check_status( naibrd_DA_ClearStatusRaw( cardIndex, module, type, (mask << shift) ) );
                  printf( "\nStatus Cleared!\n" );
               }
            }
            else if ( ( !bQuit ) && ( inputResponseCnt > 0 ) && ( errFlag == FALSE ) && ( clearAllFlag == TRUE ) )
            {
               bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
               shift = da_basicops_params->channel-1;
               if (!bQuit)
               {
                  check_status( naibrd_DA_ClearStatusRaw( cardIndex, module, NAI_DA_STATUS_BIT_LATCHED, (mask << shift) ) );
                  check_status( naibrd_DA_ClearStatusRaw( cardIndex, module, NAI_DA_STATUS_OVERCURRENT_LATCHED, (mask << shift) ) );
                  printf( "\nStatuses Cleared!\n" );
               }
            }
         }
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function clears the status(es) of all of the channels on the module.  Clearing the status of a channel
sets the latched status bit of the given status corresponding to the given channel to 0.  Statuses that can
be cleared are BIT and Overcurrent statuses.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_ClearStatusAllChannels(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   int32_t chan = da_basicops_params->channel;
   uint32_t statnum;
   uint32_t mask = 0x1u;
   uint32_t shift = 0;
   nai_da_status_type_t type;
   bool_t bQuit = FALSE;
   bool_t errFlag = FALSE;
   bool_t clearAllFlag = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      if (generation == NAI_XILINX_GEN5_ID)
      {
         printf( "Type Status type to be cleared ('0' = BIT, '1' = Overcurrent, '2' = Summary, '3' = All Statuses): " );
         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
         statnum = atoi( (const char *)inputBuffer );
         switch (statnum)
         {
            case 0:
               type = NAI_DA_STATUS_BIT_LATCHED;
               break;
            case 1:
               type = NAI_DA_STATUS_OVERCURRENT_LATCHED;
               break;
            case 2:
               type = NAI_DA_STATUS_SUMMARY_LATCHED;
               break;
            case 3:
               clearAllFlag = TRUE;
               type = NAI_DA_STATUS_BIT_REALTIME; /* Set type equal to something arbitrary */
               break;
            default:
               errFlag = TRUE;
               type = NAI_DA_STATUS_BIT_REALTIME; /* Set type equal to something arbitrary */
               if (!bQuit)
               {
                  printf( "\nError! Invalid Status Type\n" );
               }
               break;
         }

         if ( ( !bQuit ) && ( inputResponseCnt > 0 ) && ( errFlag == FALSE ) && ( clearAllFlag == FALSE ) )
         {
            for ( chan = 1; chan <= da_basicops_params->maxChannels; chan++ )
            {
               check_status( naibrd_DA_ClearStatus( cardIndex, module, chan, type ) );
            }
            if (type == NAI_DA_STATUS_OVERCURRENT_LATCHED)
            {
               check_status( naibrd_DA_ResetOverload( cardIndex, module ) );
            }
            printf( "\nStatuses Cleared!\n" );
         }
         else if ( ( !bQuit ) && ( inputResponseCnt > 0 ) && ( errFlag == FALSE ) && ( clearAllFlag == TRUE ) )
         {
            for ( chan = 1; chan <= da_basicops_params->maxChannels; chan++ )
            {
               check_status( naibrd_DA_ClearStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_LATCHED ) );
               check_status( naibrd_DA_ClearStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_LATCHED ) );
               check_status( naibrd_DA_ClearStatus( cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_LATCHED ) );
            }
            check_status( naibrd_DA_ResetOverload( cardIndex, module ) );
            printf( "\nStatuses Cleared!\n" );
         }
      }
      else
      {
         printf( "Type Status type to be cleared ('0' = BIT, '1' = Overcurrent, '2' = All Statuses): " );
         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
         statnum = atoi( (const char *)inputBuffer );
         switch (statnum)
         {
            case 0:
               type = NAI_DA_STATUS_BIT_LATCHED;
               break;
            case 1:
               type = NAI_DA_STATUS_OVERCURRENT_LATCHED;
               break;
            case 2:
               clearAllFlag = TRUE;
               type = NAI_DA_STATUS_BIT_REALTIME; /* Set type equal to something arbitrary */
               break;
            default:
               errFlag = TRUE;
               type = NAI_DA_STATUS_BIT_REALTIME; /* Set type equal to something arbitrary */
               if (!bQuit)
               {
                  printf( "\nError! Invalid Status Type\n" );
               }
               break;
         }

         if ( ( !bQuit ) && ( inputResponseCnt > 0 ) && ( errFlag == FALSE ) && ( clearAllFlag == FALSE ) )
         {
            for ( chan = 1; chan <= da_basicops_params->maxChannels; chan++ )
            {
               shift = chan-1;
               check_status( naibrd_DA_ClearStatusRaw( cardIndex, module, type, (mask << shift) ) );
            }
            printf( "\nStatuses Cleared!\n" );
         }
         else if ( ( !bQuit ) && ( inputResponseCnt > 0 ) && ( errFlag == FALSE ) && ( clearAllFlag == TRUE ) )
         {
            for ( chan = 1; chan <= da_basicops_params->maxChannels; chan++ )
            {
               shift = chan-1;
               check_status( naibrd_DA_ClearStatusRaw( cardIndex, module, NAI_DA_STATUS_BIT_LATCHED, (mask << shift) ) );
               check_status( naibrd_DA_ClearStatusRaw( cardIndex, module, NAI_DA_STATUS_OVERCURRENT_LATCHED, (mask << shift) ) );
            }
            printf( "\nStatuses Cleared!\n" );
         }
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function sets all channel outputs on the module to zero.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_ResetToZero(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if ((generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount))
   {
      printf( "This will set all channel outputs on the module to 0.  Are you sure you want to do this? (Y or N)(default:Y): " );
      bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
      if (!bQuit)
      {
         if ( ( inputBuffer[0] == 'y' ) || ( inputBuffer[0] == 'Y' ) || ( inputResponseCnt == 0 ) )
         {
            check_status( naibrd_DA_ResetToZero( cardIndex, module ) );
            printf( "\nAll Channel Outputs Have Been Reset To Zero\n" );
         }
         else if ( ( inputBuffer[0] == 'n' ) || ( inputBuffer[0] == 'N' ) )
         {
            /* If the user answers no to the prompt, do nothing */
         }
         else
         {
            printf( "\nError! Invalid user input!\n" );
         }
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function enables/disables the module/channel power supply based on user input.  Applies to Gen5 modules
only.  DA1 has one power supply for the entire module, whereas DA3 has a power supply for each channel on the
module.  The user can enable or disable the module power supply of a DA1 module or enable or disable any of the
power supplies of the channels of a DA3 module.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_PowerSupplyEnable(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   uint32_t modId = da_basicops_params->modId;
   bool_t bQuit = FALSE;
   bool_t errFlag = FALSE;
   nai_da_powersupply_ctrl_t enableVal;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if ( (generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount) )
   {
      if ((modId == NAI_MODULE_ID_DA3) || ( modId == NAI_MODULE_ID_DA4))
      {
         bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
         if (!bQuit)
         {
            printf( "Type '0' to turn off/disable channel power supply or '1' to turn on/enable channel power supply. (default:1): " );
            bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
            if (!bQuit)
            {
               if ( inputResponseCnt > 0 )
               {
                  enableVal = atoi( (const char *)inputBuffer );
                  switch (enableVal)
                  {
                     case NAI_DA_POWERSUPPLY_CTRL_DISABLE:
                     case NAI_DA_POWERSUPPLY_CTRL_ENABLE:
                        break;
                     default:
                        errFlag = TRUE;
                        printf( "\nError! Invalid user input!\n" );
                        break;
                  }

                  if ( errFlag == FALSE )
                  {
                     check_status( naibrd_DA_SetChannelPowerSupplyEnable( cardIndex, module, da_basicops_params->channel, enableVal ) );
                     if ( enableVal == NAI_DA_POWERSUPPLY_CTRL_DISABLE )
                     {
                        printf( "\nChannel %d Power Supply Disabled\n", da_basicops_params->channel );
                     }
                     else if ( enableVal == NAI_DA_POWERSUPPLY_CTRL_ENABLE )
                     {
                        printf( "\nChannel %d Power Supply Enabled\n", da_basicops_params->channel );
                     }
                  }
               }
               else if ( inputResponseCnt == 0 )
               {
                  check_status( naibrd_DA_SetChannelPowerSupplyEnable( cardIndex, module, da_basicops_params->channel, NAI_DA_POWERSUPPLY_CTRL_ENABLE ) );
                  printf( "\nChannel %d Power Supply Enabled\n", da_basicops_params->channel );
               }
            }
         }
      }
      else if ( (modId == NAI_MODULE_ID_DA1)  || (modId == NAI_MODULE_ID_DA5) )
      {
         printf( "Type '0' to turn off/disable module power supply or '1' to turn on/enable module power supply. (default:1): " );
         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
         if (!bQuit)
         {
            if ( inputResponseCnt > 0 )
            {
               enableVal = atoi( (const char *)inputBuffer );
               switch (enableVal)
               {
                  case NAI_DA_POWERSUPPLY_CTRL_DISABLE:
                  case NAI_DA_POWERSUPPLY_CTRL_ENABLE:
                     break;
                  default:
                     errFlag = TRUE;
                     printf( "\nError! Invalid user input!\n" );
                     break;
               }

               if ( errFlag == FALSE )
               {
                  check_status( naibrd_DA_SetPowerSupplyEnable( cardIndex, module, enableVal ) );
                  if ( enableVal == NAI_DA_POWERSUPPLY_CTRL_DISABLE )
                  {
                     printf( "\nModule Power Supply Disabled\n" );
                  }
                  else if ( enableVal == NAI_DA_POWERSUPPLY_CTRL_ENABLE )
                  {
                     printf( "\nModule Power Supply Enabled\n" );
                  }
               }
            }
            else if ( inputResponseCnt == 0 )
            {
               check_status( naibrd_DA_SetPowerSupplyEnable( cardIndex, module, NAI_DA_POWERSUPPLY_CTRL_ENABLE ) );
               printf( "\nModule Power Supply Enabled\n" );
            }
         }
      }
      else
      {
         printf( "This feature is not supported by this module.\n" );
      }
   }
   else
   {
      printf( "This feature is not supported by this module.\n" );
   }

   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function sets the voltage/current range of the channel specified by the user to the range specified by
the user.  For Gen5 modules, the voltage or current range will be set based on the current value in the op mode
register.  Voltage range will be set if the op mode is set to voltage mode, whereas current range will be set
if the op mode is set to current mode.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_Range(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   uint32_t modId = da_basicops_params->modId;
   bool_t bQuit = FALSE;
   bool_t errFlag = FALSE;
   nai_da_range_t range;
   nai_da_range_t tempRange;
   nai_da_range_mode_t mode;
   nai_da_data_type_t opmode;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
   if (!bQuit)
   {
      if ( (generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount) )
      {
         if (modId == NAI_MODULE_ID_DA2)
         {
            printf( "Type Voltage Range to set ('2.5' for 2.5V, '5' for 5V, '10' for 10V)(default:2.5): " );
            bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
            if (!bQuit)
            {
               if ( inputResponseCnt > 0 )
               {
                  range = atof( (const char *)inputBuffer );
                  if ( ( range != NAI_DA_GEN5_VOLT_RANGE_DA2_5V ) && ( range != NAI_DA_GEN5_VOLT_RANGE_DA2_2P5V ) && ( range != NAI_DA_GEN5_VOLT_RANGE_DA2_10V ) )
                  {
                     errFlag = TRUE;
                     printf( "\nError! Invalid range!\n" );
                  }
                  if ( errFlag == FALSE )
                  {
                     check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &mode, &tempRange ) );
                     check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, mode, range ) );
                  }
               }
               else if ( inputResponseCnt == 0 )
               {
                  check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &mode, &tempRange ) );
                  check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, mode, NAI_DA_GEN5_VOLT_RANGE_DA2_2P5V ) );
               }
            }
         }
         else if (modId == NAI_MODULE_ID_DA4)
         {
            printf( "Type Voltage Range to set ('25' for 25V, '50' for 50V, '100' for 100V)(default:25): " );
            bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
            if (!bQuit)
            {
               if ( inputResponseCnt > 0 )
               {
                  range = atof( (const char *)inputBuffer );
                  if ( ( range != NAI_DA_GEN5_VOLT_RANGE_DA4_50V ) && ( range != NAI_DA_GEN5_VOLT_RANGE_DA4_25V ) && ( range != NAI_DA_GEN5_VOLT_RANGE_DA4_100V ) )
                  {
                     errFlag = TRUE;
                     printf( "\nError! Invalid range!\n" );
                  }
                  if ( errFlag == FALSE )
                  {
                     check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &mode, &tempRange ) );
                     check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, mode, range ) );
                  }
               }
               else if ( inputResponseCnt == 0 )
               {
                  check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &mode, &tempRange ) );
                  check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, mode, NAI_DA_GEN5_VOLT_RANGE_DA4_25V ) );
               }
            }
         }
         else
         {
            printf( "Would you like to set voltage range or current range? ('V' for voltage, 'C' for current)(default:V): " );
            bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
            if (!bQuit)
            {
               if ( ( inputBuffer[0] == 'V' ) || ( inputBuffer[0] == 'v' ) || ( inputResponseCnt == 0 ) )
               {
                  opmode = NAI_DA_DATA_VOLTAGE;
               }
               else if ( ( inputBuffer[0] == 'C' ) || ( inputBuffer[0] == 'c' ) )
               {
                  opmode = NAI_DA_DATA_CURRENT;
               }
               else
               {
                  opmode = NAI_DA_DATA_ENUM_COUNT;
                  printf( "\nError! Invalid range type!\n" );
               }

               if ( modId == NAI_MODULE_ID_DA1 )
               {
                  if ( opmode == NAI_DA_DATA_VOLTAGE )
                  {
                     printf( "Type Voltage Range to set ('1.25' for 1.25V, '2.5' for 2.5V, '5' for 5V, '10' for 10V)(default:1.25): " );
                     bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
                     if (!bQuit)
                     {
                        if ( inputResponseCnt > 0 )
                        {
                           range = atof( (const char *)inputBuffer );
                           if ( ( range != NAI_DA_GEN5_VOLT_RANGE_DA1_1P25V ) && ( range != NAI_DA_GEN5_VOLT_RANGE_DA1_2P5V )
                                && ( range != NAI_DA_GEN5_VOLT_RANGE_DA1_5V ) && ( range != NAI_DA_GEN5_VOLT_RANGE_DA1_10V ) )
                           {
                              errFlag = TRUE;
                              printf( "\nError! Invalid range!\n" );
                           }
                           if ( errFlag == FALSE )
                           {
                              check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &mode, &tempRange ) );
                              check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, mode, range ) );
                           }
                        }
                        else if ( inputResponseCnt == 0 )
                        {
                           check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &mode, &tempRange ) );
                           check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, mode, NAI_DA_GEN5_VOLT_RANGE_DA1_1P25V ) );
                        }
                     }
                  }
                  else if ( opmode == NAI_DA_DATA_CURRENT )
                  {
                     printf( "Type Current Range to set ('3.125' for 3.125mA, '6.25' for 6.25mA, '12.5' for 12.5mA, '25' for 25mA)(default:3.125): " );
                     bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
                     if (!bQuit)
                     {
                        if ( inputResponseCnt > 0 )
                        {
                           range = atof( (const char *)inputBuffer );
                           if ( ( range != NAI_DA_GEN5_CURRENT_RANGE_DA1_3P125mA ) && ( range != NAI_DA_GEN5_CURRENT_RANGE_DA1_6P25mA )
                              && ( range != NAI_DA_GEN5_CURRENT_RANGE_DA1_12P5mA ) && ( range != NAI_DA_GEN5_CURRENT_RANGE_DA1_25mA ) )
                           {
                              errFlag = TRUE;
                              printf( "\nError! Invalid range!\n" );
                           }
                           if ( errFlag == FALSE )
                           {
                              check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &mode, &tempRange ) );
                              check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, mode, range ) );
                           }
                        }
                        else if ( inputResponseCnt == 0 )
                        {
                           check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &mode, &tempRange ) );
                           check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, mode, NAI_DA_GEN5_CURRENT_RANGE_DA1_3P125mA ) );
                        }
                     }
                  }
               }
               else if ( modId == NAI_MODULE_ID_DA3 )
               {
                  if ( opmode == NAI_DA_DATA_VOLTAGE )
                  {
                     printf( "Type Voltage Range to set ('10' for 10V, '20' for 20V, '40' for 40V)(default:10): " );
                     bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
                     if (!bQuit)
                     {
                        if ( inputResponseCnt > 0 )
                        {
                           range = atof( (const char *)inputBuffer );
                           if ( ( range != NAI_DA_GEN5_VOLT_RANGE_DA3_10V ) && ( range != NAI_DA_GEN5_VOLT_RANGE_DA3_20V ) && ( range != NAI_DA_GEN5_VOLT_RANGE_DA3_40V ) )
                           {
                              errFlag = TRUE;
                              printf( "\nError! Invalid range!\n" );
                           }
                           if ( errFlag == FALSE )
                           {
                              check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &mode, &tempRange ) );
                              check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, mode, range ) );
                           }
                        }
                        else if ( inputResponseCnt == 0 )
                        {
                           check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &mode, &tempRange ) );
                           check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, mode, NAI_DA_GEN5_VOLT_RANGE_DA3_10V ) );
                        }
                     }
                  }
                  else if ( opmode == NAI_DA_DATA_CURRENT )
                  {
                     printf( "Type Current Range to set ('25' for 25mA, '50' for 50mA, '100' for 100mA)(default:25): " );
                     bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
                     if (!bQuit)
                     {
                        if ( inputResponseCnt > 0 )
                        {
                           range = atof( (const char *)inputBuffer );
                           if ( ( range != NAI_DA_GEN5_CURRENT_RANGE_DA3_25mA ) && ( range != NAI_DA_GEN5_CURRENT_RANGE_DA3_50mA ) && ( range != NAI_DA_GEN5_CURRENT_RANGE_DA3_100mA ) )
                           {
                              errFlag = TRUE;
                              printf( "\nError! Invalid range!\n" );
                           }
                           if ( errFlag == FALSE )
                           {
                              check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &mode, &tempRange ) );
                              check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, mode, range ) );
                           }
                        }
                        else if ( inputResponseCnt == 0 )
                        {
                           check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &mode, &tempRange ) );
                           check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, mode, NAI_DA_GEN5_CURRENT_RANGE_DA3_25mA ) );
                        }
                     }
                  }
               }
            }
         }
      }
      else
      {
         printf( "Type Voltage Range to set ('5' for 5V, '10' for 10V, '15' for 15V, '20' for 20V, '25' for 25V)(default:5): " );
         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
         if (!bQuit)
         {
            if ( inputResponseCnt > 0 )
            {
               range = atof( (const char *)inputBuffer );
               if ( ( range != NAI_DA_GEN3_RANGE_F5_5V ) && ( range != NAI_DA_GEN3_RANGE_F5_10V ) && ( range != NAI_DA_GEN3_RANGE_F5_15V )
                  && ( range != NAI_DA_GEN3_RANGE_F5_20V ) && ( range != NAI_DA_GEN3_RANGE_F5_25V ) )
               {
                  errFlag = TRUE;
                  printf( "\nError! Invalid range!\n" );
               }
               if ( errFlag == FALSE )
               {
                  check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &mode, &tempRange ) );
                  check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, mode, range ) );
               }
            }
            else if ( inputResponseCnt == 0 )
            {
               check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &mode, &tempRange ) );
               check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, mode, NAI_DA_GEN3_RANGE_F5_5V ) );
            }
         }
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function sets the range polarity mode of the channel specified by the user to the mode specified by
the user.  Note that this function does not modify the range or the op mode of any of the channels; it only
sets the range mode to unipolar or bipolar based on user input.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_Polarity(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   uint32_t modId = da_basicops_params->modId;
   bool_t bQuit = FALSE;
   bool_t errFlag = FALSE;
   nai_da_range_mode_t polarity;
   nai_da_range_t rangeRead;
   nai_da_range_mode_t tempMode;
   nai_da_data_type_t opmode = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if ( (generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount) )
   {
      if (modId == NAI_MODULE_ID_DA2 || modId == NAI_MODULE_ID_DA4)
      {
         bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
         if (!bQuit)
         {
            printf( "Type polarity mode to set ('0' for Unipolar, '1' for Bipolar)(default:1): " );
            bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
            if (!bQuit)
            {
               if ( inputResponseCnt > 0 )
               {
                  polarity = atoi( (const char *)inputBuffer );
                  switch (polarity)
                  {
                     case NAI_DA_GEN5_RANGE_MODE_UNIPOLAR:
                     case NAI_DA_GEN5_RANGE_MODE_BIPOLAR:
                        break;
                     default:
                        errFlag = TRUE;
                        printf( "\nError! Invalid polarity mode!\n" );
                        break;
                  }

                  if ( errFlag == FALSE )
                  {
                     check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &tempMode, &rangeRead ) );
                     check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, polarity, rangeRead ) );
                  }
               }
               else if ( inputResponseCnt == 0 )
               {
                  check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &tempMode, &rangeRead ) );
                  check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, NAI_DA_GEN5_RANGE_MODE_BIPOLAR, rangeRead ) );
               }
            }
         }
      }
      else
      {
         printf( "Would you like to set voltage range polarity mode or current range polarity mode? ('V' for voltage, 'C' for current)(default:V): " );
         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
         if (!bQuit)
         {
            if ( ( inputBuffer[0] == 'V' ) || ( inputBuffer[0] == 'v' ) || ( inputResponseCnt == 0 ) )
            {
               opmode = NAI_DA_DATA_VOLTAGE;
            }
            else if ( ( inputBuffer[0] == 'C' ) || ( inputBuffer[0] == 'c' ) )
            {
               opmode = NAI_DA_DATA_CURRENT;
            }
            else
            {
               opmode = NAI_DA_DATA_ENUM_COUNT;
               printf( "\nError! Invalid range polarity mode type!\n" );
            }

            bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
            if (!bQuit)
            {
               printf( "Type polarity mode to set ('0' for Unipolar, '1' for Bipolar)(default:1): " );
               bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
               if (!bQuit)
               {
                  if ( inputResponseCnt > 0 )
                  {
                     polarity = atoi( (const char *)inputBuffer );
                     switch (polarity)
                     {
                        case NAI_DA_GEN5_RANGE_MODE_UNIPOLAR:
                        case NAI_DA_GEN5_RANGE_MODE_BIPOLAR:
                           break;
                        default:
                           errFlag = TRUE;
                           printf( "\nError! Invalid polarity mode!\n" );
                           break;
                     }

                     if ( errFlag == FALSE )
                     {
                        check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &tempMode, &rangeRead ) );
                        check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, polarity, rangeRead ) );
                     }
                  }
                  else if ( inputResponseCnt == 0 )
                  {
                     check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, opmode, &tempMode, &rangeRead ) );
                     check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, opmode, NAI_DA_GEN5_RANGE_MODE_BIPOLAR, rangeRead ) );
                  }
               }
            }
         }
      }
   }
   else
   {
      bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
      if (!bQuit)
      {
         printf( "Type polarity mode to set ('4' for Unipolar, '0' for Bipolar)(default:0): " );
         bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
         if (!bQuit)
         {
            if ( inputResponseCnt > 0 )
            {
               polarity = atoi( (const char *)inputBuffer );
               switch (polarity)
               {
                  case NAI_DA_GEN3_RANGE_MODE_UNIPOLAR:
                  case NAI_DA_GEN3_RANGE_MODE_BIPOLAR:
                     break;
                  default:
                     errFlag = TRUE;
                     printf( "\nError! Invalid polarity mode!\n" );
                     break;
               }

               if ( errFlag == FALSE )
               {
                  check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &tempMode, &rangeRead ) );
                  check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, polarity, rangeRead ) );
               }
            }
            else if ( inputResponseCnt == 0 )
            {
               check_status( naibrd_DA_GetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, &tempMode, &rangeRead ) );
               check_status( naibrd_DA_SetRange( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE, NAI_DA_GEN3_RANGE_MODE_BIPOLAR, rangeRead ) );
            }
         }
      }
   }

   return NAI_SUCCESS;
}

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

   if ((generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount))
   {
      bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
      if (!bQuit)
      {
         printf("Type Bridge Mode to set (0 for DISABLED, 1 for ENABLED)(default:DISABLED): ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0 && inputBuffer[0] == '1')
               check_status(naibrd_DA_SetFullBridgeMode(cardIndex, module, da_basicops_params->channel, TRUE));
            else
               check_status(naibrd_DA_SetFullBridgeMode(cardIndex, module, da_basicops_params->channel, FALSE));
         }
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function enables/disables the floating-point hardware conversion mode of the channel specified by the user.
Applies to Gen5 modules only.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_FloatingPointMode(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   bool_t bQuit = FALSE;
   bool_t errFlag = FALSE;
   bool_t mode = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if ((generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount))
   {
      printf("Type 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)
      {
         if (inputResponseCnt > 0)
         {
            mode = (bool_t)atoi((const char *)inputBuffer);
            switch (mode)
            {
               case TRUE:
               case FALSE:
                  break;
               default:
                  errFlag = TRUE;
                  printf("\nError! Invalid user input!\n");
                  break;
            }

            if (errFlag == FALSE)
            {
               check_status(naibrd_SetFloatingPointModeEnable(cardIndex, module, mode));
            }
         }
         else if (inputResponseCnt == 0)
         {
            check_status(naibrd_SetFloatingPointModeEnable(cardIndex, module, mode));
         }
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function sets the floating-point hardware conversion mode offset of the channel specified by the user.
Applies to Gen5 modules only. Can only be set when module is in floating-point mode.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_FloatingPointOffset(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   bool_t bQuit = FALSE;
   float64_t offset = 0.0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if ((generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount))
   {
      bQuit = naiapp_query_ChannelNumber(da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel));
      if (!bQuit)
      {
         printf("Type Floating-Point Offset value to set: ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               offset = atof((const char *)inputBuffer);
               check_status(naibrd_DA_SetFloatingPointOffset(cardIndex, module, da_basicops_params->channel, offset));
            }
            else if (inputResponseCnt == 0)
            {
               printf("Invalid Offset Value.\n");
            }
         }
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function sets the floating-point hardware conversion mode scale factor of the channel specified by the user.
Applies to Gen5 modules only. Can only be set when module is in floating-point mode.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_FloatingPointScaleFactor(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   bool_t bQuit = FALSE;
   float64_t scaleFactor = 0.0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if ((generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount))
   {
      bQuit = naiapp_query_ChannelNumber(da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel));
      if (!bQuit)
      {
         printf("Type Floating-Point Scale Factor value to set: ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               scaleFactor = atof((const char *)inputBuffer);
               check_status(naibrd_DA_SetFloatingPointScaleFactor(cardIndex, module, da_basicops_params->channel, scaleFactor));
            }
            else if (inputResponseCnt == 0)
            {
               printf("Invalid Scale Factor Value.\n");
            }
         }
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
 * <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 Handle_DA_ChannelStatusEnable(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_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(da_params->maxChannels, da_params->channel, &(da_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_DA_SetChanStatusEnable(da_params->cardIndex, da_params->module, da_params->channel,
               ((inputResponseCnt > 0) && (inputBuffer[0] == 'Y' || inputBuffer[0] == 'y')) ? TRUE : FALSE));
         }
      }
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * Handle_DA_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 Handle_DA_CheckPowerOnBIT(int32_t paramCount, int32_t* p_params)
{
   nai_status_t status = NAI_ERROR_UNKNOWN;
   p_naiapp_AppParameters_t p_da_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)
   {
      channelCount = naibrd_DA_GetChannelCount(p_da_params->modId);

         /* Check to see if PBIT ran for the module. */
      printf("Checking if the Power-On BIT test has run...\n");
      status = naibrd_DA_CheckPowerOnBITComplete(p_da_params->cardIndex, p_da_params->module, &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_DA_GetStatus(p_da_params->cardIndex, p_da_params->module, channel, NAI_DA_STATUS_BIT_LATCHED,
               &bitFailed);
            printf("Ch. %d: %s", channel, bitFailed ? "BIT FAILED\n" : "BIT Passed\n");
         }
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * Handle_DA_BITThresholds() allows the user to set and get the BIT error thresholds.
 * This is an advanced feature.
 * </summary>
 */
/**************************************************************************************************************/
static nai_status_t Handle_DA_BITThresholds(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_da_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)
   {
      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 (FALSE != bQuit)
      {
         if (inputBuffer[0] == 'S' || inputBuffer[0] == 's')
         {
            printf("\nType the desired BIT Error Threshold (Default = 5): ");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            printf("\n");
            bitThreshold = atoi((const char*)inputBuffer);
            status = naibrd_DA_SetModuleBITErrorThreshold(p_da_params->cardIndex, p_da_params->module, bitThreshold);
         }
         else if (inputBuffer[0] == 'G' || inputBuffer[0] == 'g')
         {
            status = naibrd_DA_GetModuleBITErrorThreshold(p_da_params->cardIndex, p_da_params->module, &bitThreshold);
            printf("\nBIT Error threshold: %d", bitThreshold);
         }
         else if (inputBuffer[0] == 'C' || inputBuffer[0] == 'c')
         {
            int32_t ch;
            int32_t channels = naibrd_DA_GetChannelCount(p_da_params->modId);

            printf("\nClearing BIT counters on all channels.\n");
            for (ch = 1; ch <= channels; ch++)
               status = naibrd_DA_ClearModuleBITLogic(p_da_params->cardIndex, p_da_params->module, ch);
         }
         else
         {
            printf("\nSelection not recognized.\n");
         }
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
<summary>
This function sets the op mode of the channel specified by the user to the mode specified by the user.  Valid
op modes are voltage and current mode.  Applies to Gen5 modules only.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_OpMode(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   uint32_t modId = da_basicops_params->modId;
   bool_t bQuit = FALSE;
   bool_t errFlag = FALSE;
   nai_da_data_type_t mode;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      if ( (generation == NAI_XILINX_GEN5_ID) && (modId != NAI_MODULE_ID_DA2 && modId != NAI_MODULE_ID_DA4) )
      {
         bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
         if (!bQuit)
         {
            printf( "Type Op Mode to set (0 for voltage mode, 1 for current mode)(default:0): " );
            bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
            if (!bQuit)
            {
               if ( inputResponseCnt > 0 )
               {
                  mode = atoi( (const char *)inputBuffer );
                  switch (mode)
                  {
                     case NAI_DA_DATA_VOLTAGE:
                     case NAI_DA_DATA_CURRENT:
                        break;
                     default:
                        errFlag = TRUE;
                        printf( "\nError! Invalid user input!\n" );
                        break;
                  }

                  if ( errFlag == FALSE )
                  {
                     check_status( naibrd_DA_SetOpMode( cardIndex, module, da_basicops_params->channel, mode ) );
                  }
               }
               else if ( inputResponseCnt == 0 )
               {
                  check_status( naibrd_DA_SetOpMode( cardIndex, module, da_basicops_params->channel, NAI_DA_DATA_VOLTAGE ) );
               }
            }
         }
      }
      else
      {
         printf( "This feature is not supported by this module.\n" );
      }
   }

   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function enables/disables the output of the channel specified by the user.  Applies to DA2 modules only.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_OutputEnable(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t da_basicops_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = da_basicops_params->cardIndex;
   int32_t module = da_basicops_params->module;
   uint32_t modId = da_basicops_params->modId;
   bool_t bQuit = FALSE;
   bool_t errFlag = FALSE;
   nai_da_output_enable_t enable;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if ((generation == NAI_XILINX_GEN5_ID) && (APP_PARAM_COUNT == paramCount))
   {
      if ((modId == NAI_MODULE_ID_DA2) || (modId == NAI_MODULE_ID_DA5))
      {
         bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
         if (!bQuit)
         {
            printf( "Type '0' to turn off/disable channel output or '1' to turn on/enable channel output. (default:1): " );
            bQuit = naiapp_query_ForQuitResponse( sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt );
            if (!bQuit)
            {
               if ( inputResponseCnt > 0 )
               {
                  enable = atoi( (const char *)inputBuffer );
                  switch (enable)
                  {
                     case NAI_DA_ENABLE_OUTPUT:
                     case NAI_DA_DISABLE_OUTPUT:
                        break;
                     default:
                        errFlag = TRUE;
                        printf( "\nError! Invalid user input!\n" );
                        break;
                  }

                  if ( errFlag == FALSE )
                  {
                     check_status( naibrd_DA_SetOutputEnable( cardIndex, module, da_basicops_params->channel, enable ) );
                  }
               }
               else if ( inputResponseCnt == 0 )
               {
                  check_status( naibrd_DA_SetOutputEnable( cardIndex, module, da_basicops_params->channel, NAI_DA_ENABLE_OUTPUT ) );
               }
            }
         }
      }
      else
      {
         printf( "This feature is not supported by this module.\n" );
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function displays the DA Standard Operations data.
</summary>
*/
/**************************************************************************************************************/
static void DA_DisplayOpData( int32_t cardIndex, int32_t module, int32_t maxchan, uint32_t damodid )
{
   int32_t chan;
   float64_t data;
   nai_da_range_t voltRange;
   nai_da_range_mode_t voltPolarity;
   nai_da_range_t currRange;
   nai_da_range_mode_t currPolarity;
   nai_da_output_enable_t outputEnable;
   nai_status_bit_t bitStatLatched;
   nai_status_bit_t overCurrentStatLatched;
   nai_status_bit_t summaryStatusLatched;
   nai_status_bit_t bitStatRealtime;
   nai_status_bit_t overCurrentStatRealtime;
   nai_status_bit_t summaryStatusRealtime;
   float64_t wrapVolt;
   float64_t measuredCurrent;
   float64_t internalVoltage;
   nai_da_data_type_t opmode;
   nai_da_powersupply_ctrl_t psEnable;
   bool_t floatModeEnabled = FALSE;
   char* sVoltPolarity;
   char* sCurrPolarity;
   char* sPsEnable;
   char* sOutputEnable;
   float64_t fpOffset = 0.0;
   float64_t fpScale = 0.0;
   float64_t extPowerVPos = 0.0;
   float64_t extPowerVNeg = 0.0;
   bool_t bridgeEnable = FALSE;
   char* sBridgeEnable;

   printf( "\n\nDA Standard Operations Data:\n\n" );
   if ( generation == NAI_XILINX_GEN5_ID )
   {
      if ( damodid == NAI_MODULE_ID_DA5 )
      {
         printf( "              External  External    Wrap     Wrap                         BIT   Overcurrent  Summary  Floating Floating\n" );
         printf( "                Power     Power    Voltage  Current   Output   Bridge    Status   Status     Status     Point    Point \n" );
         printf( "Ch     Data      (+)       (-)       (V)     (mA)     Enable   Enable    (L/R)    (L/R)       (L/R)     Offset   Scale \n" );
         printf( "----------------------------------------------------------------------------------------------------------------------------------\n" );
         for ( chan = 1; chan <= maxchan; chan++ )
         {
            check_status( naibrd_DA_GetData( cardIndex, module, chan, NAI_DA_DATA_VOLTAGE, &data ) );
            check_status( naibrd_DA_GetExtPowerMeasurement( cardIndex, module, chan, NAI_DA_EXTPWR_MEAS_POSITIVE_VOLTAGE, &extPowerVPos ) );
            check_status( naibrd_DA_GetExtPowerMeasurement( cardIndex, module, chan, NAI_DA_EXTPWR_MEAS_POSITIVE_VOLTAGE, &extPowerVNeg ) );
            check_status( naibrd_DA_GetWrapVoltage( cardIndex, module, chan, &wrapVolt ) );
            check_status( naibrd_DA_GetCurrentMeasurement( cardIndex, module, chan, &measuredCurrent ) );
            check_status( naibrd_DA_GetOutputEnable( cardIndex, module, chan, &outputEnable ) );
            switch ( outputEnable )
            {
               case NAI_DA_ENABLE_OUTPUT:
                  sOutputEnable = "ENABLED ";
                  break;
               case NAI_DA_DISABLE_OUTPUT:
                  sOutputEnable = "DISABLED";
                  break;
               default:
                  sOutputEnable = " ERROR  ";
                  break;
            }

            check_status(naibrd_DA_GetFullBridgeMode(cardIndex, module, chan, &bridgeEnable));
            switch ( bridgeEnable )
            {
               case NAI_DA_ENABLE_OUTPUT:
                  sBridgeEnable = "ENABLED ";
                  break;
               case NAI_DA_DISABLE_OUTPUT:
                  sBridgeEnable = "DISABLED";
                  break;
               default:
                  sBridgeEnable = " ERROR  ";
                  break;
            }

            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_LATCHED, &bitStatLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_REALTIME, &bitStatRealtime ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_LATCHED, &overCurrentStatLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_REALTIME, &overCurrentStatRealtime ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_LATCHED, &summaryStatusLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_REALTIME, &summaryStatusRealtime ) );
            check_status( naibrd_DA_GetFloatingPointOffset( cardIndex, module, chan, &fpOffset) );
            check_status( naibrd_DA_GetFloatingPointScaleFactor( cardIndex, module, chan, &fpScale) );
            printf( "%2d  %7.3f   %7.3f   %7.3f  %7.3f  %7.3f   %s  %s   (%1d/%1d)    (%1d/%1d)       (%1d/%1d)   %7.3f  %7.3f\n",
               chan, data, extPowerVPos, extPowerVNeg, wrapVolt, measuredCurrent, sOutputEnable, sBridgeEnable, bitStatLatched, bitStatRealtime,
               overCurrentStatLatched, overCurrentStatRealtime, summaryStatusLatched, summaryStatusRealtime, fpOffset, fpScale );
         }

         check_status(naibrd_GetRunningInFloatingPointMode(cardIndex, module, &floatModeEnabled));
         if (floatModeEnabled)
         {
            printf("\nHardware Floating-Point Conversion Mode: ENABLED");
         }
         else
         {
            printf("\nHardware Floating-Point Conversion Mode: DISABLED");
         }

         check_status( naibrd_DA_GetPowerSupplyEnable( cardIndex, module, &psEnable ) );
         switch ( psEnable )
         {
            case NAI_DA_POWERSUPPLY_CTRL_DISABLE:
               sPsEnable = "Disabled";
               break;
            case NAI_DA_POWERSUPPLY_CTRL_ENABLE:
               sPsEnable = "Enabled";
               break;
            default:
               sPsEnable = "in an error state";
               break;
         }
         printf( "\nModule power supply is %s.", sPsEnable );
      }
      else if ( (damodid == NAI_MODULE_ID_DA1) || (damodid == NAI_MODULE_ID_DA3) )
      {
         check_status(naibrd_GetRunningInFloatingPointMode(cardIndex, module, &floatModeEnabled));
         if (damodid == NAI_MODULE_ID_DA3)
         {
            printf( "                Voltage            Current                         Wrap         Wrap       Power     BIT   Overcurrent  Summary  Floating Floating\n" );
            printf( "                 Range   Voltage    Range   Current     Op        Voltage      Current     Supply   Status   Status     Status     Point    Point \n" );
            printf( "Ch     Data       (V)    Polarity   (mA)    Polarity   Mode         (V)         (mA)       State    (L/R)    (L/R)       (L/R)     Offset   Scale \n" );
            printf( "------------------------------------------------------------------------------------------------------------------------------------------------------\n" );
         }
         else
         {
            printf( "                Voltage            Current                         Wrap         Wrap      BIT   Overcurrent  Summary  Floating Floating\n" );
            printf( "                 Range   Voltage    Range   Current     Op        Voltage      Current   Status   Status     Status    Point    Point \n" );
            printf( "Ch     Data       (V)    Polarity   (mA)    Polarity   Mode         (V)         (mA)     (L/R)    (L/R)       (L/R)    Offset   Scale \n" );
            printf( "-------------------------------------------------------------------------------------------------------------------------------------------\n" );
         }

         for ( chan = 1; chan <= maxchan; chan++ )
         {
            check_status( naibrd_DA_GetOpMode( cardIndex, module, chan, &opmode ) );
            check_status( naibrd_DA_GetData( cardIndex, module, chan, opmode, &data ) );
            check_status( naibrd_DA_GetRange( cardIndex, module, chan, NAI_DA_DATA_VOLTAGE, &voltPolarity, &voltRange ) );
            switch ( voltPolarity )
            {
               case NAI_DA_GEN5_RANGE_MODE_UNIPOLAR:
                  sVoltPolarity = "UNIPOLAR";
                  break;
               case NAI_DA_GEN5_RANGE_MODE_BIPOLAR:
                  sVoltPolarity = "BIPOLAR ";
                  break;
               default:
                  sVoltPolarity = " ERROR  ";
                  break;
            }
            check_status( naibrd_DA_GetRange( cardIndex, module, chan, NAI_DA_DATA_CURRENT, &currPolarity, &currRange ) );
            switch ( currPolarity )
            {
               case NAI_DA_GEN5_RANGE_MODE_UNIPOLAR:
                  sCurrPolarity = "UNIPOLAR";
                  break;
               case NAI_DA_GEN5_RANGE_MODE_BIPOLAR:
                  sCurrPolarity = "BIPOLAR ";
                  break;
               default:
                  sCurrPolarity = " ERROR  ";
                  break;
            }
            check_status( naibrd_DA_GetWrapVoltage( cardIndex, module, chan, &wrapVolt ) );
            check_status( naibrd_DA_GetCurrentMeasurement( cardIndex, module, chan, &measuredCurrent ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_LATCHED, &bitStatLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_REALTIME, &bitStatRealtime ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_LATCHED, &overCurrentStatLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_REALTIME, &overCurrentStatRealtime ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_LATCHED, &summaryStatusLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_REALTIME, &summaryStatusRealtime ) );
            check_status( naibrd_DA_GetChannelPowerSupplyEnable( cardIndex, module, chan, &psEnable ) );
            check_status( naibrd_DA_GetFloatingPointOffset( cardIndex, module, chan, &fpOffset) );
            check_status( naibrd_DA_GetFloatingPointScaleFactor( cardIndex, module, chan, &fpScale) );

            if (damodid == NAI_MODULE_ID_DA3)
            {
               switch ( psEnable )
               {
                  case NAI_DA_POWERSUPPLY_CTRL_DISABLE:
                     sPsEnable = "DISABLED";
                     break;
                  case NAI_DA_POWERSUPPLY_CTRL_ENABLE:
                     sPsEnable = "ENABLED ";
                     break;
                  default:
                     sPsEnable = " ERROR  ";
                     break;
               }
            }
            else
            {
               sPsEnable = "\b\b\b";
            }

            if ( opmode == NAI_DA_DATA_CURRENT )
            {
               printf( "%2d  %7.3f mA  %7.3f  %s  %7.3f  %s  CURRENT  %10.3f   %9.3f      %s (%1d/%1d)    (%1d/%1d)       (%1d/%1d)   %7.3f  %7.3f\n",
                  chan, data, voltRange, sVoltPolarity, currRange, sCurrPolarity, wrapVolt, measuredCurrent, sPsEnable, bitStatLatched,
                  bitStatRealtime, overCurrentStatLatched, overCurrentStatRealtime, summaryStatusLatched, summaryStatusRealtime,
                  fpOffset, fpScale);
            }
            else
            {
               printf( "%2d  %7.3f V   %7.3f  %s  %7.3f  %s  VOLTAGE  %10.3f   %9.3f      %s (%1d/%1d)    (%1d/%1d)       (%1d/%1d)   %7.3f  %7.3f\n",
                  chan, data, voltRange, sVoltPolarity, currRange, sCurrPolarity, wrapVolt, measuredCurrent, sPsEnable, bitStatLatched,
                  bitStatRealtime, overCurrentStatLatched, overCurrentStatRealtime, summaryStatusLatched, summaryStatusRealtime,
                  fpOffset, fpScale);
            }
         }

         if (damodid == NAI_MODULE_ID_DA1)
         {
            check_status( naibrd_DA_GetPowerSupplyEnable( cardIndex, module, &psEnable ) );
            switch ( psEnable )
            {
               case NAI_DA_POWERSUPPLY_CTRL_DISABLE:
                  sPsEnable = "Disabled";
                  break;
               case NAI_DA_POWERSUPPLY_CTRL_ENABLE:
                  sPsEnable = "Enabled";
                  break;
               default:
                  sPsEnable = "in an error state";
                  break;
            }
            printf( "\nModule power supply is %s.", sPsEnable );
         }

         if (floatModeEnabled)
         {
            printf("\nHardware Floating-Point Conversion Mode: ENABLED\n");
         }
         else
         {
            printf("\nHardware Floating-Point Conversion Mode: DISABLED\n");
         }
      }
      else if (damodid == NAI_MODULE_ID_DA2)
      {
         check_status(naibrd_GetRunningInFloatingPointMode(cardIndex, module, &floatModeEnabled));
         printf( "                Voltage             Wrap     Wrap              Internal   BIT   Overcurrent  Summary  Floating Floating\n" );
         printf( "                 Range   Voltage   Voltage  Current   Output   Voltage   Status   Status     Status     Point    Point \n" );
         printf( "Ch     Data       (V)    Polarity    (V)     (mA)     Enable     (V)     (L/R)    (L/R)       (L/R)     Offset   Scale \n" );
         printf( "----------------------------------------------------------------------------------------------------------------------------------\n" );
         for ( chan = 1; chan <= maxchan; chan++ )
         {
            check_status( naibrd_DA_GetData( cardIndex, module, chan, NAI_DA_DATA_VOLTAGE, &data ) );
            check_status( naibrd_DA_GetRange( cardIndex, module, chan, NAI_DA_DATA_VOLTAGE, &voltPolarity, &voltRange ) );
            switch ( voltPolarity )
            {
               case NAI_DA_GEN5_RANGE_MODE_UNIPOLAR:
                  sVoltPolarity = "UNIPOLAR";
                  break;
               case NAI_DA_GEN5_RANGE_MODE_BIPOLAR:
                  sVoltPolarity = "BIPOLAR ";
                  break;
               default:
                  sVoltPolarity = " ERROR  ";
                  break;
            }

            check_status( naibrd_DA_GetWrapVoltage( cardIndex, module, chan, &wrapVolt ) );
            check_status( naibrd_DA_GetCurrentMeasurement( cardIndex, module, chan, &measuredCurrent ) );
            check_status( naibrd_DA_GetOutputEnable( cardIndex, module, chan, &outputEnable ) );

            switch ( outputEnable )
            {
               case NAI_DA_ENABLE_OUTPUT:
                  sOutputEnable = "ENABLED ";
                  break;
               case NAI_DA_DISABLE_OUTPUT:
                  sOutputEnable = "DISABLED";
                  break;
               default:
                  sOutputEnable = " ERROR  ";
                  break;
            }

            check_status( naibrd_DA_GetInternalVoltage( cardIndex, module, chan, &internalVoltage ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_LATCHED, &bitStatLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_REALTIME, &bitStatRealtime ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_LATCHED, &overCurrentStatLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_REALTIME, &overCurrentStatRealtime ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_LATCHED, &summaryStatusLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_REALTIME, &summaryStatusRealtime ) );
            check_status( naibrd_DA_GetFloatingPointOffset( cardIndex, module, chan, &fpOffset) );
            check_status( naibrd_DA_GetFloatingPointScaleFactor( cardIndex, module, chan, &fpScale) );
            printf( "%2d  %7.3f V   %7.3f  %s  %7.3f  %7.3f  %s  %7.3f   (%1d/%1d)    (%1d/%1d)       (%1d/%1d)   %7.3f  %7.3f\n",
               chan, data, voltRange, sVoltPolarity, wrapVolt, measuredCurrent, sOutputEnable, internalVoltage, bitStatLatched, bitStatRealtime,
               overCurrentStatLatched, overCurrentStatRealtime, summaryStatusLatched, summaryStatusRealtime, fpOffset, fpScale );
         }
         if (floatModeEnabled)
         {
            printf("\nHardware Floating-Point Conversion Mode: ENABLED\n");
         }
         else
         {
            printf("\nHardware Floating-Point Conversion Mode: DISABLED\n");
         }
      }
      else if (damodid == NAI_MODULE_ID_DA4)
      {
         check_status(naibrd_GetRunningInFloatingPointMode(cardIndex, module, &floatModeEnabled));
         printf( "                Voltage             Wrap     Wrap               BIT   Overcurrent  Summary  Floating Floating\n" );
         printf( "                 Range   Voltage   Voltage  Current  PwrSuply  Status   Status     Status     Point    Point \n" );
         printf( "Ch     Data       (V)    Polarity    (V)     (mA)     Enable   (L/R)    (L/R)       (L/R)     Offset   Scale \n" );
         printf( "----------------------------------------------------------------------------------------------------------------------------------\n" );
         for ( chan = 1; chan <= maxchan; chan++ )
         {
            check_status( naibrd_DA_GetData( cardIndex, module, chan, NAI_DA_DATA_VOLTAGE, &data ) );
            check_status( naibrd_DA_GetRange( cardIndex, module, chan, NAI_DA_DATA_VOLTAGE, &voltPolarity, &voltRange ) );
            switch ( voltPolarity )
            {
               case NAI_DA_GEN5_RANGE_MODE_UNIPOLAR:
                  sVoltPolarity = "UNIPOLAR";
                  break;
               case NAI_DA_GEN5_RANGE_MODE_BIPOLAR:
                  sVoltPolarity = "BIPOLAR ";
                  break;
               default:
                  sVoltPolarity = " ERROR  ";
                  break;
            }

            check_status( naibrd_DA_GetWrapVoltage( cardIndex, module, chan, &wrapVolt ) );
            check_status( naibrd_DA_GetCurrentMeasurement( cardIndex, module, chan, &measuredCurrent ) );
            check_status( naibrd_DA_GetChannelPowerSupplyEnable( cardIndex, module, chan, &psEnable ) );

            switch ( psEnable )
            {
               case NAI_DA_POWERSUPPLY_CTRL_DISABLE:
                  sPsEnable = "Disabled";
                  break;
               case NAI_DA_POWERSUPPLY_CTRL_ENABLE:
                  sPsEnable = "Enabled";
                  break;
               default:
                  sPsEnable = "in an error state";
                  break;
            }

            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_LATCHED, &bitStatLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_REALTIME, &bitStatRealtime ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_LATCHED, &overCurrentStatLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_REALTIME, &overCurrentStatRealtime ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_LATCHED, &summaryStatusLatched ) );
            check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_SUMMARY_REALTIME, &summaryStatusRealtime ) );
            check_status( naibrd_DA_GetFloatingPointOffset( cardIndex, module, chan, &fpOffset) );
            check_status( naibrd_DA_GetFloatingPointScaleFactor( cardIndex, module, chan, &fpScale) );
            printf( "%2d  %7.3f V   %7.3f  %s  %7.3f  %7.3f  %s   (%1d/%1d)    (%1d/%1d)       (%1d/%1d)   %7.3f  %7.3f\n",
               chan, data, voltRange, sVoltPolarity, wrapVolt, measuredCurrent, sPsEnable, bitStatLatched, bitStatRealtime,
               overCurrentStatLatched, overCurrentStatRealtime, summaryStatusLatched, summaryStatusRealtime, fpOffset, fpScale );
         }
         if (floatModeEnabled)
         {
            printf("\nHardware Floating-Point Conversion Mode: ENABLED\n");
         }
         else
         {
            printf("\nHardware Floating-Point Conversion Mode: DISABLED\n");
         }
      }
   }
   else
   {
      printf( "             Voltage            Wrap     Wrap    BIT   Overcurrent\n" );
      printf( "     Data     Range  Voltage   Voltage  Current Status   Status   \n" );
      printf( "Ch   (V)       (V)   Polarity    (V)     (mA)   (L/R)    (L/R)    \n" );
      printf( "-------------------------------------------------------------------\n" );
      for ( chan = 1; chan <= maxchan; chan++ )
      {
         check_status( naibrd_DA_GetData( cardIndex, module, chan, NAI_DA_DATA_VOLTAGE, &data ) );
         check_status( naibrd_DA_GetRange( cardIndex, module, chan, NAI_DA_DATA_VOLTAGE, &voltPolarity, &voltRange ) );
         switch ( voltPolarity )
         {
            case NAI_DA_GEN3_RANGE_MODE_UNIPOLAR:
               sVoltPolarity = "UNIPOLAR";
               break;
            case NAI_DA_GEN3_RANGE_MODE_BIPOLAR:
               sVoltPolarity = "BIPOLAR ";
               break;
            default:
               sVoltPolarity = " ERROR  ";
               break;
         }

         check_status( naibrd_DA_GetWrapVoltage( cardIndex, module, chan, &wrapVolt ) );
         check_status( naibrd_DA_GetCurrentMeasurement( cardIndex, module, chan, &measuredCurrent ) );
         check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_LATCHED, &bitStatLatched ) );
         check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_BIT_REALTIME, &bitStatRealtime ) );
         check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_LATCHED, &overCurrentStatLatched ) );
         check_status( naibrd_DA_GetStatus( cardIndex, module, chan, NAI_DA_STATUS_OVERCURRENT_REALTIME, &overCurrentStatRealtime ) );
         printf( "%2d  %7.3f  %7.3f %s  %7.3f  %7.3f (%1d/%1d)    (%1d/%1d)\n", chan, data, voltRange, sVoltPolarity, wrapVolt, measuredCurrent, bitStatLatched, bitStatRealtime, overCurrentStatLatched, overCurrentStatRealtime );
      }
   }
}

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

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

   printf("Enable or Disable D3 Test (0 for disable, 1 for enable): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      switch (inputBuffer[0])
      {
         case '0':
            check_status(naibrd_DA_SetModuleBITEnable(cardIndex, module, NAI_DA_D3_TEST, (bool_t)FALSE));
         break;
         case '1':
            check_status(naibrd_DA_SetModuleBITEnable(cardIndex, module, NAI_DA_D3_TEST, (bool_t)TRUE));
         break;
         default:
            printf("\nInvalid selection entered\n");
         break;
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static nai_status_t Handle_DA_WatchdogShowMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   bool_t bCmdFound = FALSE;
   uint32_t ModuleID = 0u;
   int32_t cmd = 0;
   int32_t numMenuCmds = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   p_naiapp_AppParameters_t p_da_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_da_params->cardIndex;
   int32_t module = p_da_params->module;
   int32_t chan = p_da_params->channel;
   ModuleID = naibrd_GetModuleID(cardIndex, module);

      numMenuCmds = DA_WD_CMD_COUNT;
      naiapp_utils_LoadParamMenuCommands(numMenuCmds, DA_WatchdogOpMenuCmds);
      while (bContinue)
      {
         Handle_DA_DisplayWatchdog(cardIndex, module, chan);
         naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_WD_PGM_NAME);
         printf("\nType DA Watchdog command or %c to quit : main > watchdog >", NAI_QUIT_CHAR);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               if ((inputBuffer[0] == 'B') || (inputBuffer[0] == 'b'))
               {
                  bContinue = FALSE;
               }
               else
               {
                  bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
                  if (bCmdFound)
                  {
                     DA_WatchdogOpMenuCmds[cmd].func(paramCount, p_params);
                  }
                  else
                  {
                     printf("\nInvalid command entered\n");
                  }
               }
            }
         }
         else
            bContinue = FALSE;
      }

      switch (ModuleID)
      {
         case NAI_MODULE_ID_F1:
         case NAI_MODULE_ID_F3:
         case NAI_MODULE_ID_F5:
         case NAI_MODULE_ID_J3:
         case NAI_MODULE_ID_J5:
         case NAI_MODULE_ID_J8:
            naiapp_utils_LoadParamMenuCommands(DA_GEN3_STANDARDOP_CMD_COUNT, DA_Gen3_StandardOpMenuCmds);
         break;
         case NAI_MODULE_ID_DA1:
         case NAI_MODULE_ID_DA3:
            naiapp_utils_LoadParamMenuCommands(DA_GEN5_DA1_DA3_STANDARDOP_CMD_COUNT, DA_Gen5_DA1_DA3_StandardOpMenuCmds);
            break;
         case NAI_MODULE_ID_DA2:
            naiapp_utils_LoadParamMenuCommands(DA_GEN5_DA2_STANDARDOP_CMD_COUNT, DA_Gen5_DA2_StandardOpMenuCmds);
            break;
         case NAI_MODULE_ID_DA4:
            naiapp_utils_LoadParamMenuCommands(DA_GEN5_DA4_STANDARDOP_CMD_COUNT, DA_Gen5_DA4_StandardOpMenuCmds);
            break;
         case NAI_MODULE_ID_DA5:
            naiapp_utils_LoadParamMenuCommands(DA_GEN5_DA5_STANDARDOP_CMD_COUNT, DA_Gen5_DA5_StandardOpMenuCmds);
            break;
         default:
            printf("Module ID: %u not supported!\n", ModuleID);
            break;
      }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static nai_status_t Handle_DA_WatchDogQuietTime(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   uint32_t quietTime = 0u;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   p_naiapp_AppParameters_t p_da_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_da_params->cardIndex;
   int32_t module = p_da_params->module;

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

   printf("\r\n*** To use this sample strobe it is recommended to set a quiet time > 500 ms **");
   printf("\r\nEnter the desired Watchdog Quiet Time (ms): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         if (inputBuffer[0] == '-')
         {
            printf("\nInvalid value entered\n");
         }
         else
         {
            quietTime = atoi((const char *)inputBuffer);
            if (quietTime == 0u)
            {
               if (inputBuffer[0] == '0')
               {
                  check_status(naibrd_DA_SetWatchdogQuietTime(cardIndex, module, quietTime * 1000));
               }
               else
               {
                  printf("\nInvalid value entered\n");
               }
            }
            else
            {
               check_status(naibrd_DA_SetWatchdogQuietTime(cardIndex, module, quietTime * 1000));
            }
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static nai_status_t Handle_DA_WatchDogWindowTime(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   uint32_t windowTime = 0u;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   p_naiapp_AppParameters_t p_da_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_da_params->cardIndex;
   int32_t module = p_da_params->module;

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

   printf("\r\n*** To use this sample strobe it is recommended to set a window time > 500 ms **");
   printf("\r\nEnter the desired Watchdog Window Time (ms): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         if (inputBuffer[0] == '-')
         {
            printf("\nInvalid value entered\n");
         }
         else
         {
            windowTime = atoi((const char *)inputBuffer);
            if (windowTime == 0u)
            {
               if (inputBuffer[0] == '0')
               {
                  check_status(naibrd_DA_SetWatchdogWindow(cardIndex, module, windowTime * 1000));
               }
               else
               {
                  printf("\nInvalid value entered\n");
               }
            }
            else
            {
               check_status(naibrd_DA_SetWatchdogWindow(cardIndex, module, windowTime * 1000));
            }
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static bool_t Handle_DA_DisplayWatchdog(int32_t cardIndex, int32_t module, int32_t chan)
{
   nai_status_bit_t wdStatLatched = 0u;
   nai_status_bit_t wdStatRT = 0u;
   uint32_t windowTime = 0u;
   uint32_t quietTime = 0u;

   printf("\n\nDA Watchdog Data:\n");
   check_status(naibrd_DA_GetWatchdogQuietTime(cardIndex, module, &quietTime));
   quietTime = quietTime / 1000;
   printf("Quiet Time: %d mS\n", quietTime);
   check_status(naibrd_DA_GetWatchdogWindow(cardIndex, module, &windowTime));
   windowTime = windowTime / 1000;
   printf("Window Time: %d mS\n", windowTime);

   check_status(naibrd_DA_GetStatus(cardIndex, module, chan, NAI_DA_STATUS_WATCHDOG_TIMER_FAULT_LATCHED, &wdStatLatched));
   check_status(naibrd_DA_GetStatus(cardIndex, module, chan, NAI_DA_STATUS_WATCHDOG_TIMER_FAULT_REALTIME, &wdStatRT));
   printf("WatchDog Status (R/L):  (%1d/%1d)\n", wdStatRT, wdStatLatched);

   printf("\n");

   return 0u;
}
static nai_status_t Handle_DA_StrobeWatchdog(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   int32_t* arg = (int32_t*)malloc(sizeof(int32_t) * 3);
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   p_naiapp_AppParameters_t p_da_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_da_params->cardIndex;
   int32_t module = p_da_params->module;

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

   printf("\r\n**NOTE: When this thread/application exits, the module will shut off all outputs and will need to be power cycled in order to be operational **");
   printf("\r\nEnter Y if you want to continue and N to go back: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         if ((inputBuffer[0] == 'Y') || (inputBuffer[0] == 'y'))
         {
            printf("\r\nStrobing Watchdog every (QuietTime) + (Window)/2...");
            printf("\r\nStarting thread...");
            /* Spawn thread here */

            arg[0] = cardIndex;
            arg[1] = module;

#if defined (__VXWORKS__)
            if (thread == 0)
#elif defined (LINUX)
            if (thread == (pthread_t)NULL)
#else
            if (thread == (int32_t*)NULL)
#endif
            {
#if defined (WIN32)
               LPDWORD threadID = 0;
               thread = CreateThread(NULL, 0, WD_Strobe_ThreadEntryPoint, arg, 0, threadID);
#elif defined (LINUX)
               pthread_create(&thread, NULL, WD_Strobe_ThreadEntryPoint, arg);
#elif defined (__VXWORKS__)
               thread = taskSpawn("WD_Strobe_Thread", 100, 0, 10000, (FUNCPTR)WD_Strobe_ThreadEntryPoint, (int32_t)arg, 0, 0, 0, 0, 0, 0, 0, 0, 0);
#else
#error Unsupported OS
#endif
               if (thread != 0) {}
               else
               {
                  free(arg);
                  printf("\nFailed to Create Thread");
               }
            }
            else
            {
#if defined (WIN32)
               LPDWORD threadID = 0;
#endif
               /* kill previous thread and create new one. Report this to them. */
               naiapp_kill_WDStrobe_Thread();
#if defined (WIN32)
               thread = CreateThread(NULL, 0, WD_Strobe_ThreadEntryPoint, arg, 0, threadID);
#elif defined (LINUX)
               pthread_create(&thread, NULL, WD_Strobe_ThreadEntryPoint, arg);
#elif defined (__VXWORKS__)
               thread = taskSpawn("WD_Strobe_Thread", 100, 0, 10000, (FUNCPTR)WD_Strobe_ThreadEntryPoint, (int32_t)arg, 0, 0, 0, 0, 0, 0, 0, 0, 0);
#else
#error Unsupported OS
#endif

#if defined (__VXWORKS__)
               if (thread != 0) {}
#elif defined (LINUX)
               if (thread != (pthread_t)NULL) {}
#else
               if (thread != (int32_t*)NULL) {}
#endif
               else
               {
                  free(arg);
                  printf("\nFailed to Create Thread");
               }
            }
         }
         else
         {
            printf("\r\nReturning to Menu...");
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static void naiapp_kill_WDStrobe_Thread()
{
#if defined (__VXWORKS__)
   if (thread != 0)
   {
      terminateThread = TRUE;
      thread = 0;
   }
#elif defined (LINUX)
   if (thread != ((pthread_t)NULL))
   {
      terminateThread = TRUE;
      thread = ((pthread_t)NULL);
   }
#else
   if (thread != ((int32_t*)NULL))
   {
      terminateThread = TRUE;
      thread = ((int32_t*)NULL);
   }
#endif
}
#if defined (WIN32)
DWORD WINAPI WD_Strobe_ThreadEntryPoint(LPVOID param)
#elif defined (LINUX)
void* WD_Strobe_ThreadEntryPoint(void* param)
#elif defined (__VXWORKS__)
static int WD_Strobe_ThreadEntryPoint(int32_t param)
#else
#error Unsupported OS
#endif
{
   uint32_t windowTime = 0u;
   uint32_t quietTime = 0u;
   int32_t delayTime = 0;
   int32_t* modInfo = (int32_t*)param;
   int32_t cardIndex = modInfo[0];
   int32_t module = modInfo[1];
   terminateThread = FALSE;
   free(modInfo);

   check_status(naibrd_DA_GetWatchdogQuietTime(cardIndex, module, &quietTime));
   check_status(naibrd_DA_GetWatchdogWindow(cardIndex, module, &windowTime));
   quietTime = quietTime / 1000;
   windowTime = windowTime / 1000;
   delayTime = quietTime + (windowTime / 2);
   check_status(naibrd_DA_WatchdogStrobe(cardIndex, module));
   do
   {
      nai_msDelay(delayTime);
      check_status(naibrd_DA_WatchdogStrobe(cardIndex, module));
   } while (!terminateThread);
   return NAI_SUCCESS;
}
static nai_status_t Handle_DA_kill_WDStrobe_Thread(int32_t paramCount, int32_t* p_params)
{
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
   UNREFERENCED_PARAMETER(p_params);
#endif

   naiapp_kill_WDStrobe_Thread();
   return NAI_SUCCESS;
}

Help Bot

X