DSW BasicOps
Edit this on GitLab
DSW BasicOps
Explanation
About the Sample Application Code
This C application code is designed to interact with North Atlantic Industries (NAI) embedded function modules, specifically discrete switch (DSW) modules. The application configures, controls, and reads the state of switch modules using the NAI libraries.
Definitions and Key Components
-
Includes and Definitions:
-
The code begins by including standard libraries and specific NAI libraries required for accessing and manipulating the DSW modules.
-
CONFIG_FILE
is a pointer to the default configuration file used for this operation. -
Function prototypes for various configuration and display functionalities are declared.
-
-
Enumerations and Constants:
-
Enumeration
dsw_basicops_commands
defines commands for basic operations on DSW modules, such as switching states and setting thresholds. -
DEF_DSW_CHANNEL
sets the default channel used in various operations.
-
-
Command Table:
-
DSW_BasicOpMenuCmds
is an array of command structures mapping text commands to their corresponding functionalities.
-
Application Entry Point and Main Loop
The main entry point is either DSW_BasicOps()
or main()
, depending on the operating system. The application flow is as follows:
-
Initial Setup:
-
The application starts by running the board menu using
naiapp_RunBoardMenu
. -
If the configuration file runs successfully, the application enters the main loop.
-
-
User Queries:
-
During each iteration, the application queries the user for the card index and module number.
-
If a valid module is selected,
Run_DSW_BasicOps
is invoked.
-
-
Loop Continuation:
-
The user can choose to quit or restart the application after each iteration.
-
Core Functionalities
1. Run_DSW_BasicOps
This function validates and configures the selected channel if it is a DSW module. It calls Cfg_DSW_Channel
to handle configurations and display tasks.
2. Cfg_DSW_Channel
This function displays channel configuration using Display_DSW_ChannelCfg
and processes user menu commands. It continues to prompt the user until they choose to exit.
3. Display_DSW_ChannelCfg
This function retrieves and prints the configuration state of the selected channel, including switch state, input state, thresholds, and measured voltages and currents.
4. Display_DSW_Status
This function retrieves and prints the status of the selected channel using the NAI library functions.
5. Configuration Functions:
- Configure_DSW_SwitchState
: Sets the switch state (open or closed) based on user input.
- Configure_DSW_Threshold
: Sets various threshold types based on user input. Specific functions like Configure_DSW_MinLoThreshold
, Configure_DSW_LowThreshold
, etc., act as wrappers to call this function.
Error Handling and Utilities
Throughout the code, check_status
is used to verify function calls to the NAI library, which ensures proper error handling and robustness.
Example Output
The application provides an interactive menu for the user to configure and check the status of DSW modules. It allows for setting switch states and thresholds and displays real-time measurements of voltage and current.
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");
// Example output might include values for switch state, input, thresholds, voltage, and current.
This application serves as a comprehensive tool for managing DSW modules, allowing users to interactively configure and monitor their embedded switch modules using the NAI libraries.
#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;
}