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

DSW BasicOps

DSW BasicOps Sample Application (SSK 1.x)

Overview

The DSW BasicOps sample application demonstrates how to configure and operate discrete switch (DSW) channels using the NAI Software Support Kit (SSK 1.x). It covers the core DSW operations you will need in your own application: setting switch output states (open or closed), configuring four programmable voltage thresholds for multi-level signal detection, reading real-time voltage and current measurements, and monitoring channel status including BIT, overcurrent, threshold crossings, and signal transitions.

DSW modules are enhanced discrete I/O channels with programmable voltage thresholds. Unlike standard discrete (DT) modules that detect simple high/low states, DSW modules provide four independent threshold levels — Min Low, Lower, Upper, and Max High — that divide the input voltage range into distinct zones. This allows your application to detect not just whether a signal is present, but where it falls within a defined voltage envelope. The hardware also tracks transitions between zones, giving you edge-detection capability without polling.

This sample supports the following DSW module types: K7 (Gen3), DT2, and DT5 (Gen5). It serves as a practical API reference — each menu command maps directly to one or more naibrd_DSW_*() API calls that you can lift into your own code.

For interrupt-driven DSW monitoring, see the DSW Interrupt Basic sample application guide, which demonstrates how to configure interrupts triggered by threshold crossings and state transitions.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a DSW module installed (K7, DT2, or DT5).

  • SSK 1.x installed on your development host.

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

How to Run

Launch the DSW_BasicOps executable from your build output directory. On startup the application looks for a configuration file (default_DSW_BasicOp.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, select a channel and the command menu lets you exercise each DSW operation.

Board Connection and Module Selection

Note
This startup sequence is common to all NAI sample applications. The board connection and module selection code shown here is not specific to DSW. For details on board connection configuration, see the First Time Setup Guide.

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

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

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

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

  4. Retrieve the module ID with naibrd_GetModuleID() so downstream code can adapt to the specific DSW variant installed.

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

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

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

   naiapp_access_CloseAllOpenCards();
   return 0;
}
Important

Common connection errors you may encounter at this stage:

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

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

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

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

Program Structure

Entry Point

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

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

The startup flow is the same in both cases:

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

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

  3. Call Run_DSW_BasicOps() to validate the module and enter the interactive command loop.

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

Module Validation

Run_DSW_BasicOps() validates the selected module by calling naibrd_DSW_GetChannelCount(). If the module is not a recognized DSW type, the channel count returns zero and the function prints an error. In your own application, use this same check to confirm the target slot contains a DSW module before issuing DSW API calls:

MaxChannel = naibrd_DSW_GetChannelCount(ModuleID);

if (MaxChannel == 0)
{
   printf(" *** Module selection not recognized as DSW module. ***\n\n");
}
else
{
   Cfg_DSW_Channel(cardIndex, module, ModuleID, MaxChannel);
}

Application Parameters

The Cfg_DSW_Channel() 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  dsw_params;
p_naiapp_AppParameters_t dsw_basicops_params = &dsw_params;
dsw_basicops_params->cardIndex = cardIndex;
dsw_basicops_params->module = module;
dsw_basicops_params->modId = ModuleID;
dsw_basicops_params->channel = chan;
  • cardIndex — identifies which board in a multi-board system.

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

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

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

Command Loop

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

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

Command Description

Switch

Set the switch output state (open or closed)

ML

Set the Min Low threshold voltage

L

Set the Lower threshold voltage

U

Set the Upper threshold voltage

MH

Set the Max High threshold voltage

STAT

Display all channel status flags

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

Switch State Configuration

The primary output operation on a DSW channel is setting the switch state — open (NO contact, no current path) or closed (NO-COM contact closure, current path established). This controls the physical relay or solid-state switch on the channel.

Set Switch State

To control the switch output on a channel in your own application, call naibrd_DSW_SetSwitchState() with the desired state value. Pass NAI_DSW_STATE_LO (0) for open or NAI_DSW_STATE_HI (1) for closed:

nai_dsw_state_t switchstate = NAI_DSW_STATE_HI;  /* closed */
check_status(naibrd_DSW_SetSwitchState(cardIndex, module, chan, switchstate));
  • cardIndex — identifies the board.

  • module — the slot containing the DSW module.

  • chan — the channel to control.

  • switchstate — NAI_DSW_STATE_LO (open) or NAI_DSW_STATE_HI (closed).

