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 2.x)

Overview

The DA BasicOps sample application demonstrates how to configure and operate digital-to-analog (DA) converter modules using the NAI Software Support Kit (SSK 2.x). It covers the core DA operations you will need in your own application: setting output voltage data, configuring range, polarity, and signal mode, managing channel status and BIT thresholds, enabling floating-point conversion mode, controlling power supply and channel output enable, performing watchdog operations, and managing module power reset.

This sample supports DA1 through DA5, CF1, and combination modules with DA functionality (CME, CMF, CMG). The application adapts its command menu based on the detected module type — DA2 modules add channel enable, DA3 modules add voltage/current mode and power supply control, DA5 modules use a separate optimized menu with bridge mode and power supply enable, and CF1 modules use a simplified write-through/strobe interface. Each menu command maps directly to one or more naibrd_DA_*() API calls that you can lift into your own code.

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

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a DA module installed (DA1-DA5, CF1, CME, CMF, or CMG).

  • SSK 2.x installed on your development host.

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

How to Run

Launch the da_basic_ops 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, the application detects the module type and presents the appropriate command menu.

Board Connection and Module Selection

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

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

  1. Call naiapp_RunBoardMenu() to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_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_GetModuleName() so downstream code can adapt to the specific DA variant installed.

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

   if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == NAI_TRUE)
   {
      while (!bQuit)
      {
         naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         naibrd_GetModuleCount(cardIndex, &moduleCount);
         naiapp_query_ModuleNumber(moduleCount, 1, &module);
         naibrd_GetModuleName(cardIndex, module, &modId);
         if (NAIBRD_MODULE_ID_CF1 == modId)
         {
            g_numBasicMenuCmds = CF1DA_COMMON_CMD_COUNT;
            bQuit = Run_CF1DA_BasicOps(cardIndex, module, modId);
         }
         else if (NAIBRD_MODULE_ID_DA5 == modId)
         {
            g_numBasicMenuCmds = DA5_STANDARDOP_CMD_COUNT;
            bQuit = Run_DA5_BasicOps(cardIndex, module, modId);
         }
         else
         {
            bQuit = Run_DA_BasicOps(cardIndex, module, modId);
         }
      }

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

   naiapp_access_CloseAllOpenCards();

   return 0;
}

Note the SSK 2.x differences from SSK 1.x in this startup sequence:

  • The VxWorks preprocessor guard uses NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS (SSK 1.x uses __VXWORKS__).

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

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

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

Important

Common connection errors you may encounter at this stage:

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

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

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

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

Program Structure

Entry Point

On VxWorks the entry point is DA_BasicOps(); on all other platforms it is main(). The preprocessor guard NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS selects between them. After detecting the module type, the application routes to one of three handler functions: Run_DA_BasicOps() for standard DA modules (DA1-DA4, CME, CMF, CMG), Run_CF1DA_BasicOps() for CF1 modules, or Run_DA5_BasicOps() for DA5 modules.

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:

naiapp_AppParameters_t da_params;
da_params.cardIndex = cardIndex;
da_params.module = module;
da_params.channel = DEF_DA_CHANNEL;
da_params.modId = modId;
da_params.maxChannels = naibrd_DA_GetChannelCount(da_params.modId);
  • cardIndex — identifies which board in a multi-board system.

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

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

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

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

Command Loop

Run_DA_BasicOps() drives the interactive command loop. On each iteration it displays the current channel data via DA_DisplayData(), prints the command menu, and dispatches the user’s selection to the matching handler function. The menu is dynamically constructed — module-specific commands for DA2 or DA3 are appended to the standard command table at startup:

/* Add the module specific menu items to the menu. */
switch (da_params.modId)
{
   case NAIBRD_MODULE_ID_DA2:
   case NAIBRD_MODULE_ID_CME:
   case NAIBRD_MODULE_ID_CMF:
   case NAIBRD_MODULE_ID_CMG:
      memcpy(&DA_StandardOpMenuCmds[DA_COMMON_CMD_COUNT],
         DA2_AdditionalMenuCommands, sizeof(DA2_AdditionalMenuCommands));
      g_numBasicMenuCmds = DA2_ADDITIONAL_CMD_COUNT;
      break;
   case NAIBRD_MODULE_ID_DA3:
      memcpy(&DA_StandardOpMenuCmds[DA_COMMON_CMD_COUNT],
         DA3_AdditionalMenuCommands, sizeof(DA3_AdditionalMenuCommands));
      g_numBasicMenuCmds = DA3_ADDITIONAL_CMD_COUNT;
      break;
   default:
      g_numBasicMenuCmds = DA_COMMON_CMD_COUNT;
      break;
}

Standard DA Command Menu (DA1-DA4, CME, CMF, CMG)

The standard command menu applies to DA1 through DA4 and combination modules. Module-specific commands are appended based on the detected module type.

Command Description

DATA

Set the output voltage data for a channel.

RANGE

Set the voltage output range.

POLARITY

Set the output polarity (unipolar or bipolar).

UPDATE_RATE

Set the channel update rate.

TEST_ENABLE

Enable or disable internal test mode (D3 test).

PBIT

Check power-on BIT results.

CLEAR

Clear DA status flags for the selected channel.

ALL CLEAR

Clear DA status flags for all channels.

FP_MODE

Enable or disable hardware floating-point conversion mode.

OFFSET

Set hardware floating-point conversion offset.

SCALE

Set hardware floating-point conversion scale factor.

BIT_THRESH

Set BIT error threshold.

CHANSTAT

Enable or disable channel status reporting.

WATCHDOG

Access the watchdog submenu (not available on DEOS).

PWRRESET

Access the module power reset submenu.

CH_ENABLE (DA2, CME, CMF, CMG only)

Enable or disable channel output.

MODE (DA3 only)

Set voltage or current output mode.

POWER (DA3 only)

Set power supply on or off.

DA5 Command Menu

DA5 modules use a separate, optimized command menu with DA5-specific features such as bridge mode and power supply enable:

Command Description

DATA

Set the output voltage data.

PS_ENABLE

Enable or disable the module power supply.

OUTPUT_ENABLE

Enable or disable channel output.

BRIDGE_ENABLE

Enable or disable channel full bridge mode.

CLEAR

Clear DA status flags for the selected channel.

ALL CLEAR

Clear DA status flags for all channels.

FLOAT

Enable or disable hardware floating-point conversion mode.

OFFSET

Set hardware floating-point conversion offset.

SCALE

Set hardware floating-point conversion scale factor.

CHANSTAT

Enable or disable channel status reporting.

PBIT

Check power-on BIT results.

THRESH

Get or set BIT error threshold.

WDT

Access the watchdog submenu (not available on DEOS).

CF1 Command Menu

CF1 modules use a simplified write-through/strobe interface with only five commands:

Command Description

DATA

Set the output voltage data.

RANGE

Set the voltage range.

POLARITY

Set the output polarity.

WriteThru

Enable or disable write-through mode.

Strobe

Strobe the output (push pending data to the hardware).

Watchdog Submenu

The watchdog submenu is accessed from the main menu via the WATCHDOG (standard) or WDT (DA5) command. It provides timing and strobe controls. A background thread can be started to continuously strobe the watchdog timer.

Note
The watchdog submenu is not available on DEOS because DEOS does not support POSIX threads.
Command Description

BACK

Return to the main menu.

DISPLAY

Display current watchdog settings (quiet time, window time, status).

TIME QUIET

Set the watchdog quiet time (in milliseconds).

WINDOW

Set the watchdog window time (in milliseconds).

STROBE

Start a background thread to continuously strobe the watchdog.

KILL

Terminate the watchdog strobe thread.

Module Power Reset Submenu

The module power reset submenu is accessed via the PWRRESET command. It displays the current power reset status and request bits, and lets you clear status flags or issue reset requests.

Command Description

BACK

Return to the main menu.

CLEAR

Clear a specific module power reset status flag.

SET

Set a module power reset request (Reset, Power Down, or Power Up).

Setting Output Data

The Handle_DA_Data() function prompts the user for an output voltage value and writes it to the selected channel. The function checks the current operating mode (voltage or current) to determine the correct data interpretation.

naibrd_da_mode_t mode = NAIBRD_DA_MODE_VOLTAGE;

/* Get the current operating mode */
check_status(naibrd_DA_GetOpMode(cardIndex, module, channel, &mode));

/* Set the output data (V or mA depending on mode) */
status = naibrd_DA_SetData(cardIndex, module, channel, mode, data);
  • naibrd_DA_GetOpMode() — retrieves the current operating mode (voltage or current).

  • naibrd_DA_SetData() — sets the output data for a channel.

  • naibrd_DA_GetData() — reads the current output data for a channel.

Configuring Range and Polarity

The application allows configuring the voltage output range and polarity for each channel. Range and polarity are set together via naibrd_DA_SetRangePolarity(). The handler first reads the current polarity or range so the other value is preserved.

naibrd_da_mode_t mode = NAIBRD_DA_MODE_VOLTAGE;
naibrd_da_polarity_t polarity = NAIBRD_DA_POLARITY_UNIPOLAR;
float64_t range = 0.0;

/* Read current range/polarity so we can change one without affecting the other */
check_status(naibrd_DA_GetRangePolarity(cardIndex, module, channel, mode,
   &polarity, &range));

/* Set new range, keeping existing polarity */
check_status(naibrd_DA_SetRangePolarity(cardIndex, module, channel, mode,
   polarity, newRange));
  • naibrd_DA_SetRangePolarity() — sets the output voltage range and polarity. For DA3 modules in voltage mode, valid ranges are 10V, 20V, 40V. In current mode, valid ranges are 25mA, 50mA, 100mA. For other DA modules, valid voltage ranges are 2.5V, 5V, and 10V.

  • naibrd_DA_GetRangePolarity() — reads the current range and polarity.

Setting Output Mode (DA3 Only)

The Handle_DA_Mode() function lets the user switch a DA3 channel between voltage and current output modes. This command is only supported on DA3 modules.

/* Set channel to current mode */
naibrd_DA_SetOpMode(cardIndex, module, channel, NAIBRD_DA_MODE_CURRENT);

/* Set channel to voltage mode */
naibrd_DA_SetOpMode(cardIndex, module, channel, NAIBRD_DA_MODE_VOLTAGE);
  • naibrd_DA_SetOpMode() — sets the output operating mode to voltage or current.

Enabling Channel Output (DA2, CME, CMF, CMG)

The Handle_DA_EnableOutput() function enables or disables the output for a selected channel. On DA5 modules, this same API is used via the OUTPUT_ENABLE command.

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

/* Disable channel output */
naibrd_DA_SetOutputEnable(cardIndex, module, channel, NAI_FALSE);
  • naibrd_DA_SetOutputEnable() — enables or disables the output for a channel.

  • naibrd_DA_GetOutputEnable() — reads the current output enable state.

Controlling Power Supply (DA3, DA5)

The Handle_DA_PowerSupply() function enables or disables the channel power supply. On DA3, each channel has its own power supply. On DA5, the power supply controls the entire module.

/* Enable channel power supply */
naibrd_DA_SetEnablePowerSupply(cardIndex, module, channel, NAI_TRUE);

/* Disable channel power supply */
naibrd_DA_SetEnablePowerSupply(cardIndex, module, channel, NAI_FALSE);
  • naibrd_DA_SetEnablePowerSupply() — enables or disables the power supply.

  • naibrd_DA_GetEnablePowerSupply() — reads the current power supply enable state.

Bridge Mode (DA5 Only)

The Handle_DA_BridgeMode() function enables or disables full bridge mode on a DA5 channel.

/* Enable bridge mode */
naibrd_DA_SetFullBridgeMode(cardIndex, module, channel, NAI_TRUE);

/* Disable bridge mode */
naibrd_DA_SetFullBridgeMode(cardIndex, module, channel, NAI_FALSE);
  • naibrd_DA_SetFullBridgeMode() — enables or disables full bridge mode for a channel.

  • naibrd_DA_GetFullBridgeMode() — reads the current bridge mode state.

Setting Update Rate

The Handle_DA_UpdateRate() function sets the output update rate for the module, specified in Hz.

uint32_t updateRateHz = 1000;

/* Set the update rate */
naibrd_DA_SetUpdateRate(cardIndex, module, updateRateHz);
  • naibrd_DA_SetUpdateRate() — sets the module update rate in Hz.

  • naibrd_DA_GetUpdateRate() — reads the current update rate.

