DSW BasicOps
Edit this on GitLab
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:
-
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. -
Query the user for a card index with
naiapp_query_CardIndex(). -
Query for a module slot with
naiapp_query_ModuleNumber(). -
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:
|
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:
-
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. -
Enter a loop that queries for card index and module slot.
-
Call
Run_DSW_BasicOps()to validate the module and enter the interactive command loop. -
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 bynaibrd_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) orNAI_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, ¤t));
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
|
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
|
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 |
|---|---|
|
The channel voltage dropped below the Min Low threshold since the last status clear. Indicates an under-voltage fault condition. |
|
The channel voltage was within the mid-range zone (between Lower and Upper thresholds). Indicates normal operating condition. |
|
The channel voltage exceeded the Max High threshold since the last status clear. Indicates an over-voltage fault condition. |
|
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. |
|
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. |
|
The built-in test detected a fault on this channel. Run a BIT operation to get details. |
|
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
|
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 |
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 |
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, ¤t));
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;
}