Read Switch and Input State

To read the current state of a channel, use two complementary calls. naibrd_DSW_GetSwitchState() returns the commanded output state (what you set), while naibrd_DSW_GetInputState() returns the actual sensed input state (what the hardware detects):

nai_dsw_state_t switchstate = 0;
nai_dsw_state_t inputstate = 0;

check_status(naibrd_DSW_GetSwitchState(cardIndex, module, chan, &switchstate));
check_status(naibrd_DSW_GetInputState(cardIndex, module, chan, &inputstate));

Comparing the commanded switch state against the sensed input state lets your application detect wiring faults or stuck contacts — if you command a channel closed but the input state remains open, the circuit path may be broken.

Read Voltage and Current

DSW modules provide real-time voltage and current measurements for each channel. The sample reads both instantaneous and averaged (RMS) values:

float64_t voltage = 0.0, RMSvoltage = 0.0;
float64_t current = 0.0, RMScurrent = 0.0;

check_status(naibrd_DSW_GetVoltage(cardIndex, module, chan, &voltage));
check_status(naibrd_DSW_GetCurrent(cardIndex, module, chan, &current));
check_status(naibrd_DSW_GetAvgVoltage(cardIndex, module, chan, &RMSvoltage));
check_status(naibrd_DSW_GetAvgCurrent(cardIndex, module, chan, &RMScurrent));
  • naibrd_DSW_GetVoltage() / naibrd_DSW_GetCurrent() — instantaneous readings.

  • naibrd_DSW_GetAvgVoltage() / naibrd_DSW_GetAvgCurrent() — hardware-averaged readings, useful for filtering noise on noisy signal lines.

Current values are returned in amps. The sample converts to milliamps for display (current * 1000).

Voltage LSB

To retrieve the voltage resolution (least significant bit) for the module, call naibrd_DSW_GetVoltageLSB(). This value tells you the smallest voltage step the hardware can distinguish and is useful when interpreting threshold granularity:

float64_t voltageLSB = 0.0;
check_status(naibrd_DSW_GetVoltageLSB(cardIndex, module, &voltageLSB));

Note that this is a module-level call (no channel parameter) because the LSB is determined by the hardware’s ADC resolution, which is the same for all channels on a given module.

Important

Common Errors

  • NAI_ERROR_NOT_SUPPORTED — the selected module slot does not contain a recognized DSW module. Verify the module type with naibrd_DSW_GetChannelCount() before calling DSW API functions.

  • Switch state has no effect — confirm that the channel is not configured as input-only. Some DSW modules support mixed I/O configurations. Consult your module’s manual for channel direction settings.

  • Voltage reads zero with switch closed — check that external power is applied to the channel’s input pins. DSW channels measure the voltage present on the circuit, not an internally generated signal.

Threshold Configuration

DSW modules provide four programmable voltage thresholds per channel that divide the input voltage range into distinct detection zones. This is the key capability that distinguishes DSW modules from standard discrete (DT) modules — instead of a single high/low comparison, you get multi-level signal classification.

Threshold Hierarchy

The four thresholds must be configured in ascending order to form a meaningful detection envelope:

  Max High  ----  Signals above this level trigger max-high status
      |
  Upper     ----  Signals above this level (but below Max High) are in the upper zone
      |
  Lower     ----  Signals below this level (but above Min Low) are in the lower zone
      |
  Min Low   ----  Signals below this level trigger min-low status

The thresholds create five voltage zones:

  • Below Min Low — the signal is critically low. The min-low status flag latches.

  • Between Min Low and Lower — the signal is in the low zone but not critically low.

  • Between Lower and Upper — the signal is in the mid-range zone. The mid-range status flag reflects this.

  • Between Upper and Max High — the signal is in the high zone but not critically high.

  • Above Max High — the signal is critically high. The max-high status flag latches.

This hierarchy is useful for applications like power rail monitoring, where you need to distinguish between nominal operation (mid-range), warning levels (approaching limits), and fault conditions (beyond limits). It is also valuable in test equipment scenarios where you need to verify that a signal falls within a specific voltage window.

The hardware also tracks transitions — when the signal crosses from below the lower threshold to above the upper threshold (Lo-Hi transition) or vice versa (Hi-Lo transition). These transition flags let you detect edge events without continuous polling.