Floating-Point Conversion Mode

Hardware floating-point conversion allows the module to apply an offset and scale factor to the output data automatically. Three commands control this feature:

/* Enable floating-point conversion mode */
naibrd_SetFloatingPointModeEnable(cardIndex, module, 0x1);

/* Set the offset for a channel */
naibrd_DA_SetFloatingPointAttribute(cardIndex, module, channel,
   NAIBRD_DA_ATTRIBUTE_OFFSET, offsetValue);

/* Set the scale factor for a channel */
naibrd_DA_SetFloatingPointAttribute(cardIndex, module, channel,
   NAIBRD_DA_ATTRIBUTE_SCALE_FACTOR, scaleValue);
  • naibrd_GetFloatingPointModeCapability() — checks whether the module supports floating-point mode.

  • naibrd_SetFloatingPointModeEnable() — enables or disables hardware floating-point conversion.

  • naibrd_DA_SetFloatingPointAttribute() — sets the offset or scale factor for a channel.

  • naibrd_DA_GetFloatingPointAttribute() — reads the offset or scale factor for a channel.

Internal Test Enable

The Handle_DA_TestEnable() function enables or disables the D3 internal test on the module.

/* Enable D3 internal test */
naibrd_DA_SetModuleBITEnable(cardIndex, module, NAIBRD_DA_D3_TEST, NAI_TRUE);

/* Disable D3 internal test */
naibrd_DA_SetModuleBITEnable(cardIndex, module, NAIBRD_DA_D3_TEST, NAI_FALSE);
  • naibrd_DA_SetModuleBITEnable() — enables or disables a specific BIT test type.

  • naibrd_DA_GetModuleBITEnable() — reads the current BIT test enable state.

Clearing Status Flags

The Handle_DA_ClearStatus() function clears latched status bits for a single channel. The user selects the status type (BIT, Overcurrent, or All). Handle_DA_ClearStatusAllChannels() applies the same operation across all channels.

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

/* Clear BIT latched status for a specific channel */
naibrd_DA_ClearChanMappedStatusRaw(cardIndex, module,
   NAIBRD_DA_STATUS_BIT_LATCHED, (mask << shift));

/* Clear Overcurrent latched status and reset overload */
naibrd_DA_ResetOverload(cardIndex, module);
naibrd_DA_ClearChanMappedStatusRaw(cardIndex, module,
   NAIBRD_DA_STATUS_OVERCURRENT_LATCHED, (mask << shift));
  • naibrd_DA_ClearChanMappedStatusRaw() — clears a specific latched status type using a channel bitmask.

  • naibrd_DA_ResetOverload() — resets the module overload condition.

  • naibrd_DA_GetChanMappedStatus() — reads a specific status type for a channel.

BIT Threshold

The Handle_DA_BITThresholds() function lets the user set, get, or clear the BIT error threshold and BIT counters. This is supported on DA2, DA3, DA4, CME, CMF, and CMG modules.

uint32_t bitThreshold = 5;

/* Set the BIT error threshold */
naibrd_DA_SetModuleBITErrorThreshold(cardIndex, module, bitThreshold);

/* Get the BIT error threshold */
naibrd_DA_GetModuleBITErrorThreshold(cardIndex, module, &bitThreshold);

/* Clear BIT logic for a channel */
naibrd_DA_ClearModuleBITLogic(cardIndex, module, channel);
  • naibrd_DA_SetModuleBITErrorThreshold() — sets the BIT error threshold.

  • naibrd_DA_GetModuleBITErrorThreshold() — reads the current BIT error threshold.

  • naibrd_DA_ClearModuleBITLogic() — clears the BIT counter for a channel.

Channel Status Enable

The Handle_DA_ChannelStatusEnable() function enables or disables status reporting for a selected channel. When disabled, statuses will not report and status-based interrupts will not assert.

/* Enable channel status reporting */
naibrd_DA_SetChanStatusEnable(cardIndex, module, channel, NAI_TRUE);

/* Disable channel status reporting */
naibrd_DA_SetChanStatusEnable(cardIndex, module, channel, NAI_FALSE);
  • naibrd_DA_SetChanStatusEnable() — enables or disables status reporting for a channel.

  • naibrd_DA_GetChanStatusEnable() — reads the current channel status enable state.

Power-On BIT Check

The Handle_DA_CheckPowerOnBIT() function checks whether the power-on BIT test has completed and reports the results for each channel. This is supported on DA2, DA3, DA4, CME, CMF, and CMG modules.

bool_t pbitComplete;
nai_status_bit_t bitFailed;

/* Check if PBIT has completed */
naibrd_DA_CheckPowerOnBITComplete(cardIndex, module, &pbitComplete);

if (pbitComplete)
{
   /* Read BIT status for each channel */
   for (channel = 1; channel <= channelCount; channel++)
   {
      naibrd_DA_GetChanMappedStatus(cardIndex, module, channel,
         NAIBRD_DA_STATUS_BIT_LATCHED, &bitFailed);
   }
}
  • naibrd_DA_CheckPowerOnBITComplete() — checks whether power-on BIT has completed.

  • naibrd_DA_GetChanMappedStatus() — reads the BIT result for each channel.

Watchdog Operations

The watchdog submenu provides timing and strobe controls. The Handle_DA_WatchDogQuietTime() and Handle_DA_WatchDogWindowTime() functions set the quiet and window times respectively. The Handle_DA_StrobeWatchdog() function starts a background thread that continuously strobes the watchdog at the interval (quiet time) + (window time / 2).

uint32_t quietTime_ms = 1000;
uint32_t windowTime_ms = 1000;

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

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

/* Strobe the watchdog */
naibrd_DA_WatchdogStrobe(cardIndex, module);
  • naibrd_DA_SetWatchdogQuietTime() — sets the quiet time before the watchdog becomes active (in microseconds).

  • naibrd_DA_GetWatchdogQuietTime() — reads the current quiet time.

  • naibrd_DA_SetWatchdogWindow() — sets the window time during which a strobe must occur (in microseconds).

  • naibrd_DA_GetWatchdogWindow() — reads the current window time.

  • naibrd_DA_WatchdogStrobe() — sends a watchdog strobe.

  • naibrd_DA_GetChanMappedStatus() with NAIBRD_DA_STATUS_WATCHDOG_TIMER_FAULT_LATCHED / NAIBRD_DA_STATUS_WATCHDOG_TIMER_FAULT_REALTIME — reads watchdog fault status.

Warning

When the watchdog strobe thread exits (or is killed), the module will shut off all outputs and will need to be power cycled in order to be operational again.

CF1 Write-Through and Strobe

CF1 modules use a write-through/strobe interface rather than the standard DA command set. When write-through mode is enabled, data written to a channel is immediately applied to the output. When disabled, data is staged and only applied when the strobe command is issued.

/* Enable write-through mode */
naibrd_DA_SetWriteThroughMode(cardIndex, module, NAI_TRUE);

/* Disable write-through mode (data staged until strobe) */
naibrd_DA_SetWriteThroughMode(cardIndex, module, NAI_FALSE);

/* Strobe output -- apply staged data */
naibrd_DA_UpdateStrobe(cardIndex, module);
  • naibrd_DA_SetWriteThroughMode() — enables or disables write-through mode.

  • naibrd_DA_GetWriteThroughMode() — reads the current write-through mode state.

  • naibrd_DA_UpdateStrobe() — issues a strobe to push staged data to the output.

Module Power Reset

The power reset submenu allows viewing the module’s power reset status flags, clearing specific status flags, and issuing power reset requests (Reset, Power Down, Power Up).

bool_t statusValue;

/* Read a power reset status flag */
naibrd_DA_GetModulePowerResetStatus(cardIndex, module,
   NAIBRD_DA_MODULE_POWER_RESET_STATUS_POWERED_DOWN, &statusValue);

/* Clear a power reset status flag */
naibrd_DA_ClearModulePowerResetStatus(cardIndex, module,
   NAIBRD_DA_MODULE_POWER_RESET_STATUS_POWERED_DOWN);

/* Issue a power reset request */
naibrd_DA_SetModulePowerReset(cardIndex, module,
   NAIBRD_DA_MODULE_POWER_RESET_REQUEST_RESET, NAI_TRUE);
  • naibrd_DA_GetModulePowerResetStatus() — reads a specific power reset status flag (Powered Down, Not Detected, Not Link Init, FW Not Ready, Comm Error).

  • naibrd_DA_ClearModulePowerResetStatus() — clears a specific power reset status flag.

  • naibrd_DA_GetModulePowerReset() — reads a power reset request bit.

  • naibrd_DA_SetModulePowerReset() — sets or clears a power reset request (Reset, Power Down, Power Up).

Troubleshooting Reference

Error / Symptom Possible Causes Suggested Resolution

Module not recognized as DA

The selected module slot does not contain a DA module.

Verify the module type in the slot. See the DA1 Manual.

Output voltage does not change

Channel output may be disabled, or the module power supply may be off (DA3/DA5).

Enable channel output with the CH_ENABLE / OUTPUT_ENABLE command or power supply with POWER / PS_ENABLE.

Output clipped to range limits

The requested voltage exceeds the configured range.

Increase the voltage range or reduce the requested output value.

BIT status shows failure

The built-in test detected a mismatch between the commanded and measured output.

Check external wiring. Clear BIT status and re-test. Verify the BIT threshold setting.

Watchdog triggered

The watchdog timer expired without receiving a strobe.

Use the watchdog submenu to start the strobe thread or increase the window time.

Floating-point mode has no effect

Floating-point mode is not enabled.

Use the FP_MODE or FLOAT command to enable hardware floating-point conversion.

Power reset status active

A module power reset occurred.

Clear the power reset status using the PWRRESET submenu.

WARNING about no specific menu commands

The application does not have module-specific commands for the detected DA variant.

The standard menu commands will still work. Only DA2, DA3, DA5, and CF1 have additional commands.

CF1 output not updating

Write-through mode is disabled and no strobe has been issued.

Enable write-through mode or use the Strobe command to push staged data.

Full Source

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

Full Source — da_basic_ops.c (SSK 2.x)
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_LINUX)
#include <pthread.h>
#endif

#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
#include <taskLib.h>
#endif
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"

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

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

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


#define 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 *SAMPLE_PGM_NAME = (const int8_t*)"DA Basic Operations";
static const int8_t *DEF_CONFIG_FILE = (const int8_t*)"default_DA_BasicOps.txt";

/* Function prototypes */
static bool_t Run_DA_BasicOps(int32_t cardIndex, int32_t module, uint32_t modId);
static bool_t Run_CF1DA_BasicOps(int32_t cardIndex, int32_t module, uint32_t modId);
static bool_t Run_DA5_BasicOps(int32_t cardIndex, int32_t module, uint32_t modId);

