DSW Interrupt
Edit this on GitLab
DSW Interrupt
Explanation
About the Sample Application Code for NAI DSW Interrupts
The provided C application demonstrates how to perform and manage interrupts on a North Atlantic Industries (NAI) Digital Switching (DSW) module. The purpose of this program is to highlight the method calls in the naibrd
library for performing interrupts, offering both on-board and off-board interrupt handling. Below, we’ll walk through the code and explain its key components and functions.
Include Declarations
The program begins with a series of include declarations, necessary libraries, and headers to handle various functionalities:
-
Standard libraries:
stdio.h
,stdlib.h
,string.h
,time.h
-
NAI-specific headers:
nai_dsw_int.h
,nai_dsw_cfg.h
,nai_dsw_int_ether.h
-
Helper headers for board access and user interaction:
naiapp_interrupt.h
,naiapp_interrupt_ether.h
,naiapp_boardaccess_menu.h
,naiapp_boardaccess_query.h
,naiapp_boardaccess_access.h
,naiapp_boardaccess_display.h
,naiapp_boardaccess_utils.h
-
General NAI library files:
nai.h
,naibrd.h
-
Module-specific header:
functions/naibrd_dsw.h
Configuration Declaration
A static constant CONFIG_FILE
is declared, specifying the default configuration file:
static const int8_t *CONFIG_FILE = (int8_t *)"default_DSW_Interrupt.txt";
Internal Function Prototypes
A static function prototype for Run_DSW_Interrupt()
is declared:
static bool_t Run_DSW_Interrupt();
Main Routine
Main Function
The entry point of the program is the main
function or DSW_Interrupt
function depending on the OS specific macro defined:
#if defined (__VXWORKS__)
int32_t DSW_Interrupt(void)
#else
int32_t main(void)
#endif
This function guides the user through setting up the board and module, and initializing the necessary configurations for handling interrupts.
-
Initialization: Calls
initializeDSWConfigurations
andinitializeInterruptConfigurations
to set up initial configurations. -
Board Menu: Uses
naiapp_RunBoardMenu(CONFIG_FILE)
to display a board configuration menu. -
User Query Loop: Prompts the user to enter the card index, module number, and configurations such as edge trigger value and clearing interrupt preferences.
-
Execution: If a valid module is identified, the program calls
Run_DSW_Interrupt()
to handle the interrupt setup and execution. -
Post-run Prompts: After running the interrupt handling, the user is prompted to either quit or restart the application.
-
Cleanup and Exit: Closes all open cards and exits the program.
Run_DSW_Interrupt Function
This static function performs the core interrupt handling logic in a structured manner:
static bool_t Run_DSW_Interrupt()
-
Channel Range Query: Prompts the user to enter the channel range for the DSW module.
-
Trigger Mode and Interrupt Prompt: Queries the user for the interrupt edge trigger mode and whether prompts are required for clearing interrupts.
-
Onboard/Offboard Interrupts: Asks the user for preferences on onboard versus offboard interrupt processing.
-
Interrupt Steering Set-Up: Prompts for the location where the interrupt will be sent.
-
Bus Interrupt Handling: Installs the appropriate ISR based on the user’s configuration using
naibrd_InstallISR
. -
Module Interrupt Configuration: Configures the DSW module to handle interrupts using
configureDSWToInterrupt
. -
Interrupt Handling Loop: Initializes a thread to handle messages and waits for user-triggered interrupts. Displays relevant messages and processes interrupts using
handleDSWInterrupt
. -
Module and Board Cleanup: Disables interrupts and uninstalls the ISR using
naibrd_UninstallISR
.
By following this well-defined procedure, the application is capable of handling multiple interrupts, responding to user configurations, and facilitating both onboard and offboard interrupt processing efficiently.
/**************************************************************************************************************/
/**
<summary>
The DSW_Interrupt 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.
This application differs from DSW_Interrupt_Basic in that it could handle multiple interrupts at once.
It also queries the user for the edge trigger value and whether the user should be prompted to clear an interrupt.
The application also has support for offboard interrupts.
</summary>
*/
/**************************************************************************************************************/
/************************/
/* Include Declarations */
/************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/*Common Module Specific Sample Program include files*/
#include "nai_dsw_int.h"
#include "nai_dsw_cfg.h"
#include "nai_dsw_int_ether.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"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
/* Module Specific NAI Board Library files */
#include "functions/naibrd_dsw.h"
/*********************************************/
/* Application Name and Revision Declaration */
/*********************************************/
static const int8_t *CONFIG_FILE = (int8_t *)"default_DSW_Interrupt.txt";
/********************************/
/* Internal Function Prototypes */
/********************************/
static bool_t Run_DSW_Interrupt();
/**************************************************************************************************************/
/***** 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 DSW_Interrupt(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;
initializeDSWConfigurations(0, 0, 0, 0, 0, 0);
initializeInterruptConfigurations(FALSE, FALSE, FALSE, 0, 0, 0, 0);
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
while (stop != TRUE)
{
/* Query the user for the card index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
inputDSWConfig.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);
inputDSWConfig.module = module;
if (stop != TRUE)
{
inputDSWConfig.modid = naibrd_GetModuleID(cardIndex, module);
if ((inputDSWConfig.modid != 0))
{
Run_DSW_Interrupt();
}
}
}
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.
2. Bus Interrupt Handling - Install ISR
API CALLS - naibrd_InstallISR
3. Enable Module Interrupts- Configures module to interrupt when channel receives DSW message.
API CALLS - naibrd_DSW_SetInterruptEdgeLevel, naibrd_DSW_SetIntVector, naibrd_DSW_SetInterruptSteering, naibrd_DSW_SetIntEnable
4. Not applicable for DSW module
5. Show Interrupt Handling - Check the mailbox to see if any interrupts occurred.
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, we use an API call to do this.
API CALLS - naibrd_DSW_ClearStatus
7. Clear Module Configurations
8. Clear Board Configurations
API CALLS - naibrd_UninstallISR
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_DSW_Interrupt()
{
bool_t bQuit = FALSE;
int32_t minChannel;
int32_t maxChannel;
minChannel = 1;
maxChannel = naibrd_DSW_GetChannelCount(inputDSWConfig.modid);
/* Query for Channels to Operate on */
bQuit = naiapp_query_ForChannelRange(&inputDSWConfig.minChannel,&inputDSWConfig.maxChannel,minChannel,maxChannel);
/* Query for Trigger Status of interrupts */
if(!bQuit)
{
bQuit = GetDSWLatchStatusTriggerMode(&inputInterruptConfig.interrupt_Edge_Trigger);
}
/* Query user if theyd like to be prompted for clearing interrupts */
if(!bQuit)
{
bQuit = QueryUserForClearingInterruptPrompts(&inputInterruptConfig.bPromptForInterruptClear);
}
if(!bQuit)
{
bQuit = QueryUserForOnboardOffboardInterrupts(&inputInterruptConfig.bProcessOnboardInterrupts);
}
/* Query user for location interrupt will be sent out to */
if(!bQuit)
{
bQuit = GetIntSteeringTypeFromUser(&inputInterruptConfig.steering);
}
if (!bQuit)
{
/**** 2. Implement Bus Interrupt Handling****/
setIRQ(inputInterruptConfig.steering,&inputInterruptConfig.irq);
inputInterruptConfig.cardIndex = inputDSWConfig.cardIndex;
if(inputInterruptConfig.bProcessOnboardInterrupts == TRUE)
{
check_status(naibrd_InstallISR(inputInterruptConfig.cardIndex,inputInterruptConfig.irq,(nai_isr_t)IntOnboardIsr,NULL));
}
else
{
check_status(naibrd_InstallISR(inputInterruptConfig.cardIndex,inputInterruptConfig.irq, (nai_isr_t)IntOffboardIsr, (void*)&inputDSWConfig.cardIndex));
}
/****3. configure Module to perform interrupts****/
configureDSWToInterrupt(inputInterruptConfig,inputDSWConfig);
/****Initialize Message Queue ****/
InitInterruptAppThread(ONBOARD_INT, 0);
nai_msDelay(10);
UpdateThreadState(RUN);
/****Enable Interrupts****/
enableDSWInterrupts(inputDSWConfig,TRUE);
/***5. Show Interrupt Handling (contains step 6) ***/
dswIntProcessFunc = handleDSWInterrupt;
/***Request user triggers interrupt ***/
DisplayMessage_DSWInterrupt(MSG_USER_TRIGGER_DSW_INT);
/****Wait on program threads****/
while (!isThreadStateTerminated()){}
bQuit = TRUE;
/*****7. Clear Module Configurations*****/
enableDSWInterrupts(inputDSWConfig,FALSE);
/*****8. Clear Board Configurations *****/
check_status(naibrd_UninstallISR(inputInterruptConfig.cardIndex));
}
return bQuit;
}