Set Min Low Threshold

To set the minimum low threshold on a channel, call naibrd_DSW_SetThreshold() with the NAI_DSW_THRESH_MIN_LO threshold type. Signals that fall below this voltage trigger the min-low status flag:

float64_t threshold = 1.0;  /* volts */
check_status(naibrd_DSW_SetThreshold(cardIndex, module, chan,
               NAI_DSW_THRESH_MIN_LO, threshold));

Set Lower Threshold

To set the lower threshold, use NAI_DSW_THRESH_LOWER. This defines the lower boundary of the mid-range zone. Signals between Min Low and Lower are in the low zone:

float64_t threshold = 3.0;  /* volts */
check_status(naibrd_DSW_SetThreshold(cardIndex, module, chan,
               NAI_DSW_THRESH_LOWER, threshold));

Set Upper Threshold

To set the upper threshold, use NAI_DSW_THRESH_UPPER. This defines the upper boundary of the mid-range zone. Signals between Lower and Upper are in mid-range:

float64_t threshold = 8.0;  /* volts */
check_status(naibrd_DSW_SetThreshold(cardIndex, module, chan,
               NAI_DSW_THRESH_UPPER, threshold));

Set Max High Threshold

To set the maximum high threshold, use NAI_DSW_THRESH_MAX_HI. Signals that exceed this voltage trigger the max-high status flag:

float64_t threshold = 12.0;  /* volts */
check_status(naibrd_DSW_SetThreshold(cardIndex, module, chan,
               NAI_DSW_THRESH_MAX_HI, threshold));

Read Current Thresholds

To read back the current threshold settings for a channel, call naibrd_DSW_GetThreshold() with each threshold type:

float64_t minlo = 0.0, lower = 0.0, upper = 0.0, maxhi = 0.0;

check_status(naibrd_DSW_GetThreshold(cardIndex, module, chan,
               NAI_DSW_THRESH_MIN_LO, &minlo));
check_status(naibrd_DSW_GetThreshold(cardIndex, module, chan,
               NAI_DSW_THRESH_LOWER, &lower));
check_status(naibrd_DSW_GetThreshold(cardIndex, module, chan,
               NAI_DSW_THRESH_UPPER, &upper));
check_status(naibrd_DSW_GetThreshold(cardIndex, module, chan,
               NAI_DSW_THRESH_MAX_HI, &maxhi));

Shared Threshold Helper

All four threshold commands in the sample use a single shared function, Configure_DSW_Threshold(), which accepts the threshold type as a parameter. This pattern avoids code duplication — each menu handler is a thin wrapper:

nai_status_t Configure_DSW_Threshold(int32_t cardIndex, int32_t module,
   int32_t chan, nai_dsw_thresh_type_t thresholdtype, int8_t* thresholdtext)
{
   float64_t threshold = 0.0;

   /* Parse the user's voltage input */
   threshold = atof((const char *)inputBuffer);

   /* Apply the threshold to the hardware */
   check_status(naibrd_DSW_SetThreshold(cardIndex, module, chan,
                  thresholdtype, threshold));
}

In your own code you would call naibrd_DSW_SetThreshold() directly with the appropriate nai_dsw_thresh_type_t enum value. The four threshold types are:

  • NAI_DSW_THRESH_MIN_LO — minimum low threshold

  • NAI_DSW_THRESH_LOWER — lower threshold

  • NAI_DSW_THRESH_UPPER — upper threshold

  • NAI_DSW_THRESH_MAX_HI — maximum high threshold

Important

Common Errors

  • Thresholds configured out of order — while the API will accept any voltage value for any threshold, the detection zones only make sense when Min Low < Lower < Upper < Max High. If thresholds overlap or are inverted, status flags may behave unexpectedly.

  • Threshold has no effect — the threshold voltage must be within the module’s measurable input range. Consult your module’s manual for the supported voltage range.

  • LSB granularity — threshold values are quantized to the module’s voltage LSB. Call naibrd_DSW_GetVoltageLSB() to determine the resolution. A threshold of 3.001V on a module with 0.01V LSB will be rounded to 3.00V.

Status and Diagnostics

DSW modules provide several status flags per channel that report threshold crossings, signal transitions, built-in test results, and overcurrent conditions. The sample reads all available latched status flags and displays them in a summary table.

Reading Status Flags

