RLY BasicOps
Edit this on GitLab
RLY BasicOps Sample Application (SSK 2.x)
Overview
The RLY BasicOps sample application demonstrates how to configure and operate relay (RLY) modules using the NAI Software Support Kit (SSK 2.x). It covers the core relay operations you will need in your own application: opening and closing individual relays, setting relay state words for bulk operations, reading relay position and BIT status, configuring interrupt enables and trigger modes, and toggling BIT status display.
This sample supports RY1 and RY2 relay modules. It also works with earlier-generation relay modules (KN, KL) with a reduced command set. Each menu command maps directly to one or more naibrd_RLY_*() API calls that you can lift into your own code.
For the SSK 1.x version, see RLY BasicOps (SSK 1.x).
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with a relay module installed (RY1 or RY2).
-
SSK 2.x installed on your development host.
-
The sample applications built. Refer to the SSK 2.x Software Development Guide for platform-specific build instructions.
How to Run
Launch the rly_basic_ops executable from your build output directory. On startup the application looks for a configuration file (default_RLY_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, you select a channel and a command menu lets you exercise each relay 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 RLY. |
The main() function follows a standard SSK 2.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_RLY_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_GetModuleName()so downstream code can adapt to the specific relay variant installed.
#if defined (__VXWORKS__)
int32_t RLY_BasicOps(void)
#else
int32_t main(void)
#endif
{
bool_t stop = NAI_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) == NAI_TRUE)
{
while (stop != NAI_TRUE)
{
/* Query the user for the card index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Query the user for the module number */
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
if ((moduleID != 0))
{
Run_RLY_BasicOps(cardIndex, module, moduleID);
}
}
}
naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
naiif_printf("\r\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
Note the SSK 2.x differences from SSK 1.x in this startup sequence:
-
This sample uses the legacy
__VXWORKS__preprocessor guard. Most SSK 2.x samples useNAIBSP_CONFIG_SOFTWARE_OS_VXWORKS. -
The module identifier is retrieved with
naibrd_GetModuleName()(SSK 1.x usesnaibrd_GetModuleID()). -
Boolean constants are
NAI_TRUE/NAI_FALSE(SSK 1.x usesTRUE/FALSE). -
Console output uses
naiif_printf()from the platform abstraction layer (SSK 1.x usesprintf()directly).
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Entry Point
On VxWorks the entry point is RLY_BasicOps(); on all other platforms it is main(). The preprocessor guard __VXWORKS__ selects between them. After board connection and module selection, the application calls Run_RLY_BasicOps() which validates the module and delegates to Cfg_RLY_Channel() for the interactive command loop.
Command Loop
Cfg_RLY_Channel() prompts the user for a channel number, displays the current relay status, and presents a menu of relay commands. The menu is dynamically constructed based on the module type — RY1 and RY2 modules get additional commands for clearing BIT status and setting interrupt trigger modes. Commands are defined in RLY_BasicOpMenuCmds[] and RLY_GEN5_MenuCmds[].
| Command | Description |
|---|---|
|
Display help notes with register references for the relay module. |
|
Open the relay on the selected channel (COM to N.C.). |
|
Close the relay on the selected channel (COM to N.O.). |
|
Set the relay state word to control all channels simultaneously. |
|
Enable or disable BIT interrupt for the selected channel. |
|
Toggle the BIT status display on or off. |
|
Clear (reset) the latched BIT status for the selected channel. |
|
Select interrupt trigger type: Edge or Level. |
Displaying Relay Status
The Display_RLY_Status() function reads and displays the relay setting, relay position, and BIT status for all channels. The relay position readback indicates whether the physical relay contacts match the commanded state. BIT status is displayed both as real-time and latched values.
static bool_t Display_RLY_Status(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID)
{
nai_status_bit_t BITstatus = 0;
uint32_t BITstatusWord = 0;
nai_status_bit_t BITstatuslatched = 0;
naibrd_rly_state_t relaysetting;
naibrd_rly_state_t relayposition;
int32_t MaxChannel;
MaxChannel = naibrd_RLY_GetChannelCount(ModuleID);
if (bShowBIT)
check_status(naibrd_RLY_GetGroupRaw(cardIndex, module, 1,
(naibrd_rly_raw_group_type_t)NAIBRD_RLY_RAW_GROUP_BIT_LATCHED_STATUS, &BITstatusWord));
for (i = 0; i < MaxChannel; i++)
{
check_status(naibrd_RLY_GetRelayState(cardIndex, module, displaychan, &relaysetting));
check_status(naibrd_RLY_GetRelayPosition(cardIndex, module, displaychan, &relayposition));
if (bShowBIT)
check_status(naibrd_RLY_GetChanMappedStatus(cardIndex, module, displaychan,
NAIBRD_RLY_CHAN_MAPPED_STATUS_BIT_REALTIME, &BITstatus));
}
return NAI_FALSE;
}
Key API calls used:
-
naibrd_RLY_GetChannelCount()— returns the number of relay channels for the module. -
naibrd_RLY_GetRelayState()— reads the commanded relay state (open or closed). -
naibrd_RLY_GetRelayPosition()— reads the physical relay position readback. -
naibrd_RLY_GetGroupRaw()— reads a raw group register (e.g., latched BIT status word). -
naibrd_RLY_GetChanMappedStatus()— reads a per-channel status bit (real-time or latched).
Setting Relay State
Individual relays are opened or closed using naibrd_RLY_SetRelayState(). The Open and Close commands in the menu call this directly.
case RLY_BASICOP_CMD_OPEN:
check_status(naibrd_RLY_SetRelayState(cardIndex, module, chan, NAIBRD_RLY_STATE_OPEN));
break;
case RLY_BASICOP_CMD_CLOSE:
check_status(naibrd_RLY_SetRelayState(cardIndex, module, chan, NAIBRD_RLY_STATE_CLOSE));
break;
-
naibrd_RLY_SetRelayState()— sets the relay state for a channel.NAIBRD_RLY_STATE_OPENconnects COM to N.C.;NAIBRD_RLY_STATE_CLOSEconnects COM to N.O.
Setting Relay State Word
The Configure_RLY_StateWord() function allows you to set all relay channels simultaneously using a bitmapped state word. Each bit position corresponds to a channel (LSB = channel 1).
static nai_status_t Configure_RLY_StateWord(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = NAI_FALSE;
uint32_t stateword = 0;
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ad_params->cardIndex;
int32_t module = p_ad_params->module;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
naiif_printf("\r\nEnter the relay state word to set: Range [0 to 15)\r\n");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit && inputResponseCnt > 0)
{
stateword = (atoi((const char *)inputBuffer)) & 0xF;
check_status(naibrd_RLY_SetGroupRaw(cardIndex, module, 1,
(naibrd_rly_raw_group_type_t)NAIBRD_RLY_RAW_GROUP_RELAYSTATE, stateword));
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
-
naibrd_RLY_SetGroupRaw()— writes a raw value to a group register. Used here to set all relay states in one operation.
Configuring Interrupts
The application supports configuring BIT interrupt enable and trigger type for RY1/RY2 modules.
static nai_status_t Configure_RLY_Interrupt_Enable(int32_t paramCount, int32_t* p_params)
{
// Prompts for Enable or Disable
check_status(naibrd_RLY_SetChanMappedInterruptEnable(cardIndex, module, chan,
NAIBRD_RLY_CHAN_MAPPED_STATUS_BIT_LATCHED, enable));
return bQuit;
}
static nai_status_t Configure_RLY_Interrupt_Trigger(int32_t paramCount, int32_t* p_params)
{
// Prompts for Edge or Level trigger
check_status(naibrd_RLY_SetChanMappedInterruptTriggerType(cardIndex, module, chan,
NAIBRD_RLY_CHAN_MAPPED_STATUS_BIT_LATCHED, trigmode));
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
-
naibrd_RLY_SetChanMappedInterruptEnable()— enables or disables the BIT interrupt for a channel. -
naibrd_RLY_SetChanMappedInterruptTriggerType()— sets the interrupt trigger mode to edge (one-shot on transition) or level (continuous while active). -
naibrd_RLY_ClearChanMappedStatus()— clears the latched BIT status for a channel (used by theRcommand on RY1/RY2).
Troubleshooting Reference
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
Module not recognized as RLY |
The selected module slot does not contain a relay module. |
Verify the module type in the slot. See the RY1-RY2 Manual. |
Relay does not change state |
The module may be in a fault condition or the relay may be physically stuck. |
Check the BIT status for the channel. Verify wiring and relay health. |
BIT status shows Nogo |
The relay position readback does not match the commanded state. |
This may indicate relay wear or a wiring issue. Clear the latched status and re-test. |
State word has no effect |
The entered value may be outside the valid range for the number of channels. |
Ensure the state word value is within [0, 2^N - 1] where N is the number of relay channels. |
Interrupt commands not available |
The |
Earlier-generation modules (KN, KL) do not support these features. |
Latched status does not clear |
The underlying fault condition is still present. |
Resolve the fault condition first, then clear the latched status. |
Help shows different registers |
The help display adapts its register references based on module type (RY1/RY2 vs. KN/KL). |
This is expected behavior. Use the register references that match your module type. |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — rly_basic_ops.c (SSK 2.x)
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"
/* naibrd include files */
#include "nai_libs/naibrd/include/naibrd.h"
#include "nai_libs/naibrd/include/functions/naibrd_rly.h"
/* naiif include files */
#include "nai_libs/naiif/include/naiif_stdio.h"
/* Common Sample Program include files */
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_menu.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_query.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_access.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_display.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_utils.h"
static const int8_t *CONFIG_FILE = (const int8_t *)"default_RLY_BasicOp.txt";
#define K6_VER_4 0x3420u /* "4 " */
/* Function prototypes */
static void Run_RLY_BasicOps(int32_t cardIndex, int32_t module, uint32_t modid);
static void Cfg_RLY_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
static bool_t Display_RLY_Status(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID);
static nai_status_t Configure_RLY_StateWord(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_RLY_Interrupt_Enable(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_RLY_Interrupt_Trigger(int32_t paramCount, int32_t* p_params);
static nai_status_t DisplayHelp(int32_t paramCount, int32_t* p_params);
bool_t bShowBIT = NAI_TRUE;
static const int32_t DEF_RLY_CHANNEL = 1;
/****** Command Table *******/
enum rly_basicops_commands
{
RLY_BASICOP_CMD_HELP,
RLY_BASICOP_CMD_OPEN,
RLY_BASICOP_CMD_CLOSE,
RLY_BASICOP_CMD_SETWORD,
RLY_BASICOP_CMD_INTERRUPT_ENABLE,
RLY_BASICOP_CMD_TOGGLE,
RLY_BASICOP_CMD_CLEAR, /* RY1/RY2 only */
RLY_BASICOP_CMD_INTERRUPT_TRIG, /* RY1/RY2 only */
RLY_BASICOP_CMD_COUNT
};
/****** Command Tables *******/
naiapp_cmdtbl_params_t RLY_BasicOpMenuCmds[] = {
{"Help", "RLY Notes", RLY_BASICOP_CMD_HELP, DisplayHelp},
{"Open", "RLY Open Relay", RLY_BASICOP_CMD_OPEN, NULL},
{"CLOse", "RLY Close Relay", RLY_BASICOP_CMD_CLOSE, NULL},
{"Word", "RLY Set Word", RLY_BASICOP_CMD_SETWORD, Configure_RLY_StateWord},
{"ENable", "RLY Select Interrupt Enable", RLY_BASICOP_CMD_INTERRUPT_ENABLE, Configure_RLY_Interrupt_Enable},
{"Status", "RLY Toggle Status Display", RLY_BASICOP_CMD_TOGGLE, NULL}
};
naiapp_cmdtbl_params_t RLY_GEN5_MenuCmds[] = {
{"R", "RLY Reset BIT Status", RLY_BASICOP_CMD_CLEAR, NULL},
{"EDge", "RLY Select Interrupt Trig", RLY_BASICOP_CMD_INTERRUPT_TRIG, Configure_RLY_Interrupt_Trigger}
};
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t RLY_BasicOps(void)
#else
int32_t main(void)
#endif
{
bool_t stop = NAI_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) == NAI_TRUE)
{
while (stop != NAI_TRUE)
{
/* Query the user for the card index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Query the user for the module number */
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
if ((moduleID != 0))
{
Run_RLY_BasicOps(cardIndex, module, moduleID);
}
}
}
naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
naiif_printf("\r\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
static void Run_RLY_BasicOps(int32_t cardIndex, int32_t module, uint32_t modid)
{
int32_t MaxChannel;
MaxChannel = naibrd_RLY_GetChannelCount(modid);
if (MaxChannel == 0)
naiif_printf(" *** Module selection not recognized as RLY module. ***\r\n\r\n");
else
Cfg_RLY_Channel(cardIndex, module, modid, MaxChannel);
}
static void Cfg_RLY_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel)
{
bool_t bQuit = NAI_FALSE;
bool_t bContinue = NAI_TRUE;
bool_t bCmdFound = NAI_FALSE;
int32_t chan, defaultchan = 1;
int32_t cmd;
naiapp_cmdtbl_params_t menuCmds[RLY_BASICOP_CMD_COUNT];
int32_t menuCnt, totalMenuCnt;
int32_t i;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
naiapp_AppParameters_t rly_basicops_params;
p_naiapp_AppParameters_t rly_basicOps_params = &rly_basicops_params;
rly_basicOps_params->cardIndex = cardIndex;
rly_basicOps_params->module = module;
rly_basicOps_params->channel = 1;
rly_basicOps_params->maxChannels = naibrd_RLY_GetChannelCount(ModuleID);
rly_basicOps_params->modId = ModuleID;
rly_basicOps_params->displayHex = NAI_FALSE;
while (bContinue)
{
naiif_printf(" \r\n\r\n");
naiif_printf("Channel selection \r\n");
naiif_printf("================= \r\n");
defaultchan = DEF_RLY_CHANNEL;
bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &chan);
/* Update Menu Cmds based on Module ID */
totalMenuCnt = 0;
menuCnt = sizeof(RLY_BasicOpMenuCmds) / sizeof(naiapp_cmdtbl_params_t);
for (i = 0; i < menuCnt; i++)
menuCmds[totalMenuCnt++] = RLY_BasicOpMenuCmds[i];
if ((ModuleID == NAIBRD_MODULE_ID_RY1) || (ModuleID == NAIBRD_MODULE_ID_RY2))
{
/* Added menu for Gen 5 Relay modules */
menuCnt = sizeof(RLY_GEN5_MenuCmds) / sizeof(naiapp_cmdtbl_params_t);
for (i = 0; i < menuCnt; i++)
menuCmds[totalMenuCnt++] = RLY_GEN5_MenuCmds[i];
}
naiapp_utils_LoadParamMenuCommands(totalMenuCnt, menuCmds);
while (bContinue)
{
Display_RLY_Status(cardIndex, module, chan, ModuleID);
naiapp_display_ParamMenuCommands((int8_t *)"RLY Basic Operation Menu");
naiif_printf("\r\n Type RLY command or %c to quit : ", 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)
{
naiif_printf(" <%s>", menuCmds[cmd].cmdstr);
switch (cmd)
{
case RLY_BASICOP_CMD_OPEN:
check_status(naibrd_RLY_SetRelayState(cardIndex, module, chan, NAIBRD_RLY_STATE_OPEN));
break;
case RLY_BASICOP_CMD_CLOSE:
check_status(naibrd_RLY_SetRelayState(cardIndex, module, chan, NAIBRD_RLY_STATE_CLOSE));
break;
case RLY_BASICOP_CMD_CLEAR:
check_status(naibrd_RLY_ClearChanMappedStatus(cardIndex, module, chan, NAIBRD_RLY_CHAN_MAPPED_STATUS_BIT_LATCHED));
break;
case RLY_BASICOP_CMD_TOGGLE:
bShowBIT = (~bShowBIT) & 0x1;
break;
case RLY_BASICOP_CMD_SETWORD:
case RLY_BASICOP_CMD_HELP:
case RLY_BASICOP_CMD_INTERRUPT_ENABLE:
case RLY_BASICOP_CMD_INTERRUPT_TRIG:
RLY_BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)rly_basicOps_params);
break;
default:
naiif_printf("Invalid command entered\r\n");
break;
}
}
else
naiif_printf("Invalid command entered\r\n");
}
}
else
bContinue = NAI_FALSE;
}
}
}
static bool_t Display_RLY_Status(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID)
{
nai_status_bit_t BITstatus = 0;
uint32_t BITstatusWord = 0;
nai_status_bit_t BITstatuslatched = 0;
naibrd_rly_state_t relaysetting;
naibrd_rly_state_t relayposition;
int32_t MaxChannel;
uint8_t i = 0;
uint8_t displaychan = 0;
naiif_printf("\r\n\r\n");
naiif_printf("\r\n === Setting Channel %d ===\r\n\r\n", chan);
MaxChannel = naibrd_RLY_GetChannelCount(ModuleID);
if (bShowBIT)
{
naiif_printf("Chan Relay Setting Relay Position BIT Status Latched Status \r\n");
naiif_printf("---- ------------------- -------------------- ------------ ---------------- \r\n");
}
else
{
naiif_printf("Chan Relay Setting Relay Position \r\n");
naiif_printf("---- ------------------- -------------------- \r\n");
}
if (bShowBIT)
check_status(naibrd_RLY_GetGroupRaw(cardIndex, module, 1, (naibrd_rly_raw_group_type_t)NAIBRD_RLY_RAW_GROUP_BIT_LATCHED_STATUS, &BITstatusWord));
for (i = 0; i < MaxChannel; i++)
{
displaychan = i + 1;
naiif_printf(" %2d ", displaychan);
check_status(naibrd_RLY_GetRelayState(cardIndex, module, displaychan, &relaysetting));
if (relaysetting == 1)
{
naiif_printf(" Closed ");
}
else
naiif_printf(" Open ");
check_status(naibrd_RLY_GetRelayPosition(cardIndex, module, displaychan, &relayposition));
if (relayposition == 1)
naiif_printf(" Closed (COM - N.O.) ");
else
naiif_printf(" Open (COM - N.C.) ");
if (bShowBIT)
{
BITstatuslatched = (BITstatusWord >> (displaychan - 1)) & 0x1;
check_status(naibrd_RLY_GetChanMappedStatus(cardIndex, module, displaychan, NAIBRD_RLY_CHAN_MAPPED_STATUS_BIT_REALTIME, &BITstatus));
switch (BITstatus)
{
case 0:
naiif_printf(" Go ");
break;
case 1:
naiif_printf(" Nogo ");
break;
default:
naiif_printf(" Unknown ");
break;
}
naiif_printf(" ");
switch (BITstatuslatched)
{
case 0:
naiif_printf(" Go ");
break;
case 1:
naiif_printf(" Nogo ");
break;
default:
naiif_printf(" Unknown ");
break;
}
}
naiif_printf("\r\n");
}
return NAI_FALSE;
}
static nai_status_t Configure_RLY_StateWord(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = NAI_FALSE;
bool_t bUpdateOutput = NAI_FALSE;
uint32_t stateword = 0;
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ad_params->cardIndex;
int32_t module = p_ad_params->module;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
naiif_printf("\r\nEnter the relay state word to set: Range [0 to 15) \r\n Channel Bitmapped position, 1 energizes relay \r\n > ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
stateword = (atoi((const char *)inputBuffer)) & 0xF;
bUpdateOutput = NAI_TRUE;
}
}
if (!bQuit)
{
if (bUpdateOutput)
check_status(naibrd_RLY_SetGroupRaw(cardIndex, module, 1, (naibrd_rly_raw_group_type_t)NAIBRD_RLY_RAW_GROUP_RELAYSTATE, stateword));
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static nai_status_t Configure_RLY_Interrupt_Enable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = NAI_FALSE;
bool_t bUpdateOutput = NAI_FALSE;
bool_t enable = 0;
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ad_params->cardIndex;
int32_t module = p_ad_params->module;
int32_t chan = p_ad_params->channel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
naiif_printf("\r\nEnter the selection for interrupt enable: 'Enable' or 'Disable' \r\n > ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
switch (toupper(inputBuffer[0]))
{
case 'E':
naiif_printf(" <Enable>\r\n\r\n");
enable = 1;
break;
case 'D':
naiif_printf(" <Disable>\r\n\r\n");
enable = 0;
break;
}
bUpdateOutput = NAI_TRUE;
}
}
if (!bQuit)
{
if (bUpdateOutput)
check_status(naibrd_RLY_SetChanMappedInterruptEnable(cardIndex, module, chan, NAIBRD_RLY_CHAN_MAPPED_STATUS_BIT_LATCHED, enable));
}
return bQuit;
}
static nai_status_t Configure_RLY_Interrupt_Trigger(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = NAI_FALSE;
bool_t bUpdateOutput = NAI_FALSE;
naibrd_int_trigger_type_t trigmode = 0;
p_naiapp_AppParameters_t p_rly_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_rly_params->cardIndex;
int32_t module = p_rly_params->module;
int32_t chan = p_rly_params->channel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
naiif_printf("\r\nEnter the selection for interrupt triggering mode: 'Edge' or 'Level' \r\n > ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
switch (toupper(inputBuffer[0]))
{
case 'E':
naiif_printf(" <Edge>\r\n\r\n");
trigmode = 0;
break;
case 'L':
naiif_printf(" <Level>\r\n\r\n");
trigmode = 1;
break;
}
bUpdateOutput = NAI_TRUE;
}
}
if (!bQuit)
{
if (bUpdateOutput)
check_status(naibrd_RLY_SetChanMappedInterruptTriggerType(cardIndex, module, chan, NAIBRD_RLY_CHAN_MAPPED_STATUS_BIT_LATCHED, trigmode));
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static nai_status_t DisplayHelp(int32_t paramCount, int32_t* p_params)
{
uint32_t ModuleID;
p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ad_params->cardIndex;
int32_t module = p_ad_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
naibrd_GetModuleName(cardIndex, module, &ModuleID);
naiif_printf("\r\n\r\n\r\n");
naiif_printf(" ===================================================================\r\n");
naiif_printf(" Relay module has Form C relays, single pole double throw (SPDT) \r\n");
naiif_printf(" A BIT status indication shows a mismatch detected between \r\n");
naiif_printf(" the relay setting and the position readback. \r\n");
naiif_printf(" Latched status retains any transient BIT indications that may have occurred. \r\n\r\n");
if ((ModuleID == NAIBRD_MODULE_ID_RY1) || (ModuleID == NAIBRD_MODULE_ID_RY2))
{
naiif_printf(" SET_POSITION 0x1000 Set Relay position (1:N.C.- COM) LSB=Ch.1 \r\n");
naiif_printf(" READ_POSITION 0x1018 Read Relay position (1:N.C.- COM) LSB=Ch.1 \r\n");
naiif_printf(" INDUCE_BIT 0x1004 Force BIT fail (1:forced) LSB=Ch.1 \r\n");
naiif_printf(" RELAY TYPE 0x1008 Relay config (fixed) (1:Latching, 0:Nonlatching) \r\n");
naiif_printf(" INTERRUPT_SELECT_EDGE 0x080C Edge/Level interrupt (1:Level) LSB=Ch.1 \r\n");
naiif_printf(" INTERRUPT_ENABLE 0x0808 BIT Interrupt Enable (1:Enable) LSB=Ch.1 \r\n");
naiif_printf(" BIT_STATUS_LATCHED 0x0804 Latched BIT status (1:fault) LSB=Ch.1 \r\n");
naiif_printf(" BIT_STATUS_REALTIME 0x0800 Realtime BIT status (1:fault) LSB=Ch.1 \r\n");
}
else
{
naiif_printf(" NAI_REG_RLY_SET_POSITION 0x000 \r\n");
naiif_printf(" NAI_REG_RLY_READ_POSITION 0x002 \r\n");
naiif_printf(" NAI_REG_RLY_BIT_STATUS 0x0D0 Same as latched status on KN/KL\r\n");
naiif_printf(" NAI_REG_RLY_BIT_STATUS_LATCHED 0x0D0 \r\n");
naiif_printf(" NAI_REG_RLY_INDUCE_BIT 0x0D2 \r\n");
naiif_printf(" NAI_REG_RLY_BIT_INT_ENAB 0x0E8 \r\n");
naiif_printf(" NAI_REG_RLY_INT_VECTOR_BIT 0x3E0 \r\n");
}
return NAI_SUCCESS;
}