static nai_status_t Handle_DA_Data(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_Mode(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_ClearStatus(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_ClearStatusAllChannels(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_Range(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_Polarity(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_PowerSupply(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_EnableOutput(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_UpdateRate(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_TestEnable(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_CheckPowerOnBIT(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_FloatingPointMode(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_FloatingPointOffset(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_FloatingPointScaleFactor(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_BITThresholds(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_ChannelStatusEnable(int32_t paramCount, int32_t* params);

static nai_status_t Handle_DA_WriteThru(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_Strobe(int32_t paramCount, int32_t* params);

static nai_status_t Handle_DA_BridgeMode(int32_t paramCount, int32_t* p_params);
static nai_status_t DisplayDA5Data(int32_t cardIndex, int32_t module, int32_t maxchan);

#if !defined (NAIBSP_CONFIG_SOFTWARE_OS_DEOS)
static const int8_t *SAMPLE_WD_PGM_NAME = (const int8_t*)"DA Watchdog Operations";

static nai_status_t Handle_DA_WatchDogQuietTime(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_WatchDogWindowTime(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_DisplayWatchdog(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_StrobeWatchdog(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_kill_WDStrobe_Thread(int32_t paramCount, int32_t* params);
static nai_status_t Handle_DA_WatchdogShowMenu(int32_t paramCount, int32_t* params);

static void naiapp_kill_WDStrobe_Thread();

static bool_t terminateThread;
#endif

static nai_status_t Handle_DA_ModulePowerResetMenu(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_ClearModulePowerResetStatus(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_DA_SetModulePowerReset(int32_t paramCount, int32_t* p_params);

void DA_DisplayData(int32_t cardIndex, int32_t module, int32_t maxchan, uint32_t modId);

static const int32_t DEF_DA_CHANNEL = 1;

#if defined (NAIBSP_CONFIG_SOFTWARE_OS_WINDOWS)
DWORD WINAPI WD_Strobe_ThreadEntryPoint(LPVOID param);
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_LINUX)
void* WD_Strobe_ThreadEntryPoint(void* arg);
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
static int WD_Strobe_ThreadEntryPoint(int32_t nParam);
#endif

/********************/
/* Global Variables */
/********************/

/* TX Thread */
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_WINDOWS)
static HANDLE thread = NULL;
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_LINUX)
static pthread_t thread;
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
static TASK_ID  thread;
#endif

/****** Command Tables *******/
enum da_gen5_da_common_commands
{
   DA_COMMON_CMD_DATA,
   DA_COMMON_CMD_RANGE,
   DA_COMMON_CMD_POLARITY,
   DA_COMMON_CMD_UPDATE_RATE,
   DA_COMMON_CMD_TEST_ENABLE,
   DA_COMMON_CMD_PBIT,
   DA_COMMON_CMD_CLEAR_STATUS,
   DA_COMMON_CMD_CLEAR_STATUS_ALL_CHANS,
   DA_COMMON_CMD_FLOATING_POINT_MODE,
   DA_COMMON_CMD_FLOATING_POINT_OFFSET,
   DA_COMMON_CMD_FLOATING_POINT_SCALE_FACTOR,
   DA_COMMON_CMD_BIT_THRESHOLD,
   DA_COMMON_CMD_CHANNEL_STATUS_ENABLE,
#if !defined (NAIBSP_CONFIG_SOFTWARE_OS_DEOS)
   DA_COMMON_CMD_WD_MENU,
#endif
   DA_COMMON_CMD_MODULE_POWER_RESET_MENU,
   DA_COMMON_CMD_COUNT
};

#if !defined (NAIBSP_CONFIG_SOFTWARE_OS_DEOS)
enum da_gen5_da_watchdog_commands
{
   DA_COMMON_CMD_WD_QUIETTIME,
   DA_COMMON_CMD_WD_WINDOWTIME,
   DA_COMMON_CMD_WD_DISPLAY,
   DA_COMMON_CMD_WD_PET,
   DA_COMMON_CMD_WD_KILL,
   DA_COMMON_CMD_WD_BACK,
   DA_COMMON_CMD_WD_COUNT
};
#endif

enum da_module_power_reset_commands
{
   DA_MODULE_POWER_RESET_CMD_BACK,
   DA_MODULE_POWER_RESET_CMD_CLEAR_MODULE_POWER_RESET_STATUS,
   DA_MODULE_POWER_RESET_CMD_SET_MODULE_POWER_RESET,
   DA_MODULE_POWER_RESET_CMD_COUNT
};
/* NOTE: Leave room at the end of this structure so the DA_SPECIFIC commands can be added later on. The max number of DA_SPECIFIC commands is
         defined by DA_ADDITIONAL_MAX_CMD_COUNT. */
#define DA_ADDITIONAL_MAX_CMD_COUNT 20
naiapp_cmdtbl_params_t DA_StandardOpMenuCmds[DA_COMMON_CMD_COUNT + DA_ADDITIONAL_MAX_CMD_COUNT] =
{
   {"DATA",       "Set Data",                                                 DA_COMMON_CMD_DATA,                        Handle_DA_Data},
   {"RANGE",      "Set Voltage Range",                                        DA_COMMON_CMD_RANGE,                       Handle_DA_Range},
   {"POLARITY",   "Set Polarity",                                             DA_COMMON_CMD_POLARITY,                    Handle_DA_Polarity},
   {"UPDATE_RATE","Set the update rate",                                      DA_COMMON_CMD_UPDATE_RATE,                 Handle_DA_UpdateRate},
   {"TEST_ENABLE","Enable/Disable internal test",                             DA_COMMON_CMD_TEST_ENABLE,                 Handle_DA_TestEnable},
   {"PBIT",       "Check Power-On BIT",                                       DA_COMMON_CMD_PBIT,                        Handle_DA_CheckPowerOnBIT},
   {"CLEAR",      "Clear DA Statuses",                                        DA_COMMON_CMD_CLEAR_STATUS,                Handle_DA_ClearStatus},
   {"ALL CLEAR",  "Clear DA Statuses All Channels",                           DA_COMMON_CMD_CLEAR_STATUS_ALL_CHANS,      Handle_DA_ClearStatusAllChannels},
   {"FP_MODE",    "Enable/Disable Hardware Floating-Point Conversion Mode",   DA_COMMON_CMD_FLOATING_POINT_MODE,         Handle_DA_FloatingPointMode},
   {"OFFSET",     "Set Hardware Floating-Point Conversion Mode Offset",       DA_COMMON_CMD_FLOATING_POINT_OFFSET,       Handle_DA_FloatingPointOffset},
   {"SCALE",      "Set Hardware Floating-Point Conversion Mode Scale Factor", DA_COMMON_CMD_FLOATING_POINT_SCALE_FACTOR, Handle_DA_FloatingPointScaleFactor},
   {"BIT_THRESH",  "Set BIT Error Threshold",                                  DA_COMMON_CMD_BIT_THRESHOLD,              Handle_DA_BITThresholds},
   {"CHANSTAT",   "Channel Status Enable/Disable",                            DA_COMMON_CMD_CHANNEL_STATUS_ENABLE,       Handle_DA_ChannelStatusEnable},
#if !defined (NAIBSP_CONFIG_SOFTWARE_OS_DEOS)
   {"WATCHDOG",   "Show Watchdog Menu Options",                               DA_COMMON_CMD_WD_MENU,                     Handle_DA_WatchdogShowMenu},
#endif
   {"PWRRESET",  "Show Module Power Reset Menu Options", DA_COMMON_CMD_MODULE_POWER_RESET_MENU, Handle_DA_ModulePowerResetMenu}
   /* NOTE: There is room here for DA_ADDITIONAL_MAX_CMD_COUNT commands. They will be copied in later. */
};

#if !defined (NAIBSP_CONFIG_SOFTWARE_OS_DEOS)
naiapp_cmdtbl_params_t DA_WatchdogOpMenuCmds[DA_COMMON_CMD_WD_COUNT] =
{
   {"BACK",           "Back to Main Menu",                             0,                                         NULL},
   {"DISPLAY",        "Display Watchdog Settings",                     DA_COMMON_CMD_WD_DISPLAY,                  Handle_DA_DisplayWatchdog},
   {"TIME QUIET",     "Set Watchdog Quiet Time",                       DA_COMMON_CMD_WD_QUIETTIME,                Handle_DA_WatchDogQuietTime},
   {"WINDOW",         "Set Watchdog Window Time",                      DA_COMMON_CMD_WD_WINDOWTIME,               Handle_DA_WatchDogWindowTime},
   {"STROBE",         "Start thread to continuously strobe watchdog",  DA_COMMON_CMD_WD_PET,                      Handle_DA_StrobeWatchdog},
   {"KILL",           "Kill Watchdog strobing thread",                 DA_COMMON_CMD_WD_KILL,                     Handle_DA_kill_WDStrobe_Thread}
};
#endif

naiapp_cmdtbl_params_t DA_ModulePowerResetMenuCmds[DA_MODULE_POWER_RESET_CMD_COUNT] =
{
   {"BACK",  "Back to Main Menu",               DA_MODULE_POWER_RESET_CMD_BACK,                            NULL},
   {"CLEAR", "Clear Module Power Reset Status", DA_MODULE_POWER_RESET_CMD_CLEAR_MODULE_POWER_RESET_STATUS, Handle_DA_ClearModulePowerResetStatus},
   {"SET",   "Set Module Power Reset Request",  DA_MODULE_POWER_RESET_CMD_SET_MODULE_POWER_RESET,          Handle_DA_SetModulePowerReset}
};

/* DA additional commands. Different DA modules may use any combination of the below commands.*/
#define DA_ADDITIONAL_CMD_ITEM_CH_ENABLE(DA_CMD_NUM)      \
   {"CH_ENABLE",  "Enable/Disable Channel Output",                            DA_CMD_NUM,                     Handle_DA_EnableOutput}
#define DA_ADDITIONAL_CMD_ITEM_MODE(DA_CMD_NUM)           \
   {"MODE",       "Set Voltage/Current Mode",                                 DA_CMD_NUM,                     Handle_DA_Mode}
#define DA_ADDITIONAL_CMD_ITEM_POWER(DA_CMD_NUM)          \
   {"POWER",      "Set Power Supply ON/OFF",                                  DA_CMD_NUM,                     Handle_DA_PowerSupply}

/* NOTE: This structure is meant to be appended to DA_StandardOpMenuCmds, so the first enum MUST be set to DA_COMMON_CMD_COUNT and the number
         of specific commands cannot exceeded DA_ADDITIONAL_MAX_CMD_COUNT. */
enum da_gen5_da2_additional_commands
{
   DA2_ADDITIONAL_CMD_CHANNEL_ENABLE = DA_COMMON_CMD_COUNT,
   DA2_ADDITIONAL_CMD_COUNT
};

naiapp_cmdtbl_params_t DA2_AdditionalMenuCommands[] =
{
   DA_ADDITIONAL_CMD_ITEM_CH_ENABLE(DA2_ADDITIONAL_CMD_CHANNEL_ENABLE),
};

/* NOTE: This structure is meant to be appended to DA_StandardOpMenuCmds, so the first enum MUST be set to DA_COMMON_CMD_COUNT and the number
         of specific commands cannot exceeded DA_ADDITIONAL_MAX_CMD_COUNT. */
enum da_gen5_da3_additional_commands
{
   DA3_ADDITIONAL_CMD_MODE = DA_COMMON_CMD_COUNT,
   DA3_ADDITIONAL_CMD_POWER,
   DA3_ADDITIONAL_CMD_COUNT
};

naiapp_cmdtbl_params_t DA3_AdditionalMenuCommands[] =
{
   DA_ADDITIONAL_CMD_ITEM_MODE(DA3_ADDITIONAL_CMD_MODE),
   DA_ADDITIONAL_CMD_ITEM_POWER(DA3_ADDITIONAL_CMD_POWER)
};

enum da_gen5_cf1_additional_commands
{
   DA_CF1_CMD_WRITETHRU = DA_COMMON_CMD_COUNT,
   DA_CF1_CMD_STROBE,
   DA_CF1_ADDITIONAL_CMD_COUNT
};

#define CF1DA_COMMON_CMD_COUNT 5
naiapp_cmdtbl_params_t DA_CF1OpMenuCmds[CF1DA_COMMON_CMD_COUNT] =
{
   {"DATA",       "Set Data",                                                 DA_COMMON_CMD_DATA,                        Handle_DA_Data},
   {"RANGE",      "Set Voltage Range",                                        DA_COMMON_CMD_RANGE,                       Handle_DA_Range},
   {"POLARITY",   "Set Voltage Range",                                        DA_COMMON_CMD_POLARITY,                    Handle_DA_Polarity},
   {"WriteThru",  "Set Write-Through Mode",                                   DA_CF1_CMD_WRITETHRU,                      Handle_DA_WriteThru},
   {"Strobe",     "Strobe Output",                                            DA_CF1_CMD_STROBE,                         Handle_DA_Strobe},
};

enum da_gen5_da5_standardop_commands
{
   DA5_STANDARDOP_CMD_DATA,
   DA5_STANDARDOP_CMD_POWER_SUPPLY_ENABLE,
   DA5_STANDARDOP_CMD_OUTPUT_ENABLE,
   DA5_STANDARDOP_CMD_BRIDGE_ENABLE,
   DA5_STANDARDOP_CMD_CLEAR_STATUS,
   DA5_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,
   DA5_STANDARDOP_CMD_FLOATING_POINT_MODE,
   DA5_STANDARDOP_CMD_FLOATING_OFFSET,
   DA5_STANDARDOP_CMD_FLOATING_SCALE,
   DA5_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,
   DA5_STANDARDOP_CMD_PBIT,
   DA5_STANDARDOP_CMD_BIT_THRESHOLD,
   DA5_STANDARDOP_CMD_D3,
   DA5_STANDARDOP_CMD_WATCHDOG_MENU,
};

#define DA5_STANDARDOP_CMD_COUNT 13

naiapp_cmdtbl_params_t DA_DA5OpMenuCmds[] =
{
   {"DATA",       "Set Voltage Data",                                         DA5_STANDARDOP_CMD_DATA,                        Handle_DA_Data},
   {"PS_ENABLE",  "Enable/Disable Power Supply",                              DA5_STANDARDOP_CMD_POWER_SUPPLY_ENABLE,         Handle_DA_PowerSupply},
   {"OUTPUT_ENABLE","Enable/Disable Channel Output",                          DA5_STANDARDOP_CMD_OUTPUT_ENABLE,               Handle_DA_EnableOutput},
   {"BRIDGE_ENABLE","Enable/Disable Channel Bridge",                          DA5_STANDARDOP_CMD_BRIDGE_ENABLE,               Handle_DA_BridgeMode},
   {"CLEAR",      "Clear DA Statuses",                                        DA5_STANDARDOP_CMD_CLEAR_STATUS,                Handle_DA_ClearStatus},
   {"ALL CLEAR",  "Clear DA Statuses All Channels",                           DA5_STANDARDOP_CMD_CLEAR_STATUS_ALL_CHANS,      Handle_DA_ClearStatusAllChannels},
   {"FLOAT",      "Enable/Disable Floating-Point Mode",                       DA5_STANDARDOP_CMD_FLOATING_POINT_MODE,         Handle_DA_FloatingPointMode},
   {"OFFSET",     "Set Hardware Floating-Point Conversion Mode Offset",       DA5_STANDARDOP_CMD_FLOATING_OFFSET,             Handle_DA_FloatingPointOffset},
   {"SCALE",      "Set Hardware Floating-Point Conversion Mode Scale Factor", DA5_STANDARDOP_CMD_FLOATING_SCALE,              Handle_DA_FloatingPointScaleFactor},
   {"CHANSTAT",   "Channel Status Enable/Disable",                            DA5_STANDARDOP_CMD_CHANNEL_STATUS_ENABLE,       Handle_DA_ChannelStatusEnable},
   {"PBIT",       "Check Power-On BIT",                                       DA5_STANDARDOP_CMD_PBIT,                        Handle_DA_CheckPowerOnBIT},
   {"THRESH",     "Get/Set BIT Error Threshold",                              DA5_STANDARDOP_CMD_BIT_THRESHOLD,               Handle_DA_BITThresholds},
   /*{"D3",         "Enable/Disable D3 Test",                                   DA5_STANDARDOP_CMD_D3,                          Handle_DA_SetD3TestEnable},*/
#if !defined (NAIBSP_CONFIG_SOFTWARE_OS_DEOS)
   {"WDT",        "Show Watchdog Menu Options",                               DA5_STANDARDOP_CMD_WATCHDOG_MENU,               Handle_DA_WatchdogShowMenu}
#endif
};

static int32_t g_numBasicMenuCmds = 0;

/**************************************************************************************************************/
/**
 * <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 (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t DA_BasicOps(void)
#else
int32_t main(void)
#endif
{
   bool_t bQuit = NAI_FALSE;
   int32_t cardIndex = -1;
   int32_t module = 0;
   int32_t moduleCount = 0;
   uint32_t modId = 0u;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == NAI_TRUE)
   {
      while (!bQuit)
      {
         naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         naibrd_GetModuleCount(cardIndex, &moduleCount);
         naiapp_query_ModuleNumber(moduleCount, 1, &module);
         naibrd_GetModuleName(cardIndex, module, &modId);
         if (NAIBRD_MODULE_ID_CF1 == modId)
         {
            g_numBasicMenuCmds = CF1DA_COMMON_CMD_COUNT;
            bQuit = Run_CF1DA_BasicOps(cardIndex, module, modId);
         }
         else if (NAIBRD_MODULE_ID_DA5 == modId)
         {
            g_numBasicMenuCmds = DA5_STANDARDOP_CMD_COUNT;
            bQuit = Run_DA5_BasicOps(cardIndex, module, modId);
         }
         else
         {
            bQuit = Run_DA_BasicOps(cardIndex, module, modId);
         }
      }

      naiif_printf("Type 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, uint32_t modId)
{
   bool_t bQuit = NAI_FALSE;
   bool_t bContinue = NAI_TRUE;
   bool_t bCmdFound = NAI_FALSE;
   int32_t cmd = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   naiapp_AppParameters_t da_params;
   da_params.cardIndex = cardIndex;
   da_params.module = module;
   da_params.channel = DEF_DA_CHANNEL;
   da_params.modId = modId;


   /* Add the module specific menu items to the menu. */
   switch (da_params.modId)
   {
      case NAIBRD_MODULE_ID_DA2:
      case NAIBRD_MODULE_ID_CME:
      case NAIBRD_MODULE_ID_CMF:
      case NAIBRD_MODULE_ID_CMG:
         memcpy(&DA_StandardOpMenuCmds[DA_COMMON_CMD_COUNT], DA2_AdditionalMenuCommands, sizeof(DA2_AdditionalMenuCommands));
         g_numBasicMenuCmds = DA2_ADDITIONAL_CMD_COUNT;
         break;
      case NAIBRD_MODULE_ID_DA3:
         memcpy(&DA_StandardOpMenuCmds[DA_COMMON_CMD_COUNT], DA3_AdditionalMenuCommands, sizeof(DA3_AdditionalMenuCommands));
         g_numBasicMenuCmds = DA3_ADDITIONAL_CMD_COUNT;
         break;
      default:
         naiif_printf("WARNING- No specific menu commands for module id: 0x%X8. Only the standard menu will be displayed.\r\n", da_params.modId);
         g_numBasicMenuCmds = DA_COMMON_CMD_COUNT;
         break;
   }

   /* Get the Maximum DA Channels */
   da_params.maxChannels = naibrd_DA_GetChannelCount(da_params.modId);

   naiapp_utils_LoadParamMenuCommands(g_numBasicMenuCmds, DA_StandardOpMenuCmds);

   while (bContinue)
   {
      DA_DisplayData(cardIndex, module, da_params.maxChannels, modId);
      naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_PGM_NAME);
      naiif_printf("\r\nType DA command or %c to quit : main >", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
            if (bCmdFound)
            {
               DA_StandardOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)&da_params);
            }
            else
            {
               naiif_printf("Invalid command entered\r\n");
            }
         }
         else
            naiif_printf("Invalid command entered\r\n");
      }
      else
         bContinue = NAI_FALSE;
   }

#if !defined (NAIBSP_CONFIG_SOFTWARE_OS_DEOS)
   naiapp_kill_WDStrobe_Thread();
#endif

   return bQuit;
}

/**************************************************************************************************************/
/**
 * <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* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   naibrd_da_mode_t mode = NAIBRD_DA_MODE_VOLTAGE;
   float64_t data = 0.0;
   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)
      {
         check_status(naibrd_DA_GetOpMode(da_params->cardIndex, da_params->module, da_params->channel, &mode));
         naiif_printf("Type data value to set in V/mA (depending on the mode): ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               sscanf((const char*)inputBuffer, "%lf", &data);
               status = check_status(naibrd_DA_SetData(da_params->cardIndex, da_params->module, da_params->channel, mode,
                  data));
            }
         }
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function sets the channels operation mode: Voltage or Current.
 * </summary>
 */
/**************************************************************************************************************/
static nai_status_t Handle_DA_Mode(int32_t paramCount, int32_t* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   bool_t done = NAI_FALSE;
   char c = '\0';
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      if (da_params->modId == NAIBRD_MODULE_ID_DA3)
      {
         bQuit = naiapp_query_ChannelNumber(da_params->maxChannels, da_params->channel, &(da_params->channel));
         while (!bQuit && !done)
         {
            naiif_printf("Type 'C' for Current Mode, or 'V' for Voltage mode: ");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if (!bQuit)
            {
               if (inputResponseCnt > 0)
               {
                  sscanf((const char*)inputBuffer, "%c", &c);

                  if (c == 'C' || c == 'c')
                  {
                     status = check_status(naibrd_DA_SetOpMode(da_params->cardIndex, da_params->module, da_params->channel,
                        NAIBRD_DA_MODE_CURRENT));
                     done = NAI_TRUE;
                  }
                  else if (c == 'V' || c == 'v')
                  {
                     status = check_status(naibrd_DA_SetOpMode(da_params->cardIndex, da_params->module, da_params->channel,
                        NAIBRD_DA_MODE_VOLTAGE));
                     done = NAI_TRUE;
                  }
                  else
                  {
                     naiif_printf("Invalid entry...\r\n");
                     done = NAI_FALSE;
                  }
               }
            }
         }
      }
      else
      {
         naiif_printf("This feature is not supported by this module. Press Enter\r\n");
         sscanf((const char*)inputBuffer, "%c", &c);
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <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* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   uint32_t statnum = 0u;
   uint32_t mask = 0x1u;
   uint32_t shift = 0;
   naibrd_da_chan_mapped_status_type_t type = NAIBRD_DA_STATUS_BIT_LATCHED;
   bool_t bQuit = NAI_FALSE;
   bool_t errFlag = NAI_FALSE;
   bool_t clearAllFlag = NAI_FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      naiif_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);
      sscanf((const char*)inputBuffer, "%d", &statnum);

      switch (statnum)
      {
         case 0:
            type = NAIBRD_DA_STATUS_BIT_LATCHED;
            break;
         case 1:
            type = NAIBRD_DA_STATUS_OVERCURRENT_LATCHED;
            check_status(naibrd_DA_ResetOverload(da_params->cardIndex, da_params->module));
            break;
         case 2:
            clearAllFlag = NAI_TRUE;
            check_status(naibrd_DA_ResetOverload(da_params->cardIndex, da_params->module));
            break;
         default:
            errFlag = NAI_TRUE;
            if (!bQuit)
            {
               naiif_printf("\r\nError! Invalid Status Type\r\n");
            }
            break;
      }

      if ((!bQuit) && (inputResponseCnt > 0) && (errFlag == NAI_FALSE) && (clearAllFlag == NAI_FALSE))
      {
         bQuit = naiapp_query_ChannelNumber(da_params->maxChannels, da_params->channel, &(da_params->channel));
         shift = da_params->channel - 1;
         if (!bQuit)
         {
            check_status(naibrd_DA_ClearChanMappedStatusRaw(da_params->cardIndex, da_params->module, type, (mask << shift)));
            naiif_printf("\r\nStatus Cleared!\r\n");
         }
      }
      else if ((!bQuit) && (inputResponseCnt > 0) && (errFlag == NAI_FALSE) && (clearAllFlag == NAI_TRUE))
      {
         bQuit = naiapp_query_ChannelNumber(da_params->maxChannels, da_params->channel, &(da_params->channel));
         shift = da_params->channel - 1;
         if (!bQuit)
         {
            check_status(naibrd_DA_ClearChanMappedStatusRaw(da_params->cardIndex, da_params->module, NAIBRD_DA_STATUS_BIT_LATCHED, (mask << shift)));
            check_status(naibrd_DA_ClearChanMappedStatusRaw(da_params->cardIndex, da_params->module, NAIBRD_DA_STATUS_OVERCURRENT_LATCHED,
               (mask << shift)));
            naiif_printf("\r\nStatuses Cleared!\r\n");
         }
      }

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

   return status;
}

/**************************************************************************************************************/
/**
 * <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* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   uint32_t statnum = 0;
   uint32_t mask = 0x1u;
   uint32_t shift = 0;
   naibrd_da_chan_mapped_status_type_t type = NAIBRD_DA_STATUS_BIT_LATCHED;
   bool_t bQuit = NAI_FALSE;
   bool_t errFlag = NAI_FALSE;
   bool_t clearAllFlag = NAI_FALSE;
   int32_t chan = 0;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      naiif_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);
      sscanf((const char*)inputBuffer, "%d", &statnum);

      switch (statnum)
      {
         case 0:
            type = NAIBRD_DA_STATUS_BIT_LATCHED;
            break;
         case 1:
            type = NAIBRD_DA_STATUS_OVERCURRENT_LATCHED;
            check_status(naibrd_DA_ResetOverload(da_params->cardIndex, da_params->module));
            break;
         case 2:
            clearAllFlag = NAI_TRUE;
            check_status(naibrd_DA_ResetOverload(da_params->cardIndex, da_params->module));
            break;
         default:
            errFlag = NAI_TRUE;
            if (!bQuit)
            {
               naiif_printf("\r\nError! Invalid Status Type\r\n");
            }
            break;
      }

      if ((!bQuit) && (inputResponseCnt > 0) && (errFlag == NAI_FALSE) && (clearAllFlag == NAI_FALSE))
      {
         for (chan = 1; chan <= da_params->maxChannels; chan++)
         {
            shift = chan - 1;
            check_status(naibrd_DA_ClearChanMappedStatusRaw(da_params->cardIndex, da_params->module, type, (mask << shift)));
         }
         naiif_printf("\r\nStatuses Cleared!\r\n");
      }
      else if ((!bQuit) && (inputResponseCnt > 0) && (errFlag == NAI_FALSE) && (clearAllFlag == NAI_TRUE))
      {
         for (chan = 1; chan <= da_params->maxChannels; chan++)
         {
            shift = chan - 1;
            check_status(naibrd_DA_ClearChanMappedStatusRaw(da_params->cardIndex, da_params->module, NAIBRD_DA_STATUS_BIT_LATCHED, (mask << shift)));
            check_status(naibrd_DA_ClearChanMappedStatusRaw(da_params->cardIndex, da_params->module, NAIBRD_DA_STATUS_OVERCURRENT_LATCHED,
               (mask << shift)));
         }
         naiif_printf("\r\nStatuses Cleared!\r\n");
      }
      status = NAI_SUCCESS;
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <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* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   naibrd_da_mode_t mode = NAIBRD_DA_MODE_VOLTAGE;
   float64_t range = 0.0;
   float64_t tempRange = 0.0;
   float64_t defualtRange = 0.0;
   naibrd_da_polarity_t polarity = NAIBRD_DA_POLARITY_UNIPOLAR;
   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)
      {
         check_status(naibrd_DA_GetOpMode(da_params->cardIndex, da_params->module, da_params->channel, &mode));
         if (da_params->modId == NAIBRD_MODULE_ID_DA3)
         {
            if (mode == NAIBRD_DA_MODE_VOLTAGE)
            {
               defualtRange = 10.0;
               naiif_printf("Type Voltage Range to set ('10' for 10V, '20' for 20V, '40' for 40V)");
            }
            else if (mode == NAIBRD_DA_MODE_CURRENT)
            {
               defualtRange = 25.0;
               naiif_printf("Type Current Range to set ('25' for 25mA, '50' for 50mA, '100' for 100ma)");
            }
            else
            {
            }
         }
         else
         {
            defualtRange = 5.0;
            naiif_printf("Type Voltage Range to set ('2.5' for 2.5V, '5' for 5V, '10' for 10V)");
         }

         naiif_printf("(default:%lf): ", defualtRange);

         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               sscanf((const char*)inputBuffer, "%lf", &range);

               check_status(naibrd_DA_GetRangePolarity(da_params->cardIndex, da_params->module, da_params->channel, mode, &polarity,
                  &tempRange));
               check_status(naibrd_DA_SetRangePolarity(da_params->cardIndex, da_params->module, da_params->channel, mode, polarity,
                  range));
            }
            else if (inputResponseCnt == 0)
            {
               check_status(naibrd_DA_GetRangePolarity(da_params->cardIndex, da_params->module, da_params->channel, mode, &polarity,
                  &tempRange));
               check_status(naibrd_DA_SetRangePolarity(da_params->cardIndex, da_params->module, da_params->channel, mode, polarity,
                  defualtRange));
            }
         }
      }

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

   return status;
}

/**************************************************************************************************************/
/**
 * <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* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   bool_t errFlag = NAI_FALSE;
   naibrd_da_mode_t mode = NAIBRD_DA_MODE_VOLTAGE;
   naibrd_da_polarity_t polarity = NAIBRD_DA_POLARITY_UNIPOLAR;
   float64_t rangeRead = 0.0;
   naibrd_da_polarity_t tempPolarity = NAIBRD_DA_POLARITY_UNIPOLAR;
   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)
      {
         check_status(naibrd_DA_GetOpMode(da_params->cardIndex, da_params->module, da_params->channel, &mode));
         naiif_printf("Type polarity mode to set ('U' for Unipolar, 'B' for Bipolar)(default:B): ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               if (inputBuffer[0] == 'u' || inputBuffer[0] == 'U')
               {
                  polarity = NAIBRD_DA_POLARITY_UNIPOLAR;
               }
               else if (inputBuffer[0] == 'b' || inputBuffer[0] == 'B')
               {
                  polarity = NAIBRD_DA_POLARITY_BIPOLAR;
               }
               else
               {
                  errFlag = NAI_TRUE;
                  naiif_printf("\r\nError! Invalid polarity mode!\r\n");
               }

               if (errFlag == NAI_FALSE)
               {
                  check_status(naibrd_DA_GetRangePolarity(da_params->cardIndex, da_params->module, da_params->channel,
                     mode, &tempPolarity, &rangeRead));
                  check_status(naibrd_DA_SetRangePolarity(da_params->cardIndex, da_params->module, da_params->channel,
                     mode, polarity, rangeRead));
               }
            }
            else if (inputResponseCnt == 0)
            {
               check_status(naibrd_DA_GetRangePolarity(da_params->cardIndex, da_params->module, da_params->channel,
                  mode, &tempPolarity, &rangeRead));
               check_status(naibrd_DA_SetRangePolarity(da_params->cardIndex, da_params->module, da_params->channel,
                  mode, NAIBRD_DA_POLARITY_BIPOLAR, rangeRead));
            }
         }
      }
      status = NAI_SUCCESS;
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <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_PowerSupply(int32_t paramCount, int32_t* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   bool_t errFlag = NAI_FALSE;
   bool_t enableVal;
   char c = '\0';
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      if (da_params->modId == NAIBRD_MODULE_ID_DA3)
      {
         bQuit = naiapp_query_ChannelNumber(da_params->maxChannels, da_params->channel, &(da_params->channel));
         if (!bQuit)
         {
            naiif_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)
               {
                  sscanf((const char*)inputBuffer, "%c", &c);
                  enableVal = (c == '0' ? NAI_FALSE : NAI_TRUE);

                  if (errFlag == NAI_FALSE)
                  {
                     check_status(naibrd_DA_SetEnablePowerSupply(da_params->cardIndex, da_params->module, da_params->channel, enableVal));
                     if (enableVal == NAI_FALSE)
                     {
                        naiif_printf("\r\nChannel %d Power Supply Disabled\r\n", da_params->channel);
                     }
                     else
                     {
                        naiif_printf("\r\nChannel %d Power Supply Enabled\r\n", da_params->channel);
                     }
                  }
               }
               else if (inputResponseCnt == 0)
               {
                  check_status(naibrd_DA_SetEnablePowerSupply(da_params->cardIndex, da_params->module, da_params->channel, NAI_TRUE));
                  naiif_printf("\r\nChannel %d Power Supply Enabled\r\n", da_params->channel);
               }
            }
         }
         status = NAI_SUCCESS;
      }
      else
      {
         naiif_printf("\r\n\r\n*** This feature is not supported by this module.***\r\n");
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function enables/disables the module/channel's output 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_EnableOutput(int32_t paramCount, int32_t* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   bool_t errFlag = NAI_FALSE;
   bool_t enableVal;
   char c = '\0';
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      if ((da_params->modId == NAIBRD_MODULE_ID_DA2) || (da_params->modId == NAIBRD_MODULE_ID_CME) || (da_params->modId == NAIBRD_MODULE_ID_CMF)
         || (da_params->modId == NAIBRD_MODULE_ID_CMG) )
      {
         bQuit = naiapp_query_ChannelNumber(da_params->maxChannels, da_params->channel, &(da_params->channel));
         if (!bQuit)
         {
            naiif_printf("Type '0' to turn off/disable channel's output or '1' to turn on/enable channel's output. (default:1): ");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if (!bQuit)
            {
               if (inputResponseCnt > 0)
               {
                  sscanf((const char*)inputBuffer, "%c", &c);
                  enableVal = (c == '0' ? NAI_FALSE : NAI_TRUE);

                  if (errFlag == NAI_FALSE)
                  {
                     check_status(naibrd_DA_SetOutputEnable(da_params->cardIndex, da_params->module, da_params->channel, enableVal));
                     if (enableVal == NAI_FALSE)
                     {
                        naiif_printf("\r\nChannel %d Output Disabled\r\n", da_params->channel);
                     }
                     else
                     {
                        naiif_printf("\r\nChannel %d Output Enabled\r\n", da_params->channel);
                     }
                  }
               }
               else if (inputResponseCnt == 0)
               {
                  check_status(naibrd_DA_SetOutputEnable(da_params->cardIndex, da_params->module, da_params->channel, NAI_TRUE));
                  naiif_printf("\r\nChannel %d Output Enabled\r\n", da_params->channel);
               }
            }
         }
         status = NAI_SUCCESS;
      }
      else
      {
         naiif_printf("\r\n\r\n*** This feature is not supported by this module.***\r\n");
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function sets the update rate for the module. The user is prompted for the value in Hz. If the value is
 * within range for the specific D/A used, then the range will be set, otherwise the original setting will not
 * be affected.
 * </summary>
 */
/**************************************************************************************************************/
static nai_status_t Handle_DA_UpdateRate(int32_t paramCount, int32_t* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   uint32_t updateRateHz = 0;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      naiif_printf("Enter new update rate in Hz: ");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            sscanf((const char*)inputBuffer, "%u", &updateRateHz);
            status = check_status(naibrd_DA_SetUpdateRate(da_params->cardIndex, da_params->module, updateRateHz));
         }
      }
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function
 * </summary>
 */
/**************************************************************************************************************/
static nai_status_t Handle_DA_TestEnable(int32_t paramCount, int32_t* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   naibrd_da_test_type_t testType = NAIBRD_DA_D3_TEST;
   bool_t testEnable = NAI_FALSE;
   char c = 0;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      while (!bQuit && (c != '2') && (c != '3'))
      {
         naiif_printf("Which test would you like to access? D3 (enter '3'): ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);

         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               sscanf((const char*)inputBuffer, "%c", &c);
               if (c == '3')
               {
                  testType = NAIBRD_DA_D3_TEST;
               }
            }
         }
      }

      if (!bQuit)
      {
         naiif_printf("Enable (enter 'e') or any other value to disable: ");
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);

         if (inputResponseCnt > 0)
         {
            sscanf((const char*)inputBuffer, "%c", &c);
            if (c == 'e' || c == 'E')
            {
               testEnable = NAI_TRUE;
            }
            else
            {
               testEnable = NAI_FALSE;
            }

            status = check_status(naibrd_DA_SetModuleBITEnable(da_params->cardIndex, da_params->module, testType, testEnable));
         }
      }
   }

   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* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int32_t channelCount = 0, channel = 0;
   bool_t pbitComplete;
   nai_status_bit_t bitFailed;

   if (APP_PARAM_COUNT == paramCount)
   {
      switch (da_params->modId)
      {
         case NAIBRD_MODULE_ID_DA2:
         case NAIBRD_MODULE_ID_DA3:
         case NAIBRD_MODULE_ID_DA4:
         case NAIBRD_MODULE_ID_CME:
         case NAIBRD_MODULE_ID_CMF:
         case NAIBRD_MODULE_ID_CMG:
         {
            channelCount = naibrd_DA_GetChannelCount(da_params->modId);

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

            if (pbitComplete)
            {
               /* Read the BIT status */
               naiif_printf("Checking the result of the Power-on BIT test...\r\n");
               for (channel = 1; channel <= channelCount; channel++)
               {
                  status = naibrd_DA_GetChanMappedStatus(da_params->cardIndex, da_params->module, channel, NAIBRD_DA_STATUS_BIT_LATCHED,
                     &bitFailed);
                  naiif_printf("Ch. %d: %s", channel, bitFailed ? "BIT FAILED\r\n" : "BIT Passed\r\n");
               }
            }
         }
         break;
         case NAIBRD_MODULE_ID_DA5:
         case NAIBRD_MODULE_ID_DA1:
         default:
            naiif_printf("\r\n\r\n*** This feature is not supported by this module.***\r\n");
            status = NAI_ERROR_NOT_SUPPORTED;
            break;
      }
   }

   return status;
}


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


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

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


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

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


   if (APP_PARAM_COUNT == paramCount)
   {
      naibrd_GetFloatingPointModeCapability(da_params->cardIndex, da_params->module, &fpCapable);
      if (fpCapable == NAI_TRUE)
      {
         bQuit = naiapp_query_ChannelNumber(da_params->maxChannels, da_params->channel, &(da_params->channel));
         if (!bQuit)
         {
            naiif_printf("Type Hardware Floating-Point Conversion Mode Scale Factor setting to set: ");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if ((!bQuit) && (inputResponseCnt > 0))
            {
               sscanf((const char*)inputBuffer, "%lf", &scale);
               status = check_status(naibrd_DA_SetFloatingPointAttribute(da_params->cardIndex, da_params->module, da_params->channel,
                  NAIBRD_DA_ATTRIBUTE_SCALE_FACTOR, scale));
            }
         }
      }
      else
      {
         naiif_printf("\r\n\r\n*** This feature is not supported by this module.***\r\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* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   uint32_t bitThreshold = 0u;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      switch (da_params->modId)
      {
         case NAIBRD_MODULE_ID_DA2:
         case NAIBRD_MODULE_ID_DA3:
         case NAIBRD_MODULE_ID_DA4:
         case NAIBRD_MODULE_ID_CME:
         case NAIBRD_MODULE_ID_CMF:
         case NAIBRD_MODULE_ID_CMG:
         {
            naiif_printf("Set or Get BIT Error Threshold? ('S' = Set, 'G' = Get, 'C' = Clear BIT Counter): ");
            naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);

            if (inputBuffer[0] == 'S')
            {
               naiif_printf("\r\nType the desired BIT Error Threshold (Default = 5): ");
               naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               naiif_printf("\r\n");
               bitThreshold = atoi((const char*)inputBuffer);
               status = naibrd_DA_SetModuleBITErrorThreshold(da_params->cardIndex, da_params->module, bitThreshold);
            }
            else if (inputBuffer[0] == 'G')
            {
               status = naibrd_DA_GetModuleBITErrorThreshold(da_params->cardIndex, da_params->module, &bitThreshold);
               naiif_printf("\r\nBIT Error threshold: %d", bitThreshold);
            }
            else if (inputBuffer[0] == 'C')
            {
               int32_t ch;
               int32_t channels = naibrd_DA_GetChannelCount(da_params->modId);

               naiif_printf("\r\nClearing BIT counters on all channels.\r\n");
               for (ch = 1; ch <= channels; ch++)
                  status = naibrd_DA_ClearModuleBITLogic(da_params->cardIndex, da_params->module, ch);
            }
            else
            {
               naiif_printf("\r\nSelection not recognized.\r\n");
            }
         }
         break;
         case NAIBRD_MODULE_ID_DA1:
         case NAIBRD_MODULE_ID_DA5:
         default:
            naiif_printf("\r\n\r\n*** This feature is not supported by this module.***\r\n");
            status = NAI_ERROR_NOT_SUPPORTED;
            break;
      }
   }
   else
   {
      status = NAI_ERROR_INVALID_VALUE;
   }
   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function Enables\Disables the reporting of the Channel Status. When enabled, the user will get status
 * updates. When disabled, the statuses will not report and status-based interrupts will not assert.
 * </summary>
 */
/**************************************************************************************************************/
static nai_status_t Handle_DA_ChannelStatusEnable(int32_t paramCount, int32_t* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_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)
      {
         naiif_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')) ? NAI_TRUE : NAI_FALSE));
         }
      }
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function displays the DA Standard Operations data.
 * </summary>
 */
/**************************************************************************************************************/
void DA_DisplayData(int32_t cardIndex, int32_t module, int32_t maxchan, uint32_t modId)
{
   int32_t chan = 0;
   float64_t data = 0.0;
   naibrd_da_mode_t mode = NAIBRD_DA_MODE_VOLTAGE;
   char* sMode = NULL;
   float64_t range = 0.0;
   naibrd_da_polarity_t polarity = NAIBRD_DA_POLARITY_UNIPOLAR;
   nai_status_bit_t bitStatLatched = 0;
   nai_status_bit_t overCurrentStatLatched = 0;
   nai_status_bit_t bitStatRealtime = 0;
   nai_status_bit_t overCurrentStatRealtime = 0;
   float64_t wrapVolt = 0.0;
   float64_t wrapCurrent = 0.0;
   bool_t floatMode = NAI_FALSE;
   float64_t offset = 0.0;
   float64_t scale = 0.0;
   bool_t enable = NAI_FALSE;
   char* sVoltPolarity = NULL;
   uint32_t updateRateHz = 0u;
   bool_t d3enabled = NAI_FALSE;
   bool_t chanStatusEnabled = NAI_TRUE;
   const char* chanStatus = NULL;

   naiif_printf("\r\n\r\nDA Standard Operations Data:\r\n\r\n");
   if (modId == NAIBRD_MODULE_ID_DA3)
   {
      naiif_printf("    Power   Voltage           Data              Wrap     Wrap    Floating-   Floating-   Channel    BIT   Overcurrent\r\n");
      naiif_printf("    Supply  Current   Data    Range  Voltage   Voltage  Current    Point    Point Scale   Staus    Status   Status   \r\n");
      naiif_printf("Ch  Enable    Mode   (V/mA)    (V)   Polarity    (V)     (mA)     Offset      Factor     Enabled   (R/L)    (R/L)    \r\n");
      naiif_printf("---------------------------------------------------------------------------------------------------------------------\r\n");
   }
   else
   {
      naiif_printf("                    Voltage            Wrap     Wrap    Floating-   Floating-   Channel    BIT   Overcurrent\r\n");
      naiif_printf("    Output   Data    Range  Voltage   Voltage  Current    Point    Point Scale   Staus    Status   Status   \r\n");
      naiif_printf("Ch  Enable   (V)      (V)   Polarity    (V)     (mA)     Offset      Factor     Enabled   (R/L)    (R/L)    \r\n");
      naiif_printf("------------------------------------------------------------------------------------------------------------\r\n");
   }

   for (chan = 1; chan <= maxchan; chan++)
   {
      check_status(naibrd_DA_GetOpMode(cardIndex, module, chan, &mode));
      check_status(naibrd_DA_GetData(cardIndex, module, chan, mode, &data));
      check_status(naibrd_DA_GetRangePolarity(cardIndex, module, chan, mode, &polarity, &range));

      switch (mode)
      {
         case NAIBRD_DA_MODE_VOLTAGE:
            sMode = "Voltage";
            break;
         case NAIBRD_DA_MODE_CURRENT:
            sMode = "Current";
            break;
         default:
            sMode = " ERROR ";
            break;
      }

      switch (polarity)
      {
         case NAIBRD_DA_POLARITY_UNIPOLAR:
            sVoltPolarity = "UNIPOLAR";
            break;
         case NAIBRD_DA_POLARITY_BIPOLAR:
            sVoltPolarity = "BIPOLAR ";
            break;
         default:
            sVoltPolarity = " ERROR  ";
            break;
      }

      check_status(naibrd_DA_GetWrapVoltage(cardIndex, module, chan, &wrapVolt));
      check_status(naibrd_DA_GetWrapCurrent(cardIndex, module, chan, &wrapCurrent));
      check_status(naibrd_DA_GetFloatingPointAttribute(cardIndex, module, chan, NAIBRD_DA_ATTRIBUTE_OFFSET, &offset));
      check_status(naibrd_DA_GetFloatingPointAttribute(cardIndex, module, chan, NAIBRD_DA_ATTRIBUTE_SCALE_FACTOR, &scale));
      check_status(naibrd_DA_GetChanMappedStatus(cardIndex, module, chan, NAIBRD_DA_STATUS_BIT_LATCHED, &bitStatLatched));
      check_status(naibrd_DA_GetChanMappedStatus(cardIndex, module, chan, NAIBRD_DA_STATUS_BIT_REALTIME, &bitStatRealtime));
      check_status(naibrd_DA_GetChanMappedStatus(cardIndex, module, chan, NAIBRD_DA_STATUS_OVERCURRENT_LATCHED, &overCurrentStatLatched));
      check_status(naibrd_DA_GetChanMappedStatus(cardIndex, module, chan, NAIBRD_DA_STATUS_OVERCURRENT_REALTIME, &overCurrentStatRealtime));
      check_status(naibrd_DA_GetChanStatusEnable(cardIndex, module, chan, &chanStatusEnabled));
      chanStatus = (chanStatusEnabled == NAI_FALSE) ? "NO " : "YES";

      if (modId == NAIBRD_MODULE_ID_DA3)
      {
         check_status(naibrd_DA_GetEnablePowerSupply(cardIndex, module, chan, &enable));
         naiif_printf("%2d    %d     %s %7.3f  %7.3f %s  %7.3f  %7.3f  %7.3f      %7.3f      %s     (%1d/%1d)    (%1d/%1d)\r\n", chan, enable, sMode,
            data, range, sVoltPolarity, wrapVolt, wrapCurrent, offset, scale, chanStatus, bitStatRealtime, bitStatLatched,
            overCurrentStatRealtime, overCurrentStatLatched);
      }
      else
      {
         check_status(naibrd_DA_GetOutputEnable(cardIndex, module, chan, &enable));
         naiif_printf("%2d    %d    %7.3f  %7.3f %s  %7.3f  %7.3f  %7.3f      %7.3f      %s     (%1d/%1d)    (%1d/%1d)\r\n", chan, enable,
            data, range, sVoltPolarity, wrapVolt, wrapCurrent, offset, scale, chanStatus, bitStatRealtime, bitStatLatched,
            overCurrentStatLatched, overCurrentStatRealtime);
      }

   }

   check_status(naibrd_DA_GetUpdateRate(cardIndex, module, &updateRateHz));
   naiif_printf("\r\n\r\nUpdate Rate: %uHz\r\n", updateRateHz);

   check_status(naibrd_DA_GetModuleBITEnable(cardIndex, module, NAIBRD_DA_D3_TEST, &d3enabled));
   naiif_printf("Internal tests enabled: ");
   if (d3enabled == NAI_FALSE)
   {
      naiif_printf("None");
   }
   else
   {
      if (d3enabled == NAI_TRUE)
      {
         naiif_printf("D3");
      }
   }
   naiif_printf("\r\n");

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

#if !defined (NAIBSP_CONFIG_SOFTWARE_OS_DEOS)
/**************************************************************************************************************/
/**
 * <summary>
 * This function displays the menu for watchdog commands
 * </summary>
 */
/**************************************************************************************************************/
static nai_status_t Handle_DA_WatchdogShowMenu(int32_t paramCount, int32_t* params)
{
   bool_t bQuit = NAI_FALSE;
   bool_t bContinue = NAI_TRUE;
   bool_t bCmdFound = NAI_FALSE;
   int32_t cmd = 0;
   int32_t numMenuCmds = 0;
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   numMenuCmds = DA_COMMON_CMD_WD_COUNT;

   naiapp_utils_LoadParamMenuCommands(numMenuCmds, DA_WatchdogOpMenuCmds);
   while (bContinue)
   {
      Handle_DA_DisplayWatchdog(paramCount,params);
      naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_WD_PGM_NAME);
      naiif_printf("\r\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 = NAI_FALSE;
               numMenuCmds = DA_COMMON_CMD_COUNT;
               naiapp_utils_LoadParamMenuCommands(numMenuCmds, DA_StandardOpMenuCmds);
            }
            else
            {
               bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
               if (bCmdFound)
               {
                  DA_WatchdogOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)da_params);
               }
               else
               {
                  naiif_printf("Invalid command entered\r\n");
               }
            }
         }
         else
            naiif_printf("Invalid command entered\r\n");
      }
      else
         bContinue = NAI_FALSE;
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function sets the watchdog quiet time for the module. The user is prompted for the value in ms.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t Handle_DA_WatchDogQuietTime(int32_t paramCount, int32_t* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   uint32_t quietTime = 0u;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      naiif_printf("\r\n*** To use this sample strobe it is recommended to set a quiet time > 500 ms **");
      naiif_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)
         {
            quietTime = (uint32_t)atoi((const char *)inputBuffer);
            status = check_status(naibrd_DA_SetWatchdogQuietTime(da_params->cardIndex, da_params->module, quietTime*1000));
         }
      }
   }

   return status;
}
/**************************************************************************************************************/
/**
 * <summary>
 * This function sets the watchdog window time for the module. The user is prompted for the value in ms.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t Handle_DA_WatchDogWindowTime(int32_t paramCount, int32_t* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   uint32_t windowTime = 0u;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      naiif_printf("\r\n*** To use this sample strobe it is recommended to set a window time > 500 ms **");
      naiif_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)
         {
            windowTime = (uint32_t)atoi((const char *)inputBuffer);
            status = check_status(naibrd_DA_SetWatchdogWindow(da_params->cardIndex, da_params->module, windowTime * 1000));
         }
      }
   }

   return status;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function displays the DA Watchdog Operations data.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t Handle_DA_DisplayWatchdog(int32_t paramCount, int32_t* params)
{
   nai_status_bit_t wdStatLatched = NAI_STATUS_BIT_LO;
   nai_status_bit_t wdStatRT = NAI_STATUS_BIT_LO;
   uint32_t windowTime = 0u;
   uint32_t quietTime = 0u;
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;

   if (APP_PARAM_COUNT == paramCount)
   {
      naiif_printf("\r\n\r\nDA Watchdog Data:\r\n");
      check_status(naibrd_DA_GetWatchdogQuietTime(da_params->cardIndex, da_params->module, &quietTime));
      quietTime = quietTime/1000;
      naiif_printf("Quiet Time: %dmS\r\n", quietTime);
      check_status(naibrd_DA_GetWatchdogWindow(da_params->cardIndex, da_params->module, &windowTime));
      windowTime = windowTime/1000;
      naiif_printf("Window Time: %dmS\r\n", windowTime);

      check_status(naibrd_DA_GetChanMappedStatus(da_params->cardIndex, da_params->module, 1, NAIBRD_DA_STATUS_WATCHDOG_TIMER_FAULT_LATCHED, &wdStatLatched));
      check_status(naibrd_DA_GetChanMappedStatus(da_params->cardIndex, da_params->module, 1, NAIBRD_DA_STATUS_WATCHDOG_TIMER_FAULT_REALTIME, &wdStatRT));
      naiif_printf("WatchDog Status (R/L):  (%1d/%1d)\r\n", wdStatRT, wdStatLatched);

      naiif_printf("\r\n");
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
 * <summary>
 * This function will start a thread to continuously strobe the watchdog. The user is prompted for the value in ms.
 * 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.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t Handle_DA_StrobeWatchdog(int32_t paramCount, int32_t* params)
{
   p_naiapp_AppParameters_t da_params = (p_naiapp_AppParameters_t)params;
   bool_t bQuit = NAI_FALSE;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   int32_t* arg = (int32_t*)malloc(sizeof(int32_t) * 3);
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   if (APP_PARAM_COUNT == paramCount)
   {
      naiif_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 **");
      naiif_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')
            {
               naiif_printf("\r\nStrobing Watchdog every (QuietTime) + (Window)/2...");
               naiif_printf("\r\nStarting thread...");
               /* Spawn thread here */

               arg[0] = da_params->cardIndex;
               arg[1] = da_params->module;

#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
               if (thread == 0)
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_WINDOWS)
               if (thread != ((int32_t*)NULL))
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_LINUX)
               if (thread != ((pthread_t)NULL))
#endif
               {
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_WINDOWS)
                  LPDWORD threadID = 0;
                  thread = CreateThread(NULL, 0, WD_Strobe_ThreadEntryPoint, arg, 0, threadID);
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_LINUX)
                  pthread_create(&thread, NULL, WD_Strobe_ThreadEntryPoint, arg);
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_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);
                     naiif_printf("\r\nFailed to Create Thread");
                  }
               }
               else
               {
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_WINDOWS)
                  LPDWORD threadID = 0;