To read a status flag in your own application, call naibrd_DSW_GetStatus() with the desired status type. The sample reads all seven latched status types:

nai_status_bit_t status;

/* Threshold status */
check_status(naibrd_DSW_GetStatus(cardIndex, module, chan,
               NAI_DSW_STATUS_MIN_LO_LATCHED, &status));
check_status(naibrd_DSW_GetStatus(cardIndex, module, chan,
               NAI_DSW_STATUS_MID_RANGE_LATCHED, &status));
check_status(naibrd_DSW_GetStatus(cardIndex, module, chan,
               NAI_DSW_STATUS_MAX_HI_LATCHED, &status));

/* Transition status */
check_status(naibrd_DSW_GetStatus(cardIndex, module, chan,
               NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, &status));
check_status(naibrd_DSW_GetStatus(cardIndex, module, chan,
               NAI_DSW_STATUS_HI_LO_TRANS_LATCHED, &status));

/* Diagnostic status */
check_status(naibrd_DSW_GetStatus(cardIndex, module, chan,
               NAI_DSW_STATUS_BIT_LATCHED, &status));
check_status(naibrd_DSW_GetStatus(cardIndex, module, chan,
               NAI_DSW_STATUS_OVERCURRENT_LATCHED, &status));

Each status flag returns a nai_status_bit_t value: 1 if the condition has been detected (latched), 0 if not.

Status Flag Reference

The following table describes each status type and what it indicates:

Status Type What It Indicates

NAI_DSW_STATUS_MIN_LO_LATCHED

The channel voltage dropped below the Min Low threshold since the last status clear. Indicates an under-voltage fault condition.

NAI_DSW_STATUS_MID_RANGE_LATCHED

The channel voltage was within the mid-range zone (between Lower and Upper thresholds). Indicates normal operating condition.

NAI_DSW_STATUS_MAX_HI_LATCHED

The channel voltage exceeded the Max High threshold since the last status clear. Indicates an over-voltage fault condition.

NAI_DSW_STATUS_LO_HI_TRANS_LATCHED

A low-to-high transition occurred — the signal crossed from below the lower threshold to above the upper threshold. Useful for detecting switch closure or rising-edge events.

NAI_DSW_STATUS_HI_LO_TRANS_LATCHED

A high-to-low transition occurred — the signal crossed from above the upper threshold to below the lower threshold. Useful for detecting switch opening or falling-edge events.

NAI_DSW_STATUS_BIT_LATCHED

The built-in test detected a fault on this channel. Run a BIT operation to get details.

NAI_DSW_STATUS_OVERCURRENT_LATCHED

The channel current exceeded the hardware’s overcurrent limit. This is a hardware protection feature — check for short circuits or excessive load on the output.

Latched vs. Real-Time Status

The sample reads the _LATCHED variants of each status type. Latched status flags remain set once the condition occurs, even if the condition clears, until your application explicitly clears them. This ensures you never miss a transient event.

The DSW API also provides real-time (non-latched) status types (NAI_DSW_STATUS_BIT, NAI_DSW_STATUS_OVERCURRENT, NAI_DSW_STATUS_MAX_HI, NAI_DSW_STATUS_MIN_LO, NAI_DSW_STATUS_MID_RANGE, NAI_DSW_STATUS_LO_HI_TRANS, NAI_DSW_STATUS_HI_LO_TRANS). Real-time flags reflect the current instantaneous state and are useful for continuous monitoring loops.

Clearing Status

To clear a latched status flag, call naibrd_DSW_ClearStatus() with the same status type. This resets the latch so it can capture the next event:

check_status(naibrd_DSW_ClearStatus(cardIndex, module, chan,
               NAI_DSW_STATUS_MAX_HI_LATCHED));

Clear status flags after reading them to ensure you detect subsequent events. If you do not clear a latched flag, it remains set indefinitely and you will not be able to distinguish a new event from the original one.

Interrupt-Driven Status Monitoring

For applications that cannot afford to poll status registers continuously, DSW modules support interrupt-driven notification for all status types. When a threshold crossing or transition occurs, the hardware can generate an interrupt that your application handles asynchronously.

See the DSW Interrupt Basic sample application guide for a complete walkthrough of configuring DSW interrupts, including interrupt steering, edge vs. level mode, and handler registration.

Important

