TTL Interrupt
Edit this on GitLab
TTL Interrupt
Explanation
About TTL_Interrupt
Sample Application
Overview
The TTL_Interrupt
program is designed to demonstrate how to handle interrupts in a system using North Atlantic Industries' Synchronous Serial Interface Kit (SSK). This application manages multiple interrupts efficiently and interacts with embedded function modules via predefined method calls in the naibrd
library. It prompts the user for edge trigger values, provides options for clearing interrupts, and supports both onboard and offboard interrupts.
Purpose
The main goal of this application is to educate users on handling interrupts with TTL (Transistor-Transistor Logic) messages. It provides a structured process to configure, activate, handle, and clear interrupts using several library calls.
Code Breakdown
Include Declarations
The program includes multiple headers essential for configuring and managing interrupts:
- Standard libraries: stdio.h
, stdlib.h
, string.h
, time.h
- Module-specific headers: nai_ttl_int.h
, nai_ttl_cfg.h
, nai_ttl_int_ether.h
- Common sample program headers: 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
- NAI board headers: nai.h
, naibrd.h
, functions/naibrd_ttl.h
Application Name and Revision Declaration
This part of the code contains static constants specifying the application name and its version:
static const int8_t *CONFIG_FILE = (int8_t *)"default_TTL_Interrupt.txt";
Internal Function Prototypes
The function Run_TTL_Interrupt()
is declared as an internal function but defined later in the code.
Main Routine
The main function is the entry point of the application:
#if defined (__VXWORKS__)
int32_t TTL_Interrupt(void)
#else
int32_t main(void)
#endif
{
// Variable declarations
bool_t stop = FALSE;
int32_t cardIndex, moduleCnt, module, inputResponseCnt;
int8_t inputBuffer[80];
// Initialize configurations
initializeTTLConfigurations(0, 0, 0, 0, 0, 0);
initializeInterruptConfigurations(FALSE, FALSE, FALSE, 0, 0, 0, 0);
// Run board menu
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
while (stop != TRUE)
{
// Query card index
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
inputTTLConfig.cardIndex = cardIndex;
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
// Query module number
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
inputTTLConfig.module = module;
if (stop != TRUE)
{
inputTTLConfig.modid = naibrd_GetModuleID(cardIndex, module);
if (inputTTLConfig.modid != 0)
{
Run_TTL_Interrupt();
}
}
}
printf("\nType Q to quit or Enter key to restart application:\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
// Exit the program
printf("\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
This main function initializes configurations, runs the board menu, and queries user inputs for card index and module number. Depending on the user input, it triggers the Run_TTL_Interrupt()
function to handle interrupts.
Run_TTL_Interrupt Function
This function manages the interrupt handling process in multiple steps:
static bool_t Run_TTL_Interrupt()
{
bool_t bQuit = FALSE;
int32_t minChannel, maxChannel;
minChannel = 1;
maxChannel = naibrd_TTL_GetChannelCount(inputTTLConfig.modid);
// Query for channels to operate on
bQuit = naiapp_query_ForChannelRange(&inputTTLConfig.minChannel, &inputTTLConfig.maxChannel, minChannel, maxChannel);
if (!bQuit) bQuit = GetTTLLatchStatusTriggerMode(&inputInterruptConfig.interrupt_Edge_Trigger);
if (!bQuit) bQuit = QueryUserForClearingInterruptPrompts(&inputInterruptConfig.bPromptForInterruptClear);
if (!bQuit) bQuit = QueryUserForOnboardOffboardInterrupts(&inputInterruptConfig.bProcessOnboardInterrupts);
if (!bQuit) bQuit = GetIntSteeringTypeFromUser(&inputInterruptConfig.steering);
if (!bQuit)
{
setIRQ(inputInterruptConfig.steering, &inputInterruptConfig.irq);
inputInterruptConfig.cardIndex = inputTTLConfig.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*)&inputTTLConfig.cardIndex));
}
configureTTLToInterrupt(inputInterruptConfig, inputTTLConfig);
InitInterruptAppThread(ONBOARD_INT, 0);
nai_msDelay(10);
UpdateThreadState(RUN);
enableTTLInterrupts(inputTTLConfig, TRUE);
ttlIntProcessFunc = handleTTLInterrupt;
DisplayMessage_TTLInterrupt(MSG_USER_TRIGGER_TTL_INT);
while (!isThreadStateTerminated()){}
bQuit = TRUE;
enableTTLInterrupts(inputTTLConfig, FALSE);
check_status(naibrd_UninstallISR(inputInterruptConfig.cardIndex));
}
return bQuit;
}
This function performs several key operations: 1. Query User Inputs: It gathers the channel range, edge trigger status, interrupt clearing prompts, onboard/offboard interrupt preferences, and interrupt steering type from the user. 2. Bus Interrupt Handling: It installs an ISR (Interrupt Service Routine) based on whether the interrupts are onboard or offboard. 3. Interrupt Configuration: Configures the TTL module to generate interrupts upon receiving messages. 4. Initialize Message Queue and Enable Interrupts: Prepares the message queue and enables interrupts. 5. Interrupt Processing: Handles user-triggered interrupts and waits for threads to terminate. 6. Clear Configurations: Disables interrupts and uninstalls the ISR.
Definitions and Enumerations
-
ISR (Interrupt Service Routine): A function called by the system in response to an interrupt.
-
TTL (Transistor-Transistor Logic): A digital signal technology used for handling logical states.
-
Edge Trigger: Refers to interrupt generation on the rising or falling edge of a signal.
-
Onboard/Offboard Interrupts: Specifies whether the interrupt handling is performed onboard the specific hardware or offboard within a host application.
Summary
The TTL_Interrupt
application effectively demonstrates how to set up and handle interrupts using NAI’s SSK and associated libraries. It offers a user-driven, configurable approach to manage TTL interrupts, making it a valuable learning tool for developers working with NAI’s embedded systems.
/**************************************************************************************************************/
/**
<summary>
The TTL_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 TTL_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_ttl_int.h"
#include "nai_ttl_cfg.h"
#include "nai_ttl_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_ttl.h"
/*********************************************/
/* Application Name and Revision Declaration */
/*********************************************/
/*
static const int8_t *App_Name = "TTL Interrupt";
static const int8_t *App_Rev = "1.0";
*/
static const int8_t *CONFIG_FILE = (int8_t *)"default_TTL_Interrupt.txt";
/********************************/
/* Internal Function Prototypes */
/********************************/
static bool_t Run_TTL_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 TTL_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;
initializeTTLConfigurations(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);
inputTTLConfig.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);
inputTTLConfig.module = module;
if (stop != TRUE)
{
inputTTLConfig.modid = naibrd_GetModuleID(cardIndex, module);
if ((inputTTLConfig.modid != 0))
{
Run_TTL_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 TTL message.
API CALLS - naibrd_TTL_SetInterruptEdgeLevel, naibrd_TTL_SetIntVector, naibrd_TTL_SetInterruptSteering, naibrd_TTL_SetIntEnable
4. Not applicable for TTL 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_TTL_ClearStatus
7. Clear Module Configurations
8. Clear Board Configurations
API CALLS - naibrd_UninstallISR
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_TTL_Interrupt()
{
bool_t bQuit = FALSE;
int32_t minChannel;
int32_t maxChannel;
minChannel = 1;
maxChannel = naibrd_TTL_GetChannelCount(inputTTLConfig.modid);
/*Query for Channels to Operate on*/
bQuit = naiapp_query_ForChannelRange(&inputTTLConfig.minChannel,&inputTTLConfig.maxChannel,minChannel,maxChannel);
/*Query for Trigger Status of interrupts*/
if(!bQuit)
{
bQuit = GetTTLLatchStatusTriggerMode(&inputInterruptConfig.interrupt_Edge_Trigger);
}
/*Query user if they'd 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 = inputTTLConfig.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*)&inputTTLConfig.cardIndex));
}
/****3. configure Module to perform interrupts****/
configureTTLToInterrupt(inputInterruptConfig,inputTTLConfig);
/****Initialize Message Queue ****/
InitInterruptAppThread(ONBOARD_INT, 0);
nai_msDelay(10);
UpdateThreadState(RUN);
/****Enable Interrupts****/
enableTTLInterrupts(inputTTLConfig,TRUE);
/***5. Show Interrupt Handling (contains step 6) ***/
ttlIntProcessFunc = handleTTLInterrupt;
/***Request user triggers interrupt ***/
DisplayMessage_TTLInterrupt(MSG_USER_TRIGGER_TTL_INT);
/****Wait on program threads****/
while (!isThreadStateTerminated()){}
bQuit = TRUE;
/*****7. Clear Module Configurations*****/
enableTTLInterrupts(inputTTLConfig,FALSE);
/*****8. Clear Board Configurations *****/
check_status(naibrd_UninstallISR(inputInterruptConfig.cardIndex));
}
return bQuit;
}