#endif
                  /* kill previous thread and create new one. Report this to them. */

                  naiapp_kill_WDStrobe_Thread();

#if defined (NAIBSP_CONFIG_SOFTWARE_OS_WINDOWS)
                  thread = CreateThread(NULL, 0, WD_Strobe_ThreadEntryPoint, arg, 0, threadID);
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_LINUX)
                  pthread_create(&thread, NULL, WD_Strobe_ThreadEntryPoint, arg);
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_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 (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
                  if (thread != 0) {}
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_WINDOWS)
               if (thread != ((int32_t*)NULL)){}
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_LINUX)
               if (thread != ((pthread_t)NULL)){}
#endif
                  else
                  {

                     free(arg);
                     naiif_printf("\r\nFailed to Create Thread");
                  }

               }

            }
            else
            {
               naiif_printf("\r\nReturning to Menu...");
            }

         }
      }
   }

   return status;
}
/**************************************************************************************************************/
/**
 * <summary>
 * This function will terminate the WD strobing thread. Module will shut off outputs at this state and
 * will need to be power cycled to be operational.
 * </summary>
 */
 /**************************************************************************************************************/
static void naiapp_kill_WDStrobe_Thread()
{
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
   if (thread != 0)
   {
      terminateThread = NAI_TRUE;
      thread = 0;
   }
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_WINDOWS)
   if (thread != ((int32_t*)NULL))
   {
      terminateThread = NAI_TRUE;
      thread = ((int32_t*)NULL);
   }
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_LINUX)
   if (thread != ((pthread_t)NULL))
   {
      terminateThread = NAI_TRUE;
      thread = ((pthread_t)NULL);
   }