Common Errors

  • Status flag always reads 1 — you are reading a latched flag that was set by a previous event and never cleared. Call naibrd_DSW_ClearStatus() to reset it.

  • Transition flags never trigger — verify that the Lower and Upper thresholds are configured. Transitions are detected relative to these two thresholds, not Min Low and Max High.

  • BIT status set unexpectedly — BIT failures can indicate a hardware fault or that the channel is not properly connected. Check cabling and consult the module manual for BIT failure codes.

  • Overcurrent flag set at startup — some modules report overcurrent during power-on initialization. Clear the status after initial configuration is complete.

Troubleshooting Reference

Note
This section summarizes errors covered in the preceding sections and adds general troubleshooting guidance. Consult your module’s manual for hardware-specific diagnostics and voltage range specifications.
Error / Symptom Possible Causes Suggested Resolution

Module not recognized as DSW

Wrong module slot selected; module is a standard DT rather than DSW type.

Verify the module type with naibrd_DSW_GetChannelCount(). Check the board’s module map against your slot selection.

No board found at startup

Board not powered; incorrect interface or IP address in configuration file.

Verify physical connections and power. Delete the configuration file to force the interactive board menu.

Connection timeout

Network misconfiguration; firewall blocking traffic; wrong bus settings for PCI/PCIe.

Confirm IP addresses, subnet masks, and firewall rules. For PCI, verify the board is enumerated by the OS.

Switch state has no effect

Channel configured as input-only; external circuit not connected.

Verify channel direction settings in the module manual. Check external wiring.

Voltage reads zero

No external signal applied; channel not connected; wrong channel number.

Apply a known voltage to the channel input pins and verify the channel index.

Thresholds appear to have no effect

Threshold values outside the module’s measurable range; thresholds configured out of order.

Ensure Min Low < Lower < Upper < Max High and all values are within the module’s input range.

Status flags always latched

Status not cleared after reading; previous event set the latch.

Call naibrd_DSW_ClearStatus() after reading each latched status flag.

Transition flags never trigger

Lower and Upper thresholds not configured; signal does not cross both thresholds.

Set the Lower and Upper thresholds to bracket the expected signal transition range.

Overcurrent at startup

Normal behavior during power-on initialization on some modules.

Clear overcurrent status after completing initial channel configuration.

BIT failure on a channel

Hardware fault; channel not properly terminated; cabling issue.

Check physical connections. Consult the module manual for BIT failure code interpretation.

Full Source

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

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

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

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

/* Function prototypes */
int32_t Run_DSW_BasicOps(int32_t cardIndex, int32_t module, int32_t ModuleID);
static void Cfg_DSW_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);

static void Display_DSW_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID);
static nai_status_t Display_DSW_Status(int32_t paramCount, int32_t* p_params);

static nai_status_t Configure_DSW_SwitchState(int32_t paramCount, int32_t* p_params);
nai_status_t Configure_DSW_MinLoThreshold(int32_t paramCount, int32_t* p_params);
nai_status_t Configure_DSW_LowThreshold(int32_t paramCount, int32_t* p_params);
nai_status_t Configure_DSW_UpperThreshold(int32_t paramCount, int32_t* p_params);
nai_status_t Configure_DSW_MaxHiThreshold(int32_t paramCount, int32_t* p_params);
nai_status_t Configure_DSW_Threshold(int32_t cardIndex, int32_t module, int32_t chan, nai_dsw_thresh_type_t thresholdtype, int8_t* thresholdtext);

static const int32_t DEF_DSW_CHANNEL       = 1;

/****** Command Table *******/
enum dsw_basicops_commands
{
   DSW_BASICOP_CMD_SWITCHSTATE,
   DSW_BASICOP_CMD_THRESHOLD_MIN_LO,
   DSW_BASICOP_CMD_THRESHOLD_LOWER,
   DSW_BASICOP_CMD_THRESHOLD_UPPER,
   DSW_BASICOP_CMD_THRESHOLD_MAX_HI,
   DSW_BASICOP_CMD_STATUS,
   DSW_BASICOP_CMD_COUNT
};

