RLY Interrupt Ethernet
Edit this on GitLab
RLY Interrupt Ethernet
Explanation
/**************************************************************************************************************/
/**
<summary>
The RLY_Interrupt_Ethernet program demonstrates how to perform an interrupt when a single channel receives
a message. The purpose of this program is to demonstrate the method calls in the naibrd library for performing
the interrupt. More information on this process can be found in the naibrd SSK Quick Guide(Interrupts) file.
</summary>
*/
/**************************************************************************************************************/
/************************/
/* Include Declarations */
/************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/* Common Module Specific Sample Program include files */
#include "nai_rly_int.h"
#include "nai_rly_cfg.h"
/* Common Sample Program include files */
#include "include/naiapp_interrupt.h"
#include "include/naiapp_interrupt_ether.h"
#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"
#include "nai_rly_int_ether.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
/* Module Specific NAI Board Library files */
#include "functions/naibrd_dsw.h"
#include "maps/nai_map_rly.h"
/*********************************************/
/* Application Name and Revision Declaration */
/*********************************************/
/*
static const int8_t *App_Name = "RLY Interrupt Ethernet";
static const int8_t *App_Rev = "1.0";
*/
static const int8_t *CONFIG_FILE = (int8_t *)"default_RLY_Interrupt_Ethernet.txt";
static uint8_t DEF_RX_RESPONSE_IPv4_ADDR[] = { 192,168,1,100 };
/********************************/
/* Internal Function Prototypes */
/********************************/
static bool_t Run_RLY_Interrupt_Basic_Ethernet();
/**************************************************************************************************************/
/***** Main Routine *****/
/**************************************************************************************************************/
/**************************************************************************************************************/
/**
<summary>
The main routine assists in gaining access to the board.
The following routines from the nai_sys_cfg.c file are
called to assist with accessing and configuring the board.
- ConfigDevice
- DisplayDeviceCfg
- GetBoardSNModCfg
- CheckModule
</summary>
*/
/*****************************************************************************/
#if defined (__VXWORKS__)
int32_t RLY_Interrupt_Basic_Ethernet(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
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);
inputRLYConfig.cardIndex = cardIndex;
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Query the user for the module number */
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
inputRLYConfig.module = module;
if (stop != TRUE)
{
inputRLYConfig.modid = naibrd_GetModuleID(cardIndex, module);
if ((inputRLYConfig.modid != 0))
{
Run_RLY_Interrupt_Basic_Ethernet();
}
}
}
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>
This function is broken into the following major steps. These steps correspond with the steps provided
in the naibrd SSK Quick Guide(Interrupts) file.
2a. Ethernet Interrupt Handling - Setup IDR to handle interrupt
API CALLS - naibrd_Ether_SetIDRConfig, naibrd_Ether_StartIDR,naibrd_Ether_ClearIDRConfig
3. Enable Module Interrupts- Configures module to interrupter when channel receives DSW message.
API CALLS - naibrd_DSW_SetInterruptEdgeLevel, naibrd_DSW_SetIntVector, naibrd_DSW_SetInterruptSteering, naibrd_DSW_SetIntEnable
4. Not applicable to DSW module
5. Show Interrupt Handling - The IDR server will listen on the boards ports for IDRs indicating an interrupt.
These results will be decoded and displayed to the user.
6. Re-arming Interrupts - Clear the status register to allow interrupts to occur again. This is done by writing to the status register.
In this program, the write command is included in the IDR.
API CALLS - nai_ether_BeginWriteMessage, nai_ether_WriteMessageData, nai_ether_FinishMessage
7. Clear Module Configurations
API CALLS - naibrd_DSW_SetRxEnable, naibrd_DSW_ClearStatus
8. Clear Board Configurations
API CALLS - naibrd_Ether_StopIDR, naibrd_Ether_ClearIDRConfig
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_RLY_Interrupt_Basic_Ethernet()
{
bool_t bQuit = FALSE;
bool_t bGen4DSWIDRCommands;
inputRLYConfig.maxChannel = naibrd_RLY_GetChannelCount(inputRLYConfig.modid);
inputRLYConfig.minChannel = 1;
initializeRLYConfigurations(0, 0, 0, 0, 0, 0);
initializeInterruptConfigurations(FALSE, FALSE, FALSE, 0, NAIBRD_INT_STEERING_ON_BOARD_1, -1, 0);
initializeIDRConfigurations(0, 0, DEF_RX_RESPONSE_PROTOCOL, DEF_RX_RESPONSE_PORT, DEF_RX_RESPONSE_IPv4_ADDR, DEF_RX_RESPONSE_IPv4_LENGTH, COMMANDS, 0, 0, DEF_ETHERNET_CAN_IDR_ID);
/* check if DSW module supports GEN 4 Ethernet */
bGen4DSWIDRCommands = SupportsGen4Ether(inputRLYConfig.cardIndex);
if (!bGen4DSWIDRCommands) {
printf("RLY Ethernet Interrupt Support Prior to Generation 4 Ethernet commands currently not supported\n");
bQuit = TRUE;
}
if (!bQuit) {
bQuit = naiapp_query_ChannelNumber(inputRLYConfig.maxChannel, inputRLYConfig.minChannel, &inputRLYConfig.channel);
}
if (!bQuit) {
bQuit = QueryIDRConfigInformation(&inputIDRConfig);
}
if (!bQuit) {
bQuit = QueryUserForOnboardOffboardInterrupts(&inputInterruptConfig.bProcessOnboardInterrupts);
}
if (!bQuit)
{
bQuit = QueryUserForEtherIDRMsgDisplay(&bDisplayEtherUPR);
}
if (!bQuit)
{
/****2. Setup IDR to Handle Interrupt (also contains step 6) ****/
if (inputInterruptConfig.bProcessOnboardInterrupts == TRUE)
{
inputIDRConfig.cardIndex = inputRLYConfig.cardIndex;
inputIDRConfig.boardInterface = NAI_INTF_ONBOARD;
inputInterruptConfig.steering = NAIBRD_INT_STEERING_ON_BOARD_1;
}
else /*OffBoard Interrupt*/
{
inputIDRConfig.cardIndex = 0;
inputIDRConfig.boardInterface = NAI_INTF_PCI;
inputInterruptConfig.steering = NAIBRD_INT_STEERING_CPCI_APP;
}
setupIDRConfiguration_RLY(inputRLYConfig, &inputIDRConfig, bGen4DSWIDRCommands);
check_status(naibrd_Ether_StartIDR(inputIDRConfig.cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID));
/****3. configure module To Interrupt****/
configureRLYToInterruptOnRx(inputInterruptConfig, inputRLYConfig);
enableRLYInterrupts(inputRLYConfig, TRUE);
/****5. Show Interrupt Handling****/
rlyEtherIntFunc = HandleRLYEtherInterrupt;
bQuit = runIDRServer(inputIDRConfig);
/*****7. Clear Module Configurations*****/
enableRLYInterrupts(inputRLYConfig, FALSE);
/*****8. Clear Board Configurations *****/
check_status(naibrd_Ether_StopIDR(inputIDRConfig.cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID));
check_status(naibrd_Ether_ClearIDRConfig(inputIDRConfig.cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID));
}
return bQuit;
}
About.txt - Explanation of RLY_Interrupt_Ethernet Program
This application demonstrates how to set up and handle interrupts on a relay module using Ethernet communication with North Atlantic Industries (NAI) function modules. The code primarily uses the naibrd library to perform various operations related to setting up and processing interrupts.
Structure Overview
-
Include Declarations:
-
Standard libraries (
stdio.h
,stdlib.h
, etc.) -
Module-specific headers (
nai_rly_int.h
,nai_rly_cfg.h
, etc.) -
NAI common sample program headers
-
Board-specific headers (
nai.h
,naibrd.h
) -
Specific module library files (
naibrd_dsw.h
,nai_map_rly.h
)
-
-
Constants and Prototypes:
-
CONFIG_FILE
: Default configuration file for Ethernet settings. -
DEF_RX_RESPONSE_IPv4_ADDR
: Default IPv4 address for receiving responses. -
Function prototype for
Run_RLY_Interrupt_Basic_Ethernet()
, which is the main workhorse of the application.
-
-
Main Routine:
-
The
main
function initializes the program, retrieves the board and module configuration, and sets up the interrupt handling. It prompts the user for necessary inputs and enters into an operation loop until the user decides to quit.
-
Detailed Walkthrough
Main Function
The main function initializes necessary variables and enters into a loop where it performs the following actions:
-
Configuration and Setup:
-
Calls
naiapp_RunBoardMenu()
to load the default configuration fromCONFIG_FILE
. -
Queries the user for the card index and module number, ensuring valid entries.
-
Module Configuration:
-
Retrieves the module ID (modid) using
naibrd_GetModuleID()
to confirm the correct setup. -
Run Relay Interrupt Handling:
-
Calls
Run_RLY_Interrupt_Basic_Ethernet()
to perform the core functionality of setting up and handling Ethernet-based relay interrupts.
After the operation completes or if the user desires to quit, the function ensures all open cards are closed using naiapp_access_CloseAllOpenCards()
.
Run_RLY_Interrupt_Basic_Ethernet Function
This function encapsulates the main operational logic for handling relay interrupts over an Ethernet connection:
-
Initialize Configurations:
-
Sets up relay and interrupt configurations using helper functions like
initializeRLYConfigurations()
andinitializeInterruptConfigurations()
.
-
-
Check Module Support:
-
Checks if the module supports the operations using
SupportsGen4Ether()
and reports if it does not.
-
-
User Queries:
-
Asks the user for necessary configuration details such as the channel number, IDR configuration details, and whether to display Ethernet UPR messages.
-
-
Setup IDR for Interrupt Handling:
-
Configures IDR setup specific to whether the interrupts are onboard or off-board using
setupIDRConfiguration_RLY()
. -
Calls
naibrd_Ether_StartIDR()
to start the IDR configuration.
-
-
Enable Module Interrupts:
-
Configures the module to handle interrupts on receiving messages using the relay-specific functions like
configureRLYToInterruptOnRx()
andenableRLYInterrupts()
.
-
-
Show and Handle Interrupts:
-
Sets up the function
HandleRLYEtherInterrupt
to handle actual interrupts and starts an IDR server usingrunIDRServer()
to listen and respond to interrupts.
-
-
Clear Configurations:
-
After interrupt handling is complete, clears both module and board configurations ensuring a clean state using functions such as
check_status(naibrd_Ether_StopIDR())
andcheck_status(naibrd_Ether_ClearIDRConfig())
.
-
Conclusion
This sample application provides a comprehensive guide for setting up and handling Ethernet-based relay interrupts using NAI function modules. The detailed steps and API calls demonstrated here are aimed at helping users understand and implement similar functionality in their specific applications.
/**************************************************************************************************************/
/**
<summary>
The RLY_Interrupt_Ethernet program demonstrates how to perform an interrupt when a single channel receives
a message. The purpose of this program is to demonstrate the method calls in the naibrd library for performing
the interrupt. More information on this process can be found in the naibrd SSK Quick Guide(Interrupts) file.
</summary>
*/
/**************************************************************************************************************/
/************************/
/* Include Declarations */
/************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/*Common Module Specific Sample Program include files*/
#include "nai_rly_int.h"
#include "nai_rly_cfg.h"
/* Common Sample Program include files */
#include "include/naiapp_interrupt.h"
#include "include/naiapp_interrupt_ether.h"
#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"
#include "nai_rly_int_ether.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
/* Module Specific NAI Board Library files */
#include "functions/naibrd_dsw.h"
#include "maps/nai_map_rly.h"
/*********************************************/
/* Application Name and Revision Declaration */
/*********************************************/
/*
static const int8_t *App_Name = "RLY Interrupt Ethernet";
static const int8_t *App_Rev = "1.0";
*/
static const int8_t *CONFIG_FILE = (int8_t *)"default_RLY_Interrupt_Ethernet.txt";
static uint8_t DEF_RX_RESPONSE_IPv4_ADDR[] = { 192,168,1,100 };
/********************************/
/* Internal Function Prototypes */
/********************************/
static bool_t Run_RLY_Interrupt_Basic_Ethernet();
/**************************************************************************************************************/
/***** Main Routine *****/
/**************************************************************************************************************/
/**************************************************************************************************************/
/**
<summary>
The main routine assists in gaining access to the board.
The following routines from the nai_sys_cfg.c file are
called to assist with accessing and configuring the board.
- ConfigDevice
- DisplayDeviceCfg
- GetBoardSNModCfg
- CheckModule
</summary>
*/
/*****************************************************************************/
#if defined (__VXWORKS__)
int32_t RLY_Interrupt_Basic_Ethernet(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
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);
inputRLYConfig.cardIndex = cardIndex;
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Query the user for the module number */
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
inputRLYConfig.module = module;
if (stop != TRUE)
{
inputRLYConfig.modid = naibrd_GetModuleID(cardIndex, module);
if ((inputRLYConfig.modid != 0))
{
Run_RLY_Interrupt_Basic_Ethernet();
}
}
}
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>
This function is broken into the following major steps. These steps correspond with the steps provided
in the naibrd SSK Quick Guide(Interrupts) file.
2a. Ethernet Interrupt Handling - Setup IDR to handle interrupt
API CALLS - naibrd_Ether_SetIDRConfig, naibrd_Ether_StartIDR,naibrd_Ether_ClearIDRConfig
3. Enable Module Interrupts- Configures module to interrupter when channel receives DSW message.
API CALLS - naibrd_DSW_SetInterruptEdgeLevel, naibrd_DSW_SetIntVector, naibrd_DSW_SetInterruptSteering, naibrd_DSW_SetIntEnable
4. Not applicable to DSW module
5. Show Interrupt Handling - The IDR server will listen on the boards ports for IDRs indicating an interrupt.
These results will be decoded and displayed to the user.
6. Re-arming Interrupts - Clear the status register to allow interrupts to occur again. This is done by writing to the status register.
In this program, the write command is included in the IDR.
API CALLS - nai_ether_BeginWriteMessage, nai_ether_WriteMessageData, nai_ether_FinishMessage
7. Clear Module Configurations
API CALLS - naibrd_DSW_SetRxEnable, naibrd_DSW_ClearStatus
8. Clear Board Configurations
API CALLS - naibrd_Ether_StopIDR, naibrd_Ether_ClearIDRConfig
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_RLY_Interrupt_Basic_Ethernet()
{
bool_t bQuit = FALSE;
bool_t bGen4DSWIDRCommands;
inputRLYConfig.maxChannel = naibrd_RLY_GetChannelCount(inputRLYConfig.modid);
inputRLYConfig.minChannel = 1;
initializeRLYConfigurations(0, 0, 0, 0, 0, 0);
initializeInterruptConfigurations(FALSE, FALSE, FALSE, 0, NAIBRD_INT_STEERING_ON_BOARD_1, -1, 0);
initializeIDRConfigurations(0, 0, DEF_RX_RESPONSE_PROTOCOL, DEF_RX_RESPONSE_PORT, DEF_RX_RESPONSE_IPv4_ADDR, DEF_RX_RESPONSE_IPv4_LENGTH, COMMANDS, 0, 0, DEF_ETHERNET_CAN_IDR_ID);
/* check if DSW module supports GEN 4 Ethernet */
bGen4DSWIDRCommands = SupportsGen4Ether(inputRLYConfig.cardIndex);
if (!bGen4DSWIDRCommands) {
printf("RLY Ethernet Interrupt Support Prior to Generation 4 Ethernet commands currently not supported\n");
bQuit = TRUE;
}
if (!bQuit) {
bQuit = naiapp_query_ChannelNumber(inputRLYConfig.maxChannel, inputRLYConfig.minChannel, &inputRLYConfig.channel);
}
if (!bQuit) {
bQuit = QueryIDRConfigInformation(&inputIDRConfig);
}
if (!bQuit) {
bQuit = QueryUserForOnboardOffboardInterrupts(&inputInterruptConfig.bProcessOnboardInterrupts);
}
if (!bQuit)
{
bQuit = QueryUserForEtherIDRMsgDisplay(&bDisplayEtherUPR);
}
if (!bQuit)
{
/****2. Setup IDR to Handle Interrupt (also contains step 6) ****/
if (inputInterruptConfig.bProcessOnboardInterrupts == TRUE)
{
inputIDRConfig.cardIndex = inputRLYConfig.cardIndex;
inputIDRConfig.boardInterface = NAI_INTF_ONBOARD;
inputInterruptConfig.steering = NAIBRD_INT_STEERING_ON_BOARD_1;
}
else /*OffBoard Interrupt*/
{
inputIDRConfig.cardIndex = 0;
inputIDRConfig.boardInterface = NAI_INTF_PCI;
inputInterruptConfig.steering = NAIBRD_INT_STEERING_CPCI_APP;
}
setupIDRConfiguration_RLY(inputRLYConfig, &inputIDRConfig, bGen4DSWIDRCommands);
check_status(naibrd_Ether_StartIDR(inputIDRConfig.cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID));
/****3. configure module To Interrupt****/
configureRLYToInterruptOnRx(inputInterruptConfig, inputRLYConfig);
enableRLYInterrupts(inputRLYConfig, TRUE);
/****5. Show Interrupt Handling****/
rlyEtherIntFunc = HandleRLYEtherInterrupt;
bQuit = runIDRServer(inputIDRConfig);
/*****7. Clear Module Configurations*****/
enableRLYInterrupts(inputRLYConfig, FALSE);
/*****8. Clear Board Configurations *****/
check_status(naibrd_Ether_StopIDR(inputIDRConfig.cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID));
check_status(naibrd_Ether_ClearIDRConfig(inputIDRConfig.cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID));
}
return bQuit;
}