#endif
}
/**************************************************************************************************************/
/**
 * <summary>
 * This function will continuously loop, strobing the watchdog every QuietTime + Window/2.
 * </summary>
 */
 /**************************************************************************************************************/
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_WINDOWS)
DWORD WINAPI WD_Strobe_ThreadEntryPoint(LPVOID param)
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_LINUX)
void* WD_Strobe_ThreadEntryPoint(void* param)
#elif defined (NAIBSP_CONFIG_SOFTWARE_OS_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 = NAI_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);
   naibrd_DA_WatchdogStrobe(cardIndex, module);
   do
   {
      naiif_msDelay(delayTime);
      check_status(naibrd_DA_WatchdogStrobe(cardIndex, module));
   } while (!terminateThread);
   return NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
 * <summary>
 * This function will terminate the WD strobing thread. Module will shut off outputs at this state and
 * will need to be power cycled to be operational.
 * </summary>
 */
 /**************************************************************************************************************/
static nai_status_t Handle_DA_kill_WDStrobe_Thread(int32_t paramCount, int32_t* params)
{
   NAIBSP_UNREFERENCED_PARAMETER(paramCount);
   NAIBSP_UNREFERENCED_PARAMETER(params);

   naiapp_kill_WDStrobe_Thread();
   return NAI_SUCCESS;
}
#endif