/****** Command Tables *******/
naiapp_cmdtbl_params_t DSW_BasicOpMenuCmds[] = {
   {"Switch",  "DSW Set Switch State",       DSW_BASICOP_CMD_SWITCHSTATE,       Configure_DSW_SwitchState},
   {"ML",      "DSW Set Min Low Threshold",  DSW_BASICOP_CMD_THRESHOLD_MIN_LO,  Configure_DSW_MinLoThreshold},
   {"L",       "DSW Set Lower Threshold",    DSW_BASICOP_CMD_THRESHOLD_LOWER,   Configure_DSW_LowThreshold},
   {"U",       "DSW Set Upper Threshold",    DSW_BASICOP_CMD_THRESHOLD_UPPER,   Configure_DSW_UpperThreshold},
   {"MH",      "DSW Set Max High Threshold", DSW_BASICOP_CMD_THRESHOLD_UPPER,   Configure_DSW_MaxHiThreshold},
   {"STAT",    "DSW Display Status",         DSW_BASICOP_CMD_STATUS,            Display_DSW_Status},
};

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

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

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

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

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

   return 0;
}

/**************************************************************************************************************/
/**
<summary>
Run_DSW_BasicOps prompts the user for the card, module and channel to use for the application and calls
Cfg_DSW_Channel if the card, module, channel is valid for as a discrete switch module.
</summary>
*/
/**************************************************************************************************************/
int32_t Run_DSW_BasicOps(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
   int32_t MaxChannel;

   MaxChannel = naibrd_DSW_GetChannelCount(ModuleID);

   if (MaxChannel == 0)
   {
      printf(" *** Module selection not recognized as DSW module. ***\n\n");
   }
   else
   {
      Cfg_DSW_Channel(cardIndex, module, ModuleID, MaxChannel);
   }
   return cardIndex;
}

/**************************************************************************************************************/
/**
<summary>
Cfg_DSW_Channel handles calling the Display_DSW_ChannelCfg routine to display the discrete channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
static void Cfg_DSW_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel)
{
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   bool_t bCmdFound = FALSE;
   int32_t chan, defaultchan = 1;
   int32_t cmd;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   naiapp_AppParameters_t  dsw_params;
   p_naiapp_AppParameters_t dsw_basicops_params = &dsw_params;
   dsw_basicops_params->cardIndex = cardIndex;
   dsw_basicops_params->module = module;
   dsw_basicops_params->modId = ModuleID;
   while (bContinue)
   {
      printf("    \r\n\r\n");
      printf("Channel selection \r\n");
      printf("================= \r\n");
      defaultchan = DEF_DSW_CHANNEL;
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &chan);
      dsw_basicops_params->channel = chan;

      naiapp_utils_LoadParamMenuCommands(DSW_BASICOP_CMD_COUNT, DSW_BasicOpMenuCmds);
      while (bContinue)
      {
         Display_DSW_ChannelCfg(cardIndex, module, chan, ModuleID);
         naiapp_display_ParamMenuCommands((int8_t *)"DSW Basic Operation Menu");
         printf("\nType DSW command or %c to return : ", 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)
               {
                  switch (cmd)
                  {
                  case DSW_BASICOP_CMD_SWITCHSTATE:
                  case DSW_BASICOP_CMD_THRESHOLD_MIN_LO:
                  case DSW_BASICOP_CMD_THRESHOLD_LOWER:
                  case DSW_BASICOP_CMD_THRESHOLD_UPPER:
                  case DSW_BASICOP_CMD_THRESHOLD_MAX_HI:
                  case DSW_BASICOP_CMD_STATUS:
                     DSW_BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)dsw_basicops_params);
                     break;
                  default:
                     printf("Invalid command entered\n");
                     break;
                  }
               }
               else
                  printf("Invalid command entered\n");
            }
         }
         else
            bContinue = FALSE;
      }
   }
}

/**************************************************************************************************************/
/**
<summary>
Display_DSW_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for basic operation.
</summary>
*/
/**************************************************************************************************************/
static void Display_DSW_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID)
{
   nai_dsw_state_t switchstate = 0;
   nai_dsw_state_t inputstate = 0;
   float64_t voltageLSB = 0.0;
   float64_t minlo= 0.0, lower = 0.0, upper = 0.0, maxhi = 0.0;
   float64_t voltage = 0.0, RMSvoltage = 0.0, current = 0.0, RMScurrent = 0.0;
   uint32_t ModuleVer;
   uint32_t ModuleRev;
   uint32_t ModInfo_Special;
   naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
   check_status(naibrd_DSW_GetSwitchState(cardIndex, module, chan, &switchstate));
   check_status(naibrd_DSW_GetInputState(cardIndex, module, chan, &inputstate));
   check_status(naibrd_DSW_GetThreshold(cardIndex, module, chan, NAI_DSW_THRESH_MIN_LO, &minlo));
   check_status(naibrd_DSW_GetThreshold(cardIndex, module, chan, NAI_DSW_THRESH_LOWER, &lower));
   check_status(naibrd_DSW_GetThreshold(cardIndex, module, chan, NAI_DSW_THRESH_UPPER, &upper));
   check_status(naibrd_DSW_GetThreshold(cardIndex, module, chan, NAI_DSW_THRESH_MAX_HI, &maxhi));

   check_status(naibrd_DSW_GetVoltageLSB(cardIndex, module, &voltageLSB));

   /*read channel voltage and current*/
   check_status(naibrd_DSW_GetVoltage(cardIndex, module, chan, &voltage));
   check_status(naibrd_DSW_GetCurrent(cardIndex, module, chan, &current));
   check_status(naibrd_DSW_GetAvgVoltage(cardIndex, module, chan, &RMSvoltage));
   check_status(naibrd_DSW_GetAvgCurrent(cardIndex, module, chan, &RMScurrent));

   printf("\n === Channel %d ===\n\n", chan);
   printf(" Switch   Input    ==== Thresholds ( LSB: %1.3fV ) =====     \n", voltageLSB);
   printf(" State    State    MinLow     Lower     Upper    Max Hi      \n");
   printf(" ------   -----    -------   -------   -------   -------     \n");

   switch (switchstate)
   {
      case NAI_DSW_STATE_LO:
      printf(" Open ");
      break;
      case NAI_DSW_STATE_HI:
      printf("Closed");
      break;
      /* undefined value read back */
      default:
      printf(" UNK  ");
      break;
   }

   printf("    %3i     ", inputstate);
   printf("%+8.3f  %+8.3f  %+8.3f  %+8.3f    ", minlo, lower, upper, maxhi);

   printf("\n\n\n  =====Meas.======    ======RMS=======");
   printf("\n  V         mA        V          mA ");
   printf("\n  ------    ------    ------    ------");

   printf("\n%+8.3f  ", voltage);
   printf("%+8.3f  ", current*1000);      /*display in mA units*/
   printf("%+8.3f  ", RMSvoltage);
   printf("%+8.3f  ", RMScurrent*1000);   /*display in mA units*/
}

