nai rly int
Edit this on GitLab
nai rly int
Explanation
About the Sample Application Code for NAI SSK and Embedded Function Modules
This document provides an explanation of the provided sample application code written in C for interacting with North Atlantic Industries (NAI) embedded function modules using their Software Support Kit (SSK). The main focus of this code is to configure and handle relay (RLY) module interrupts.
Included Libraries and Definitions
The code begins by including necessary standard libraries and NAI-specific libraries:
- Standard Libraries:
- stdlib.h
- stdio.h
- NAI Common Libraries:
- naiapp_interrupt.h
- Handles interrupt-related functionalities.
- naiapp_interrupt_ether.h
- Related to Ethernet-based interrupts.
- naiapp_boardaccess_query.h
- Utilities for querying board access.
- naiapp_boardaccess_access.h
- Functions for accessing the board.
- naiapp_boardaccess_display.h
- Functions for displaying board information.
- naiapp_boardaccess_utils.h
- Utilities for board access.
- DSW-specific Libraries:
- nai_rly_int.h
- Relay interrupts specifics.
- nai_rly_cfg.h
- Relay configuration specifics.
- naibrd Libraries:
- nai.h
, naibrd.h
, naibrd_ether.h
- General NAI board-related functions.
- naibrd_rly.h
- Relay functions.
- nai_map_rly.h
- Mapping for relay functions.
The code defines several key functions to configure, enable, handle, and display relay interrupts.
Functions and Their Explanations
1. configureRLYToInterruptOnRx
This function configures a relay module to generate an interrupt when a message is received on any of its channels:
- Parameters:
- InterruptConfig inputInterruptConfig
: Configuration for the interrupt.
- RlyConfig inputRLYConfig
: Configuration for the relay module.
- Logic:
- Disables relay interrupts initially.
- Configures the interrupt vector.
- Clears any existing status and sets up edge/level mode for each channel.
- Sets the interrupt steering (target for the interrupt).
2. enableRLYInterrupts
This function enables or disables interrupts for a range of relay channels:
- Parameters:
- RlyConfig inputRLYConfig
: Configuration for the relay module.
- bool_t enable
: Boolean indicating whether to enable or disable interrupts.
- Logic:
- Iterates through the specified range of channels and sets the interrupt enable flag accordingly.
3. basic_ISR_RLY
This function serves as the basic interrupt service routine (ISR) for handling relay interrupts:
- Parameters:
- uint32_t param
(for VxWorks) or void *param, uint32_t vector
(for other OS).
- Logic:
- Sets a flag indicating an interrupt occurrence.
- Clears the onboard interrupt (platform-specific).
4. checkForRLYInterrupt
This function prompts the user to check if a relay interrupt has occurred:
- Parameters:
- RlyConfig inputRLYConfig
: Configuration for the relay module.
- Logic:
- Continually prompts the user to check for interrupts.
- If an interrupt occurred, it displays the vector and status.
- Prompts the user to clear the status register if desired.
5. GetRLYLatchStatusTriggerMode
This function prompts the user to specify the trigger mode for the interrupt status (edge or level triggered):
- Parameters:
- int32_t* interrupt_Edge_Trigger
: Pointer to store the user-specified trigger mode.
- Logic:
- Prompts the user for input and validates it.
6. handleRLYInterrupt
This function handles the logic after a relay interrupt occurs:
- Parameters:
- uint32_t nVector
: Vector of the interrupt.
- Logic:
- Displays an interrupt occurred message.
- Prompts the user to clear the interrupt.
- Retrieves and clears the raw status for each channel.
- Prints detailed interrupt information.
7. promptUserToClearInterrupt_RLY
This utility function prompts the user to clear a relay interrupt: - Logic: - Displays a message and waits for user response to clear the interrupt.
8. DisplayMessage_RLYInterrupt
This function displays specific messages related to relay interrupts:
- Parameters:
- int32_t msgId
: Message identifier.
- Logic:
- Displays messages based on the provided message ID.
9. printInterruptInformation_RLY
This function prints detailed information about an interrupt:
- Parameters:
- int32_t interruptID
: ID or vector of the interrupt.
- uint32_t status
: The status of the interrupt.
- bool_t isEther
: Flag indicating if the interrupt is Ethernet-based.
- Logic:
- Prints the interrupt ID, status, and other relevant information.
This code provides a comprehensive approach to configuring and handling relay module interrupts in a system using the NAI SSK. It includes user prompts, configuration setups, and detailed interrupt handling mechanisms to ensure robust interaction with the relay modules.
#include <stdlib.h>
#include <stdio.h>
/* Common Sample Program include files */
#include "include/naiapp_interrupt.h"
#include "include/naiapp_interrupt_ether.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"
/* Common DSW Sample Program include files */
#include "nai_rly_int.h"
#include "nai_rly_cfg.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "naibrd_ether.h"
#include "functions/naibrd_rly.h"
#include "maps/nai_map_rly.h"
/**************************************************************************************************************/
/**
<summary>
This function configures an interrupt to occur when a message is received on any of the relay channels.
</summary>
*/
/**************************************************************************************************************/
void configureRLYToInterruptOnRx(InterruptConfig inputInterruptConfig, RlyConfig inputRLYConfig)
{
int32_t cardIndex = inputRLYConfig.cardIndex;
int32_t module = inputRLYConfig.module;
int32_t vector = NAI_RLY_INTERRUPT_VECTOR;
int32_t interrupt_Edge_Trigger = inputInterruptConfig.interrupt_Edge_Trigger;
int32_t steering = inputInterruptConfig.steering;
int32_t chan = 1;
enableRLYInterrupts(inputRLYConfig, FALSE);
/* Setup the Interrupt Vector - map to the same vector */
check_status(naibrd_RLY_SetGroupInterruptVector(cardIndex, module, 1, NAI_RLY_BIT_STATUS_LATCHED, vector));
for (chan = 1; chan <= inputRLYConfig.maxChannel; chan++)
{
/* Clear the Interrupt Status (Read the status and write back "1" to statuses which are set to clear the status) */
check_status(naibrd_RLY_ClearStatus(cardIndex, module, chan, NAI_RLY_BIT_STATUS_LATCHED));
/* Setup the Latched Status Mode */
check_status(naibrd_RLY_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_RLY_BIT_STATUS_LATCHED, (nai_rly_interrupt_t)interrupt_Edge_Trigger));
}
check_status(naibrd_RLY_SetGroupInterruptSteering(cardIndex, module, 1, NAI_RLY_BIT_STATUS_LATCHED, steering));
}
/**************************************************************************************************************/
/**
<summary>
Enables the channels within the (minChannel,maxChannel) range to interrupt
if enable is true and disables them otherwise.
</summary>
*/
/**************************************************************************************************************/
void enableRLYInterrupts(RlyConfig inputRLYConfig, bool_t enable) {
int32_t channel;
for (channel = inputRLYConfig.minChannel; channel <= inputRLYConfig.maxChannel; channel++)
{
check_status(naibrd_RLY_SetInterruptEnable(inputRLYConfig.cardIndex, inputRLYConfig.module, channel, NAI_RLY_BIT_STATUS_LATCHED, enable));
}
}
/**************************************************************************************************************/
/**
<summary>
The routine is called to handle a interrupt. This function alerts checkForInterrupt that an interrupt has occurred.
In vxWorks you must clear the Interrupt on the board within the ISR.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
void basic_ISR_RLY(uint32_t param)
#else
void basic_ISR_RLY(void *param, uint32_t vector)
#endif
{
interruptOccured = TRUE;
#if defined (__VXWORKS__)
interruptVector = nai_Onboard_GetInterruptVector();
nai_Onboard_ClearInterrupt();
#elif defined (WIN32)
UNREFERENCED_PARAMETER(param);
interruptVector = vector;
#else
interruptVector = vector;
#endif
}
/**************************************************************************************************************/
/**
<summary>
Prompts user to check if an interrupt has occurred. MyIsr() should be installed if using this function.
</summary>
*/
/**************************************************************************************************************/
bool_t checkForRLYInterrupt(RlyConfig inputRLYConfig)
{
bool_t bQuit;
int32_t cardIndex;
int32_t module;
int32_t channel;
uint32_t rawstatus = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
cardIndex = inputRLYConfig.cardIndex;
module = inputRLYConfig.module;
channel = inputRLYConfig.channel;
bQuit = FALSE;
interruptOccured = FALSE;
while (!bQuit) {
printf("\nPress enter to check if RLY interrupt Occurred (press Q to quit):");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit) {
if (interruptOccured) {
check_status(naibrd_RLY_GetGroupRaw(cardIndex, module, 1, NAI_RLY_RAW_GROUP_BIT_LATCHED_STATUS, &rawstatus));
printf("\nVector = %#x \n", interruptVector);
printf("Status = %#x \n", rawstatus);
interruptOccured = FALSE;
}
else {
printf("\nNo Interrupt Occurred");
}
printf("\n\nWould you like to clear the status register? (default:N):");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (inputBuffer[0] == 'y' || inputBuffer[0] == 'Y')
{
for (channel = 1; channel <= inputRLYConfig.maxChannel; channel++)
{
/* Clear the Interrupt Status (Read the status and write back "1" to statuses which are set to clear the status) */
check_status(naibrd_RLY_ClearStatus(cardIndex, module, channel, NAI_RLY_BIT_STATUS_LATCHED));
}
}
}
}
return bQuit;
}
/**************************************************************************************************************/
/**
<summary>
GetDSWLatchStatusTriggerMode handles prompting the user for the trigger mode for the latched status register
(Edge Triggered or Level Triggered).
</summary>
*/
/**************************************************************************************************************/
bool_t GetRLYLatchStatusTriggerMode(int32_t* interrupt_Edge_Trigger)
{
bool_t bQuit;
uint32_t temp;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nEnter Latched Status Trigger Mode (Edge=0, Level=1) (Default=0): ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
temp = (int32_t)atol((const char*)inputBuffer);
if (temp == 0 || temp == 1)
{
*interrupt_Edge_Trigger = temp;
}
else
{
printf("ERROR: Invalid Interrupt Trigger Mode.\n");
}
}
else
*interrupt_Edge_Trigger = 0;
}
return(bQuit);
}
/**************************************************************************************************************/
/**
<summary>
This routine takes in the vector of the RLY RX interrupt that has just occurred. A
</summary>
*/
/**************************************************************************************************************/
void handleRLYInterrupt(uint32_t nVector) {
uint32_t rawstatus = 0;
int32_t chan = 1;
int32_t maxChannel;
nai_rly_status_type_t rly_status_type;
rly_status_type = NAI_RLY_BIT_STATUS_LATCHED;
maxChannel = inputRLYConfig.maxChannel;
printf("\n\nInterrupt Occurred \n\n");
if (inputInterruptConfig.bPromptForInterruptClear)
{
promptUserToClearInterrupt_RLY();
}
check_status(naibrd_RLY_GetGroupRaw(inputRLYConfig.cardIndex, inputRLYConfig.module, 1, rly_status_type, &rawstatus));
for (chan = 1; chan <= maxChannel; chan++)
{
check_status(naibrd_RLY_ClearStatus(inputRLYConfig.cardIndex, inputRLYConfig.module, chan, rly_status_type));
}
printInterruptInformation_RLY(nVector, rawstatus, FALSE);
}
void promptUserToClearInterrupt_RLY()
{
/* Prompt the user to clear the interrupt received */
SetUserRequestClearInt(FALSE);
printf("\n");
DisplayMessage_RLYInterrupt(MSG_USER_CLEAR_RLY_INT);
/* Wait for the user to respond */
while (!GetUserRequestClearInt())
{
nai_msDelay(10);
}
}
/**************************************************************************************************************/
/**
<summary>
DisplayMessage_DSWInterrupt handles displaying the messages associated with the msgId passed in.
</summary>
*/
/**************************************************************************************************************/
void DisplayMessage_RLYInterrupt(int32_t msgId)
{
switch (msgId)
{
case (int32_t)MSG_BANNER_RLY_INT:
{
printf("\n********************************************************************************");
printf("\n****** RLY INTERRUPT ******");
printf("\nAn interrupt will occur when the RLY Module receives a BIT FAult status ");
printf("\n********************************************************************************");
}
break;
case (int32_t)MSG_USER_TRIGGER_RLY_INT:
{
printf("\nPress \"Q\" to quit the application.\nPlease trigger RLY BIT Fault status interrupt (Recv Msg):");
}
break;
case (int32_t)MSG_USER_CLEAR_RLY_INT:
{
printf("Press \"C\" to clear interrupts... ");
}
break;
}
}
/**************************************************************************************************************/
/**
<summary>
Function will print the Data provided for each channel that has been set in the status register.
It will also print the status and idr id or vector.
</summary>
*/
/**************************************************************************************************************/
void printInterruptInformation_RLY(int32_t interruptID, uint32_t status, bool_t isEther)
{
printf("Interrupt Information\n");
printf("-----------------------------------\n");
if (isEther)
printf("\nIDR ID = %#x \n", interruptID);
else
printf("\nVector = %#x \n", interruptID);
printf("Status = %#x \n", status);
printf("\nFrames Rx = %d", frameCount);
printf("\n-----------------------------------\n");
}