/**************************************************************************************************************/
/**
<summary>
Configure_DA_ModulePowerResetMenu displays the menu for module power reset commands.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_ModulePowerResetMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   bool_t bContinue = NAI_TRUE;
   bool_t bCmdFound = NAI_FALSE;
   int32_t cmd = 0;
   int32_t numMenuCmds = 0;
   bool_t poweredDownStatus = NAI_FALSE;
   bool_t notDetectedStatus = NAI_FALSE;
   bool_t notLinkInitStatus = NAI_FALSE;
   bool_t notFWNotStatus = NAI_FALSE;
   bool_t commErrorStatus = NAI_FALSE;
   bool_t resetRequest = NAI_FALSE;
   bool_t powerDownRequest = NAI_FALSE;
   bool_t powerUpRequest = NAI_FALSE;
   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;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   numMenuCmds = DA_MODULE_POWER_RESET_CMD_COUNT;
   naiapp_utils_LoadParamMenuCommands(numMenuCmds, DA_ModulePowerResetMenuCmds);
   while (bContinue)
   {
      naiif_printf("\r\n\r\n\r\n");
      naiif_printf(" -----------------------------Status------------------------------    ----------Request----------\r\n");
      naiif_printf(" Powered Down  Not Detected  Not Link Init  Not FW Not  Comm Error    Reset  Power Down  Power Up\r\n");
      naiif_printf(" ------------  ------------  -------------  ----------  ----------    -----  ----------  --------\r\n");
      check_status(naibrd_DA_GetModulePowerResetStatus(cardIndex, module, NAIBRD_DA_MODULE_POWER_RESET_STATUS_POWERED_DOWN, &poweredDownStatus));
      check_status(naibrd_DA_GetModulePowerResetStatus(cardIndex, module, NAIBRD_DA_MODULE_POWER_RESET_STATUS_NOT_DETECTED, &notDetectedStatus));
      check_status(naibrd_DA_GetModulePowerResetStatus(cardIndex, module, NAIBRD_DA_MODULE_POWER_RESET_STATUS_NOT_LINK_INIT, &notLinkInitStatus));
      check_status(naibrd_DA_GetModulePowerResetStatus(cardIndex, module, NAIBRD_DA_MODULE_POWER_RESET_STATUS_FW_NOT_READY, &notFWNotStatus));
      check_status(naibrd_DA_GetModulePowerResetStatus(cardIndex, module, NAIBRD_DA_MODULE_POWER_RESET_STATUS_COMM_ERROR, &commErrorStatus));
      check_status(naibrd_DA_GetModulePowerReset(cardIndex, module, NAIBRD_DA_MODULE_POWER_RESET_REQUEST_RESET, &resetRequest));
      check_status(naibrd_DA_GetModulePowerReset(cardIndex, module, NAIBRD_DA_MODULE_POWER_RESET_REQUEST_POWER_DOWN, &powerDownRequest));
      check_status(naibrd_DA_GetModulePowerReset(cardIndex, module, NAIBRD_DA_MODULE_POWER_RESET_REQUEST_POWER_UP, &powerUpRequest));
      naiif_printf("      %1d             %1d              %1d            %1d           %1d           %1d        %1d          %1d\r\n",
         poweredDownStatus, notDetectedStatus, notLinkInitStatus, notFWNotStatus, commErrorStatus, resetRequest, powerDownRequest, powerUpRequest);
      naiapp_display_ParamMenuCommands((int8_t*)"DT Power Reset Operation Menu");
      naiif_printf("\r\nType DA Module Power Reset command or %c to quit : main > module power reset >", 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 = NAI_FALSE;
            }
            else
            {
               bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
               if (bCmdFound)
               {
                  DA_ModulePowerResetMenuCmds[cmd].func(paramCount, p_params);
               }
               else
               {
                  naiif_printf("\r\nInvalid command entered\r\n");
               }
            }
         }
      }
      else
         bContinue = NAI_FALSE;
   }
   naiapp_utils_LoadParamMenuCommands(g_numBasicMenuCmds, DA_StandardOpMenuCmds);
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_DA_ClearModulePowerResetStatus handles the user request to clear the module power reset status
and calls the method in the naibrd library to clear the module power reset status. The user is
prompted for the module power reset status type to clear.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_ClearModulePowerResetStatus(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   naibrd_da_module_power_reset_status_type_t statusTypeToClear = (naibrd_da_module_power_reset_status_type_t)0u;
   bool_t modulePowerResetStatusRead = 0u;
   char statusTypeStr[14] = "";
   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;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   NAIBSP_UNREFERENCED_PARAMETER(paramCount);

   naiif_printf("\r\nSelect Module Power Reset Status type to clear: (0 for Powered Down, 1 for Not Detected, 2 for Not Link Init, 3 for Not FW Not, 4 for Comm Error, q for quit): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      switch (inputBuffer[0])
      {
      case '0':
         statusTypeToClear = NAIBRD_DA_MODULE_POWER_RESET_STATUS_POWERED_DOWN;
         sprintf(statusTypeStr, "Powered Down");
         break;
      case '1':
         statusTypeToClear = NAIBRD_DA_MODULE_POWER_RESET_STATUS_NOT_DETECTED;
         sprintf(statusTypeStr, "Not Detected");
         break;
      case '2':
         statusTypeToClear = NAIBRD_DA_MODULE_POWER_RESET_STATUS_NOT_LINK_INIT;
         sprintf(statusTypeStr, "Not Link Init");
         break;
      case '3':
         statusTypeToClear = NAIBRD_DA_MODULE_POWER_RESET_STATUS_FW_NOT_READY;
         sprintf(statusTypeStr, "Not FW Not");
         break;
      case '4':
         statusTypeToClear = NAIBRD_DA_MODULE_POWER_RESET_STATUS_COMM_ERROR;
         sprintf(statusTypeStr, "Comm Error");
         break;
      case 'q':
      case 'Q':
         bQuit = NAI_TRUE;
         break;
      default:
         bQuit = NAI_TRUE;
         naiif_printf("\r\nInvalid module power reset status type entered\r\n");
         break;
      }

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

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_DA_SetModulePowerReset handles the user request to set the module power reset request
and calls the method in the naibrd library to set the module power reset request. The user is
prompted for the module power reset request type to set, and then the user is prompted to set
or reset the request bit.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Handle_DA_SetModulePowerReset(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   naibrd_da_module_power_reset_type_t resetTypeToSet = (naibrd_da_module_power_reset_type_t)0u;
   char resetTypeStr[11] = "";
   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;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;


   NAIBSP_UNREFERENCED_PARAMETER(paramCount);

   naiif_printf("\r\nSelect Module Power Reset Request type to set: (0 for Reset, 1 for Power Down, 2 for Power Up, q for quit): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if ((!bQuit) && (inputResponseCnt > 0))
   {
      switch (inputBuffer[0])
      {
      case '0':
         resetTypeToSet = NAIBRD_DA_MODULE_POWER_RESET_REQUEST_RESET;
         sprintf(resetTypeStr, "Reset");
         break;
      case '1':
         resetTypeToSet = NAIBRD_DA_MODULE_POWER_RESET_REQUEST_POWER_DOWN;
         sprintf(resetTypeStr, "Power Down");
         break;
      case '2':
         resetTypeToSet = NAIBRD_DA_MODULE_POWER_RESET_REQUEST_POWER_UP;
         sprintf(resetTypeStr, "Power Up");
         break;
      case 'q':
      case 'Q':
         bQuit = NAI_TRUE;
         break;
      default:
         bQuit = NAI_TRUE;
         naiif_printf("\r\nInvalid module power reset request type entered\r\n");
         break;
      }

      if (!bQuit)
      {
         naiif_printf("\r\nDo you want to set or reset the %s request? (1 to set, 0 to reset): ", resetTypeStr);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if ((!bQuit) && (inputResponseCnt > 0))
         {
            if (inputBuffer[0] == '0')
            {
               check_status(naibrd_DA_SetModulePowerReset(cardIndex, module, resetTypeToSet, (bool_t)NAI_FALSE));
            }
            else if (inputBuffer[0] == '1')
            {
               check_status(naibrd_DA_SetModulePowerReset(cardIndex, module, resetTypeToSet, (bool_t)NAI_TRUE));
            }
            else
            {
               naiif_printf("\r\nInvalid selection entered\r\n");
            }
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

static bool_t Run_CF1DA_BasicOps(int32_t cardIndex, int32_t module, uint32_t modId)
{
   bool_t bQuit = NAI_FALSE;
   bool_t bCmdFound = NAI_FALSE;
   naiapp_AppParameters_t da_params;
   int32_t channel = 0;
   float64_t data = 0.0;
   float64_t range = 0.0;
   naibrd_da_polarity_t polarity;
   bool_t writeThru = NAI_FALSE;
   int32_t cmd = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   da_params.cardIndex = cardIndex;
   da_params.module = module;
   da_params.channel = 1;
   da_params.displayHex = NAI_FALSE;
   da_params.modId = modId;
   da_params.maxChannels = naibrd_DA_GetChannelCount(modId);

   naiapp_utils_LoadParamMenuCommands(g_numBasicMenuCmds, DA_CF1OpMenuCmds);

   do
   {
      naiif_printf("\r\n\r\n");
      naiif_printf("              Data         Range\r\n");
      naiif_printf("Channel      (Volts)       (Volts)    Polarity \r\n");
      naiif_printf("-------------------------------------------------\r\n");

      for (channel = 1; channel <= da_params.maxChannels; channel++)
      {
         check_status(naibrd_DA_GetData(cardIndex, module, channel, NAIBRD_DA_MODE_VOLTAGE,&data));
         check_status(naibrd_DA_GetRangePolarity(cardIndex, module, channel, NAIBRD_DA_MODE_VOLTAGE, &polarity, &range));

         naiif_printf("%2d         %7.3f       %7.3f        %s\r\n", channel, data, range,
            NAIBRD_DA_POLARITY_UNIPOLAR == polarity ? "UNIPOLAR" : "BIPOLAR");
      }

      check_status(naibrd_DA_GetWriteThroughMode(cardIndex, module, &writeThru));
      naiif_printf("\r\nWrite-Through Mode: %s\r\n", NAI_FALSE == writeThru ? "OFF" : "ON" );

      naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_PGM_NAME);
      naiif_printf("\r\nType DA command or %c to quit : main >", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
            if (bCmdFound)
            {
               DA_CF1OpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)&da_params);
            }
            else
            {
               naiif_printf("Invalid command entered\r\n");
            }
         }
         else
            naiif_printf("Invalid command entered\r\n");
      }
   } while (!bQuit);

   return bQuit;
}

static nai_status_t Handle_DA_WriteThru(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_da_params = (p_naiapp_AppParameters_t)p_params;
   int8_t inputBuffer[5];
   int32_t inputResponseCnt;
   nai_status_t status = NAI_ERROR_UNKNOWN;
   bool_t bQuit = NAI_TRUE;
   bool_t writeThruMode = NAI_FALSE;

   if (APP_PARAM_COUNT == paramCount)
   {
      naiif_printf("\r\n\r\nEnter '1' to set write-through mode on, any other key to turn off.\r\n");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            if ( '1' == inputBuffer[0] )
            {
               writeThruMode = NAI_TRUE;
            }
         }

         status = check_status(naibrd_DA_SetWriteThroughMode(p_da_params->cardIndex, p_da_params->module, writeThruMode));
      }
   }

   return status;
}

static nai_status_t Handle_DA_Strobe(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_da_params = (p_naiapp_AppParameters_t)p_params;
   nai_status_t status = NAI_ERROR_UNKNOWN;

   if (APP_PARAM_COUNT == paramCount)
   {
      status = check_status(naibrd_DA_UpdateStrobe(p_da_params->cardIndex, p_da_params->module));
   }

   return status;
}

static bool_t Run_DA5_BasicOps(int32_t cardIndex, int32_t module, uint32_t modId)
{
   bool_t bQuit = NAI_FALSE;
   bool_t bCmdFound = NAI_FALSE;
   naiapp_AppParameters_t da_params;
   int32_t cmd = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   da_params.cardIndex = cardIndex;
   da_params.module = module;
   da_params.channel = 1;
   da_params.displayHex = NAI_FALSE;
   da_params.modId = modId;
   da_params.maxChannels = naibrd_DA_GetChannelCount(modId);

   naiapp_utils_LoadParamMenuCommands(g_numBasicMenuCmds, DA_DA5OpMenuCmds);

   do
   {
      DisplayDA5Data(da_params.cardIndex, da_params.module, da_params.maxChannels);

      naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_PGM_NAME);
      naiif_printf("\r\nType DA command or %c to quit : main >", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
            if (bCmdFound)
            {
               DA_DA5OpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)&da_params);
            }
            else
            {
               naiif_printf("Invalid command entered\r\n");
            }
         }
         else
            naiif_printf("Invalid command entered\r\n");
      }
   } while (!bQuit);

   return bQuit;
}

static nai_status_t DisplayDA5Data(int32_t cardIndex, int32_t module, int32_t maxchan)
{
   int32_t chan;
   float64_t data;
   bool_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 wrapCurrent;
   bool_t psEnable;
   bool_t floatModeEnabled = NAI_FALSE;
   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 = NAI_FALSE;
   char* sBridgeEnable;

   naiif_printf( "\r\n\r\nDA Standard Operations Data:\r\n\r\n" );

   naiif_printf( "              External  External    Wrap     Wrap                         BIT   Overcurrent  Summary  Floating Floating\r\n" );
   naiif_printf( "                Power     Power    Voltage  Current   Output   Bridge    Status   Status     Status     Point    Point \r\n" );
   naiif_printf( "Ch     Data      (+)       (-)       (V)     (mA)     Enable   Enable    (L/R)    (L/R)       (L/R)     Offset   Scale \r\n" );
   naiif_printf( "----------------------------------------------------------------------------------------------------------------------------------\r\n" );
   for ( chan = 1; chan <= maxchan; chan++ )
   {
      check_status( naibrd_DA_GetData( cardIndex, module, chan, NAIBRD_DA_MODE_VOLTAGE, &data ) );
      check_status( naibrd_DA_GetExtPowerVoltage( cardIndex, module, chan, &extPowerVPos ) );
      check_status( naibrd_DA_GetNegExtPowerVoltage( cardIndex, module, chan, &extPowerVNeg ) );
      check_status( naibrd_DA_GetWrapVoltage( cardIndex, module, chan, &wrapVolt ) );
      check_status( naibrd_DA_GetWrapCurrent( cardIndex, module, chan, &wrapCurrent ) );
      check_status( naibrd_DA_GetOutputEnable( cardIndex, module, chan, &outputEnable ) );
      sOutputEnable = (NAI_FALSE == outputEnable) ? "DISABLED" : "ENABLED ";
      check_status(naibrd_DA_GetFullBridgeMode(cardIndex, module, chan, &bridgeEnable));
      sBridgeEnable = (NAI_FALSE == bridgeEnable) ? "DISABLED" : "ENABLED ";
      check_status( naibrd_DA_GetChanMappedStatus( cardIndex, module, chan, NAIBRD_DA_STATUS_BIT_LATCHED, &bitStatLatched ) );
      check_status( naibrd_DA_GetChanMappedStatus( cardIndex, module, chan, NAIBRD_DA_STATUS_BIT_REALTIME, &bitStatRealtime ) );
      check_status( naibrd_DA_GetChanMappedStatus( cardIndex, module, chan, NAIBRD_DA_STATUS_OVERCURRENT_LATCHED, &overCurrentStatLatched ) );
      check_status( naibrd_DA_GetChanMappedStatus( cardIndex, module, chan, NAIBRD_DA_STATUS_OVERCURRENT_REALTIME, &overCurrentStatRealtime ) );
      check_status( naibrd_DA_GetChanMappedStatus( cardIndex, module, chan, NAIBRD_DA_STATUS_SUMMARY_LATCHED, &summaryStatusLatched ) );
      check_status( naibrd_DA_GetChanMappedStatus( cardIndex, module, chan, NAIBRD_DA_STATUS_SUMMARY_REALTIME, &summaryStatusRealtime ) );
      check_status( naibrd_DA_GetFloatingPointAttribute( cardIndex, module, chan,  NAIBRD_DA_ATTRIBUTE_OFFSET, &fpOffset) );
      check_status( naibrd_DA_GetFloatingPointAttribute( cardIndex, module, chan,  NAIBRD_DA_ATTRIBUTE_SCALE_FACTOR, &fpScale) );
      naiif_printf( "%2d  %7.3f   %7.3f   %7.3f  %7.3f  %7.3f   %s  %s   (%1d/%1d)    (%1d/%1d)       (%1d/%1d)   %7.3f  %7.3f\r\n",
         chan, data, extPowerVPos, extPowerVNeg, wrapVolt, wrapCurrent, sOutputEnable, sBridgeEnable, bitStatLatched, bitStatRealtime,
         overCurrentStatLatched, overCurrentStatRealtime, summaryStatusLatched, summaryStatusRealtime, fpOffset, fpScale );
   }

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

   check_status( naibrd_DA_GetEnablePowerSupply( cardIndex, module, 1, &psEnable ) );
   sPsEnable = (NAI_FALSE == psEnable) ? "DISABLED" : "ENABLED ";
   naiif_printf( "\r\nModule power supply is %s.", sPsEnable );

   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 = NAI_FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (APP_PARAM_COUNT == paramCount)
   {
      bQuit = naiapp_query_ChannelNumber( da_basicops_params->maxChannels, da_basicops_params->channel, &(da_basicops_params->channel) );
      if (!bQuit)
      {
         naiif_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, NAI_TRUE));
            else
               check_status(naibrd_DA_SetFullBridgeMode(cardIndex, module, da_basicops_params->channel, NAI_FALSE));
         }
      }
   }
   return NAI_SUCCESS;
}

Help Bot

X