/**************************************************************************************************************/
/**
<summary>
Display_DSW_Status illustrate the methods to call in the naibrd library to retrieve the status states.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Display_DSW_Status(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dsw_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dsw_params->cardIndex;
   int32_t module = p_dsw_params->module;
   int32_t chan = p_dsw_params->channel;

   nai_status_bit_t status;
   /* Available status:
         NAI_DSW_STATUS_BIT,
         NAI_DSW_STATUS_OVERCURRENT,
         NAI_DSW_STATUS_MAX_HI,
         NAI_DSW_STATUS_MIN_LO,
         NAI_DSW_STATUS_MID_RANGE,
         NAI_DSW_STATUS_LO_HI_TRANS,
         NAI_DSW_STATUS_HI_LO_TRANS,
   */
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
   printf("\n");
   printf("  ----------------- Status ----------------------------\n");
   printf("  MinLo   MidRng  MaxHi  Low-Hi   Hi-Lo    BIT     OC\n");
   printf(" ------- -------- ------ ------- -------- ------ ------\n");

   check_status(naibrd_DSW_GetStatus(cardIndex, module, chan, NAI_DSW_STATUS_MIN_LO_LATCHED, &status));
   printf("  %3i   ", status);

   check_status(naibrd_DSW_GetStatus(cardIndex, module, chan, NAI_DSW_STATUS_MID_RANGE_LATCHED, &status));
   printf("  %3i   ", status);

   check_status(naibrd_DSW_GetStatus(cardIndex, module, chan, NAI_DSW_STATUS_MAX_HI_LATCHED, &status));
   printf("  %3i   ", status);

   check_status(naibrd_DSW_GetStatus(cardIndex, module, chan, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, &status));
   printf("  %3i   ", status);

   check_status(naibrd_DSW_GetStatus(cardIndex, module, chan, NAI_DSW_STATUS_HI_LO_TRANS_LATCHED, &status));
   printf("  %3i   ", status);

   check_status(naibrd_DSW_GetStatus(cardIndex, module, chan, NAI_DSW_STATUS_BIT_LATCHED, &status));
   printf("  %3i   ", status);

   check_status(naibrd_DSW_GetStatus(cardIndex, module, chan, NAI_DSW_STATUS_OVERCURRENT_LATCHED, &status));
   printf("  %3i   ", status);

   printf("\n\n");

   return NAI_ERROR_UNKNOWN;
}

