nai dsw int
Edit this on GitLab
nai dsw int
Explanation
About the Sample Application Code
This C application code from North Atlantic Industries (NAI) is designed to interface with their Single Slot Kits (SSK) to handle interrupts from embedded function modules. The code sets up, enables, and checks for interrupts from the Data Set-Word (DSW) channels. Here’s an explanation of the various sections and functions in the code:
Headers and Includes
#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"
/* Common DSW Sample Program include files */
#include "nai_dsw_int.h"
#include "nai_dsw_cfg.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "naibrd_ether.h"
#include "functions/naibrd_dsw.h"
#include "maps/nai_map_dsw.h"
#include <stdlib.h>
These are the necessary include files for the application. They bring in the definitions and declarations needed for interrupt handling, board access, and Data Set-Word (DSW) specific operations.
Function: configureDSWToInterrupt
void configureDSWToInterrupt(InterruptConfig inputInterruptConfig, DswConfig inputDSWConfig)
This function configures interrupts for when messages are received on any of the DSW channels. - It clears any existing interrupt statuses. - Sets up interrupt vectors for low-to-high and high-to-low transitions. - Loops over each channel to set edge-level interrupts and steering.
Function: enableDSWInterrupts
void enableDSWInterrupts(DswConfig inputDSWConfig, bool_t enable)
This function enables or disables interrupts for a range of channels specified in inputDSWConfig
.
- Iterates through channels and sets interrupt enabling based on the boolean parameter enable
.
Function: basic_ISR_DSW
void basic_ISR_DSW(void *param, uint32_t vector)
This is the basic Interrupt Service Routine (ISR) called when an interrupt occurs. - It flags that an interrupt has occurred. - On VxWorks systems, it clears the interrupt on the board.
Function: checkForDSWInterrupt
bool_t checkForDSWInterrupt(DswConfig inputDSWConfig)
This function prompts the user to check if an interrupt has occurred. - Indicates whether the interrupt has occurred and prints the relevant status. - Prompts whether to clear the status register if an interrupt is detected.
Function: GetDSWLatchStatusTriggerMode
bool_t GetDSWLatchStatusTriggerMode(int32_t* interrupt_Edge_Trigger)
Prompts the user for the trigger mode for the latched status register.
- Asks user to specify edge-triggered or level-triggered mode.
- Updates the interrupt_Edge_Trigger
based on the user input.
Function: handleDSWInterrupt
void handleDSWInterrupt(uint32_t nVector)
Handles the DSW RX interrupt that has occurred by logging the interrupt status. - Gets status, clears it, and prints interrupt information. - Prompts the user to clear the interrupt if configured to do so.
Function: promptUserToClearInterrupt_DSW
void promptUserToClearInterrupt_DSW()
Prompts the user to clear the received interrupt. - Waits for user interaction to clear the interrupt.
Function: DisplayMessage_DSWInterrupt
void DisplayMessage_DSWInterrupt(int32_t msgId)
Displays specific messages to the user related to the DSW interrupts. - Provides clear messaging for different interrupt stages (e.g., banner display, user prompt for triggering and clearing interrupts).
Function: printInterruptInformation_DSW
void printInterruptInformation_DSW(int32_t interruptID, uint32_t status, bool_t isEther)
Prints relevant information about the interrupt. - Displays the interrupt ID/vector, status, and frame count.
The code is well-structured to handle setting up, enabling, and managing interrupts for NAI DSW modules. Various utility functions and user prompts ensure interactive and clear interrupt handling.
/* 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"
/* Common DSW Sample Program include files */
#include "nai_dsw_int.h"
#include "nai_dsw_cfg.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "naibrd_ether.h"
#include "functions/naibrd_dsw.h"
#include "maps/nai_map_dsw.h"
#include <stdlib.h>
/**************************************************************************************************************/
/**
<summary>
This function configures an interrupt to occur when a message is received on any of the dsw channels.
</summary>
*/
/**************************************************************************************************************/
void configureDSWToInterrupt(InterruptConfig inputInterruptConfig, DswConfig inputDSWConfig)
{
int32_t cardIndex = inputDSWConfig.cardIndex;
int32_t module = inputDSWConfig.module;
int32_t interrupt_Edge_Trigger = inputInterruptConfig.interrupt_Edge_Trigger;
int32_t steering = inputInterruptConfig.steering;
uint32_t rawstatus = 0;
int32_t chan;
enableDSWInterrupts(inputDSWConfig, FALSE);
/* Clear the Interrupt Status (Read the status and write back "1" to statuses which are set to clear the status) */
check_status(naibrd_DSW_GetGroupStatusRaw(cardIndex, module, 1, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, &rawstatus));
check_status(naibrd_DSW_ClearGroupStatusRaw(cardIndex, module, 1, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, rawstatus));
check_status(naibrd_DSW_GetGroupStatusRaw(cardIndex, module, 1, NAI_DSW_STATUS_HI_LO_TRANS_LATCHED, &rawstatus));
check_status(naibrd_DSW_ClearGroupStatusRaw(cardIndex, module, 1, NAI_DSW_STATUS_HI_LO_TRANS_LATCHED, rawstatus));
/* Setup the Interrupt Vector - map to the same vector */
check_status(naibrd_DSW_SetGroupInterruptVector(cardIndex, module, 1, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, NAI_DSW_LOHI_INTERRUPT_VECTOR));
check_status(naibrd_DSW_SetGroupInterruptVector(cardIndex, module, 1, NAI_DSW_STATUS_HI_LO_TRANS_LATCHED, NAI_DSW_HILO_INTERRUPT_VECTOR));
/* Setup the Latched Status Mode */
for (chan = 1; chan <= inputDSWConfig.maxChannel; chan++)
{
check_status(naibrd_DSW_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, (nai_dsw_interrupt_t)interrupt_Edge_Trigger));
check_status(naibrd_DSW_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_DSW_STATUS_HI_LO_TRANS_LATCHED, (nai_dsw_interrupt_t)interrupt_Edge_Trigger));
}
check_status(naibrd_DSW_SetGroupInterruptSteering(cardIndex, module, 1, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, steering));
check_status(naibrd_DSW_SetGroupInterruptSteering(cardIndex, module, 1, NAI_DSW_STATUS_HI_LO_TRANS_LATCHED, steering));
}
/**************************************************************************************************************/
/**
<summary>
Enables the channels within the (minChannel,maxChannel) range to interrupt
if enable is true and disables them otherwise.
</summary>
*/
/**************************************************************************************************************/
void enableDSWInterrupts(DswConfig inputDSWConfig, bool_t enable) {
int32_t channel;
for (channel = inputDSWConfig.minChannel; channel <= inputDSWConfig.maxChannel; channel++)
{
check_status(naibrd_DSW_SetInterruptEnable(inputDSWConfig.cardIndex, inputDSWConfig.module, channel, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, enable));
check_status(naibrd_DSW_SetInterruptEnable(inputDSWConfig.cardIndex, inputDSWConfig.module, channel, NAI_DSW_STATUS_HI_LO_TRANS_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_DSW(uint32_t param)
#else
void basic_ISR_DSW(void *param, uint32_t vector)
#endif
{
#if defined (WIN32)
UNREFERENCED_PARAMETER(param);
#endif
interruptOccured = TRUE;
#if defined (__VXWORKS__)
interruptVector = nai_Onboard_GetInterruptVector();
nai_Onboard_ClearInterrupt();
#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 checkForDSWInterrupt(DswConfig inputDSWConfig) {
bool_t bQuit;
int32_t cardIndex;
int32_t module;
uint32_t rawstatus = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
cardIndex = inputDSWConfig.cardIndex;
module = inputDSWConfig.module;
bQuit = FALSE;
interruptOccured = FALSE;
while (!bQuit) {
printf("\nPress enter to check if Lo-Hi interrupt Occurred (press Q to quit):");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit) {
if (interruptOccured) {
check_status(naibrd_DSW_GetGroupStatusRaw(cardIndex, module, 1, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, &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')
{
check_status(naibrd_DSW_ClearGroupStatusRaw(cardIndex, module, 1, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, rawstatus));
}
}
}
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 GetDSWLatchStatusTriggerMode(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 DSW RX interrupt that has just occurred. And gets the status, fifo status,
and fifo data of all channels that interrupted, and prints it.
</summary>
*/
/**************************************************************************************************************/
void handleDSWInterrupt(uint32_t nVector) {
uint32_t rawstatus = 0;
printf("\n\nInterrupt Occurred \n\n");
if (inputInterruptConfig.bPromptForInterruptClear)
{
promptUserToClearInterrupt_DSW();
}
check_status(naibrd_DSW_GetGroupStatusRaw(inputDSWConfig.cardIndex, inputDSWConfig.module, 1, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, &rawstatus));
check_status(naibrd_DSW_ClearGroupStatusRaw(inputDSWConfig.cardIndex, inputDSWConfig.module, 1, NAI_DSW_STATUS_LO_HI_TRANS_LATCHED, rawstatus));
printInterruptInformation_DSW(nVector, rawstatus, FALSE);
}
void promptUserToClearInterrupt_DSW()
{
/* Prompt the user to clear the interrupt received */
SetUserRequestClearInt(FALSE);
printf("\n");
DisplayMessage_DSWInterrupt(MSG_USER_CLEAR_DSW_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_DSWInterrupt(int32_t msgId)
{
switch (msgId)
{
case (int32_t)MSG_BANNER_DSW_INT:
{
printf("\n********************************************************************************");
printf("\n****** DSW INTERRUPT ******");
printf("\nAn interrupt will occur when the DSW Module receives a Lo-Hi transition status ");
printf("\n********************************************************************************");
}
break;
case (int32_t)MSG_USER_TRIGGER_DSW_INT:
{
printf("\nPress \"Q\" to quit the application.\nPlease trigger DSW Lo-Hi status interrupt (Recv Msg):");
}
break;
case (int32_t)MSG_USER_CLEAR_DSW_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_DSW(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");
}