/**************************************************************************************************************/
/**
<summary>
Configure_DSW_SwitchState handles the user request to change the switch state for the selected
channel and calls the method in the naibrd library to set the state.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DSW_SwitchState(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t bUpdateOutput = FALSE;
   nai_dsw_state_t switchstate = 0;
   p_naiapp_AppParameters_t p_dsw_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dsw_params->cardIndex;
   int32_t module = p_dsw_params->module;
   int32_t chan = p_dsw_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   /* Set the switch state (open or closed).
   */
   printf("\n Type the desired switch state, Open or Closed (i.e. NO-COM Contact closure)\n ");
   printf(" Enter Open or Closed: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         switch (toupper(inputBuffer[0]))
         {
         case 'O':
            switchstate = 0;
            bUpdateOutput = TRUE;
            break;
         case 'C':
            switchstate=  1;
            bUpdateOutput = TRUE;
            break;
         default:
            printf("ERROR: Invalid switch state selection\n");
            break;
         }
      }
   }
   if (!bQuit)
   {
      if (bUpdateOutput)
         check_status(naibrd_DSW_SetSwitchState(cardIndex, module, chan, switchstate));
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_DSW_MinLoThreshold calls the Configure_DSW_Threshold() routine for Min Low Threshold configuration.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_DSW_MinLoThreshold(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dsw_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dsw_params->cardIndex;
   int32_t module = p_dsw_params->module;
   int32_t chan = p_dsw_params->channel;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   return Configure_DSW_Threshold(cardIndex, module, chan, NAI_DSW_THRESH_MIN_LO, (int8_t *)"Min Low");
}

/**************************************************************************************************************/
/**
<summary>
Configure_DSW_LowThreshold calls the Configure_DSW_Threshold() routine for Lower Threshold configuration.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_DSW_LowThreshold(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dsw_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dsw_params->cardIndex;
   int32_t module = p_dsw_params->module;
   int32_t chan = p_dsw_params->channel;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   return Configure_DSW_Threshold(cardIndex, module, chan, NAI_DSW_THRESH_LOWER, (int8_t *)"Lower");
}

/**************************************************************************************************************/
/**
<summary>
Configure_DSW_UpperThreshold calls the Configure_DSW_Threshold() routine for Upper Threshold configuration.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_DSW_UpperThreshold(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dsw_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dsw_params->cardIndex;
   int32_t module = p_dsw_params->module;
   int32_t chan = p_dsw_params->channel;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   return Configure_DSW_Threshold(cardIndex, module, chan, NAI_DSW_THRESH_UPPER, (int8_t *)"Upper");
}

/**************************************************************************************************************/
/**
<summary>
Configure_DSW_MaxHiThreshold calls the Configure_DSW_Threshold() routine for Max High Threshold configuration.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_DSW_MaxHiThreshold(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dsw_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dsw_params->cardIndex;
   int32_t module = p_dsw_params->module;
   int32_t chan = p_dsw_params->channel;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
   return Configure_DSW_Threshold(cardIndex, module, chan, NAI_DSW_THRESH_MAX_HI, (int8_t *)"Max High");
}

/**************************************************************************************************************/
/**
<summary>
Configure_DSW_Threshold handles the user request to configure the selected threshold configuration and
channel and calls the method in the naibrd library to set the threshold voltage.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_DSW_Threshold(int32_t cardIndex, int32_t module, int32_t chan, nai_dsw_thresh_type_t thresholdtype, int8_t* thresholdtext)
{
   bool_t bQuit = FALSE;
   float64_t threshold= 0.0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nEnter the desired %s threshold voltage : ", thresholdtext);
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         threshold = atof((const char *)inputBuffer);
         check_status(naibrd_DSW_SetThreshold(cardIndex, module, chan, thresholdtype, threshold));
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

Help Bot

X