TTL Interrupt Basic Sample Application (SSK 1.x)
Overview
The TTL Interrupt Basic sample application demonstrates the simplest way to have an NAI TTL (Transistor-Transistor Logic) discrete I/O module raise a hardware interrupt when a channel’s logic level changes. Rather than polling a channel’s input state (as TTL BasicOps does), the module is configured to interrupt the host on a low-to-high or high-to-low transition, and an installed Interrupt Service Routine (ISR) records that the event occurred.
“Basic” means this sample deliberately keeps the scope narrow: one channel, onboard interrupts only, a simple ISR that just sets a flag, and a manual check-and-clear loop. The related TTL Interrupt sample extends this to a range of channels, selectable edge/level trigger modes, and offboard interrupts; TTL Interrupt Ethernet delivers the same interrupts over Ethernet.
The sample follows the standard NAI interrupt recipe from the naibrd SSK Quick Guide (Interrupts):
- Select the channel and where the interrupt should be steered.
- Install a bus ISR with
naibrd_InstallISR(). - Configure the module to interrupt on a transition (vector, edge/level, steering).
- Enable the interrupt on the channel.
- Wait for the interrupt and report it.
- Re-arm by clearing the latched status.
- Disable the channel interrupt.
- Uninstall the ISR with
naibrd_UninstallISR().
Note
The board-access and interrupt plumbing (
configureTTLToInterrupt(),enableTTLInterrupts(),basic_ISR_TTL(),checkForTTLInterrupt()) lives in the shared helper filesnai_ttl_int.candnai_ttl_cfg.cunderAppSrc/TTL/NAI_TTL_Common_Utils/. This guide shows both the top-levelTTL_Interrupt_Basic.cand the relevant helper code, because the actualnaibrd_TTL_*()interrupt calls live in the helper.
Prerequisites
Before running this sample, make sure you have:
- An NAI board with a TTL module installed (TL1–TL8), able to raise onboard interrupts on the host bus.
- SSK 1.x installed on your development host.
- The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.
- A way to drive a logic transition on the selected channel (an external signal, or a second output channel wired to it).
How to Run
Launch the TTL_Interrupt_Basic executable from your build output directory. On startup the application looks for a configuration file (default_TTL_Interrupt_Basic.txt). On the first run this file will not exist — the application presents an interactive board menu where you configure a board connection, card index, and module slot. After selecting the module you are prompted for a channel and an interrupt steering destination, then the sample waits for you to trigger a transition on that channel.
Board Connection and Module Selection
Note
This startup sequence is common to all NAI sample applications. The board connection and module selection code shown here is not specific to TTL.
The main() function first zeroes the shared TTL and interrupt configuration structures, then runs the standard SSK 1.x startup flow:
initializeTTLConfigurations(0, 0, 0, 0, 0, 0);
initializeInterruptConfigurations(FALSE, FALSE, FALSE, 0, 0, 0, 0);
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
while (stop != TRUE)
{
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
inputTTLConfig.cardIndex = cardIndex;
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
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_Basic();
}
}
/* ... prompt to quit or restart ... */
}
}The selected card, module, and module ID are stored in the shared inputTTLConfig structure (a TtlConfig), which every helper reads.
Important
Common connection errors you may encounter at this stage:
- No board found — verify that the board is powered on and physically connected. Check that the configuration file lists the correct interface and address.
- Connection timeout — confirm network settings (for Ethernet connections) or bus configuration (for PCI/PCIe). Firewalls and IP mismatches are frequent causes.
- Invalid card or module index — indices are zero-based for cards and one-based for modules.
- No interrupt ever arrives — confirm the interrupt steering destination matches how your host receives interrupts, and that something is actually driving a transition on the selected channel. See the troubleshooting table below.
The Interrupt Setup Sequence
Run_TTL_Interrupt_Basic() is the whole application in miniature. It queries the channel and steering, installs the ISR, configures and enables the interrupt, waits, then tears everything down:
static bool_t Run_TTL_Interrupt_Basic()
{
bool_t bQuit = FALSE;
int32_t maxChannel = naibrd_TTL_GetChannelCount(inputTTLConfig.modid);
int32_t minChannel = 1;
/* Select a single channel; min == max == the chosen channel */
bQuit = naiapp_query_ChannelNumber(maxChannel, minChannel, &inputTTLConfig.channel);
inputTTLConfig.minChannel = inputTTLConfig.channel;
inputTTLConfig.maxChannel = inputTTLConfig.channel;
/* Ask where the interrupt should be steered */
if (!bQuit)
bQuit = GetIntSteeringTypeFromUser(&inputInterruptConfig.steering);
if (!bQuit)
{
/* 2. Bus interrupt handling -- install the ISR */
setIRQ(inputInterruptConfig.steering, &inputInterruptConfig.irq);
naibrd_InstallISR(inputTTLConfig.cardIndex, inputInterruptConfig.irq, basic_ISR_TTL, NULL);
/* 3. Configure the module to interrupt, and 4. enable it */
configureTTLToInterrupt(inputInterruptConfig, inputTTLConfig);
enableTTLInterrupts(inputTTLConfig, TRUE);
/* 5 & 6. Show interrupt handling and re-arm */
bQuit = checkForTTLInterrupt(inputTTLConfig);
/* 7. Disable the channel interrupt */
enableTTLInterrupts(inputTTLConfig, FALSE);
/* 8. Uninstall the ISR */
check_status(naibrd_UninstallISR(inputTTLConfig.cardIndex));
}
return bQuit;
}int32_t naibrd_TTL_GetChannelCount(uint32_t modid)— number of TTL channels for the module (0 if not a TTL module).nai_status_t naibrd_InstallISR(int32_t cardIndex, naibrd_irq_id_t irq_id, nai_isr_t isr, void* param)— registersisras the handler for the given IRQ line on the card. Theirq_idis derived from the chosen steering by thesetIRQ()helper.nai_status_t naibrd_UninstallISR(int32_t cardIndex)— removes the ISR registered on the card.
GetIntSteeringTypeFromUser(), setIRQ(), and initializeInterruptConfigurations() are common (non-TTL) interrupt helpers shared by every module’s interrupt sample.
Configuring the Module to Interrupt
configureTTLToInterrupt() (in nai_ttl_int.c) is where the module is programmed to raise interrupts. It clears any stale latched status, assigns an interrupt vector to each transition type, sets the trigger mode per channel, and steers the interrupt:
/* Clear stale latched status for the whole group before arming */
naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &rawstatus);
naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, rawstatus);
/* ... same for HI_LO_TRANS and BIT ... */
/* Map each transition type to an interrupt vector */
naibrd_TTL_SetGroupInterruptVector(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, NAI_TTL_LOHI_INTERRUPT_VECTOR);
naibrd_TTL_SetGroupInterruptVector(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, NAI_TTL_HILO_INTERRUPT_VECTOR);
naibrd_TTL_SetGroupInterruptVector(cardIndex, module, 1, NAI_TTL_STATUS_BIT_LATCHED, NAI_TTL_BIT_INTERRUPT_VECTOR);
/* Set edge- or level-triggered mode for each channel in range */
for (chan = 1; chan <= inputTTLConfig.maxChannel; chan++)
{
naibrd_TTL_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, (nai_ttl_interrupt_t)interrupt_Edge_Trigger);
/* ... same for HI_LO_TRANS and BIT ... */
}
/* Steer each transition type's interrupt to the chosen destination */
naibrd_TTL_SetGroupInterruptSteering(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, steering);
/* ... same for HI_LO_TRANS and BIT ... */nai_status_t naibrd_TTL_GetGroupStatusRaw(int32_t cardIndex, int32_t module, int32_t group, nai_ttl_status_type_t type, uint32_t* outstatusRaw)— reads the raw latched status bits for a whole channel group at once.nai_status_t naibrd_TTL_ClearGroupStatusRaw(int32_t cardIndex, int32_t module, int32_t group, nai_ttl_status_type_t type, uint32_t statusRaw)— clears the latched status bits by writing back the read-back value. This both clears stale state before arming and re-arms the interrupt afterward.nai_status_t naibrd_TTL_SetGroupInterruptVector(int32_t cardIndex, int32_t module, int32_t group, nai_ttl_status_type_t type, uint32_t vector)— assigns the interrupt vector reported when this status type fires. The sample maps Lo-Hi, Hi-Lo, and BIT to distinct vectors so the handler can tell them apart.nai_status_t naibrd_TTL_SetEdgeLevelInterrupt(int32_t cardIndex, int32_t module, int32_t channel, nai_ttl_status_type_t type, nai_ttl_interrupt_t interruptType)— selects edge-triggered vs. level-triggered latched-status behavior for the channel.nai_status_t naibrd_TTL_SetGroupInterruptSteering(int32_t cardIndex, int32_t module, int32_t group, nai_ttl_status_type_t type, naibrd_int_steering_t steering)— routes the interrupt to a destination (e.g. an onboard processor or the host bus).
The status types used are NAI_TTL_STATUS_LO_HI_TRANS_LATCHED (low-to-high transition), NAI_TTL_STATUS_HI_LO_TRANS_LATCHED (high-to-low transition), and NAI_TTL_STATUS_BIT_LATCHED (built-in-test fault). Interrupts are configured for a group; the group here is group 1.
Enabling the Interrupt and the ISR
Configuration alone does not arm the channel. enableTTLInterrupts() turns the interrupt on (or off) for every channel in the selected range:
void enableTTLInterrupts(TtlConfig inputTTLConfig, bool_t enable)
{
int32_t channel;
for (channel = inputTTLConfig.minChannel; channel <= inputTTLConfig.maxChannel; channel++)
{
naibrd_TTL_SetInterruptEnable(inputTTLConfig.cardIndex, inputTTLConfig.module, channel, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, enable);
naibrd_TTL_SetInterruptEnable(inputTTLConfig.cardIndex, inputTTLConfig.module, channel, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, enable);
naibrd_TTL_SetInterruptEnable(inputTTLConfig.cardIndex, inputTTLConfig.module, channel, NAI_TTL_STATUS_BIT_LATCHED, enable);
}
}nai_status_t naibrd_TTL_SetInterruptEnable(int32_t cardIndex, int32_t module, int32_t channel, nai_ttl_status_type_t type, bool_t enable)— enables or disables interrupt generation for one status type on one channel. In “Basic” the range is a single channel, so this affects just the selected channel.
The installed ISR, basic_ISR_TTL(), is intentionally minimal — it records that an interrupt occurred and captures its vector, leaving the actual work to the main-thread check loop:
#if defined (__VXWORKS__)
void basic_ISR_TTL(uint32_t param)
#else
void basic_ISR_TTL(void *param, uint32_t vector)
#endif
{
interruptOccured = TRUE;
#if defined (__VXWORKS__)
interruptVector = nai_Onboard_GetInterruptVector();
nai_Onboard_ClearInterrupt(); /* on VxWorks the ISR must clear the board interrupt */
#else
interruptVector = vector;
#endif
}Note
Keep ISRs short. This one only sets a flag and stores the vector; all reporting and status-clearing happens on the main thread in
checkForTTLInterrupt(). On VxWorks the ISR must additionally clear the onboard interrupt so it does not re-fire immediately.
Detecting and Re-arming
checkForTTLInterrupt() is the interactive wait loop. Each time you press Enter it reports whether an interrupt fired, prints the vector and raw status, and offers to clear (re-arm) the latched status:
if (interruptOccured)
{
switch (interruptVector)
{
case NAI_TTL_LOHI_INTERRUPT_VECTOR:
printf("\nLo-Hi Interrupt Occurred");
naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &rawstatus);
break;
case NAI_TTL_HILO_INTERRUPT_VECTOR:
printf("\nHi-Lo Interrupt Occurred");
naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &rawstatus);
break;
}
interruptOccured = FALSE;
}
/* If the user asks to clear, write the status back to re-arm */
naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, rawstatus);The vector tells the handler which transition fired; naibrd_TTL_GetGroupStatusRaw() then reports which channels in the group latched, and naibrd_TTL_ClearGroupStatusRaw() clears them so the next transition can interrupt again. Until the latched status is cleared, the same condition will not re-interrupt.
Troubleshooting Reference
This table summarizes common errors and symptoms covered in the sections above. Consult your module’s manual and the naibrd SSK Quick Guide (Interrupts) for more detail.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
| No board found or connection timeout | Board not powered, incorrect or missing configuration file, network issue | Verify hardware is powered and connected; check default_TTL_Interrupt_Basic.txt or reconfigure in the board menu. |
| ISR never fires | No transition on the channel, or interrupt steered somewhere the host does not service | Confirm a real logic transition is occurring on the selected channel, and that the steering destination matches your host. |
| Interrupt fires once, then never again | Latched status not cleared | Clear (re-arm) the latched status with naibrd_TTL_ClearGroupStatusRaw() after handling each interrupt. |
| BIT interrupts unexpectedly | A built-in-test fault on the channel | Investigate the channel’s BIT status; the sample maps NAI_TTL_STATUS_BIT_LATCHED to its own vector. |
| Level-triggered interrupt storms | Level mode with a persistent condition | Use edge-triggered mode (interrupt_Edge_Trigger = 0) unless you specifically need level behavior. |
Full Source
The top-level sample source is shown first, followed by the shared interrupt-helper routines it calls.
Full Source — TTL_Interrupt_Basic.c (SSK 1.x)
/**************************************************************************************************************/
/**
<summary>
The TTL_Interrupt_Basic program demonstrates how to perform an interrupt when a single channel receives
a ttl 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_ttl_int.h"
#include "nai_ttl_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"
/* 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 *CONFIG_FILE = (int8_t *)"default_TTL_Interrupt_Basic.txt";
/********************************/
/* Internal Function Prototypes */
/********************************/
static bool_t Run_TTL_Interrupt_Basic();
/**************************************************************************************************************/
/***** Main Routine *****/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t TTL_Interrupt_Basic(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_Basic();
}
}
}
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 to this module
5. Show Interrupt Handling - Check if any interrupt has occurred and report back the status and vector
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_ClearStatusRaw
7. Clear Module Configurations
8. Clear Board Configurations
API CALLS - naibrd_UninstallISR
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_TTL_Interrupt_Basic()
{
bool_t bQuit = FALSE;
int32_t maxChannel = naibrd_TTL_GetChannelCount(inputTTLConfig.modid);
int32_t minChannel = 1;
/*Query user for RX channel*/
if(!bQuit)
{
bQuit = naiapp_query_ChannelNumber(maxChannel,minChannel,&inputTTLConfig.channel);
inputTTLConfig.minChannel = inputTTLConfig.channel;
inputTTLConfig.maxChannel = inputTTLConfig.channel;
}
/*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);
naibrd_InstallISR(inputTTLConfig.cardIndex,inputInterruptConfig.irq, basic_ISR_TTL,NULL);
/****3. configure Module to perform interrupts****/
configureTTLToInterrupt(inputInterruptConfig,inputTTLConfig);
enableTTLInterrupts(inputTTLConfig,TRUE);
/****5. Show Interrupt Handling (contains step 6)****/
bQuit = checkForTTLInterrupt(inputTTLConfig);
/*****7. Clear Module Configurations*****/
enableTTLInterrupts(inputTTLConfig,FALSE);
/*****8. Clear Board Configurations *****/
check_status(naibrd_UninstallISR(inputTTLConfig.cardIndex));
}
return bQuit;
}Shared interrupt helpers — nai_ttl_int.c (SSK 1.x, relevant routines)
/**************************************************************************************************************/
/* configureTTLToInterrupt: program the module to interrupt on a logic transition (or BIT) for the group. */
/**************************************************************************************************************/
void configureTTLToInterrupt(InterruptConfig inputInterruptConfig, TtlConfig inputTTLConfig)
{
int32_t cardIndex = inputTTLConfig.cardIndex;
int32_t module = inputTTLConfig.module;
int32_t interrupt_Edge_Trigger = inputInterruptConfig.interrupt_Edge_Trigger;
int32_t steering = inputInterruptConfig.steering;
uint32_t rawstatus = 0;
int32_t chan;
enableTTLInterrupts(inputTTLConfig, FALSE);
/* Clear the Interrupt Status (Read the status and write back "1" to statuses which are set to clear the status) */
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &rawstatus));
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, rawstatus));
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &rawstatus));
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, rawstatus));
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_BIT_LATCHED, &rawstatus));
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_BIT_LATCHED, rawstatus));
/* Setup the Interrupt Vector - map to the same vector */
check_status(naibrd_TTL_SetGroupInterruptVector(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, NAI_TTL_LOHI_INTERRUPT_VECTOR));
check_status(naibrd_TTL_SetGroupInterruptVector(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, NAI_TTL_HILO_INTERRUPT_VECTOR));
check_status(naibrd_TTL_SetGroupInterruptVector(cardIndex, module, 1, NAI_TTL_STATUS_BIT_LATCHED, NAI_TTL_BIT_INTERRUPT_VECTOR));
/* Setup the Latched Status Mode (edge/level) for each channel in range */
for (chan = 1; chan <= inputTTLConfig.maxChannel; chan++)
{
check_status(naibrd_TTL_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, (nai_ttl_interrupt_t)interrupt_Edge_Trigger));
check_status(naibrd_TTL_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, (nai_ttl_interrupt_t)interrupt_Edge_Trigger));
check_status(naibrd_TTL_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_TTL_STATUS_BIT_LATCHED, (nai_ttl_interrupt_t)interrupt_Edge_Trigger));
}
check_status(naibrd_TTL_SetGroupInterruptSteering(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, steering));
check_status(naibrd_TTL_SetGroupInterruptSteering(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, steering));
check_status(naibrd_TTL_SetGroupInterruptSteering(cardIndex, module, 1, NAI_TTL_STATUS_BIT_LATCHED, steering));
}
/**************************************************************************************************************/
/* enableTTLInterrupts: enable/disable interrupt generation for each channel in the configured range. */
/**************************************************************************************************************/
void enableTTLInterrupts(TtlConfig inputTTLConfig, bool_t enable)
{
int32_t channel;
for (channel = inputTTLConfig.minChannel; channel <= inputTTLConfig.maxChannel; channel++)
{
check_status(naibrd_TTL_SetInterruptEnable(inputTTLConfig.cardIndex, inputTTLConfig.module, channel, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, enable));
check_status(naibrd_TTL_SetInterruptEnable(inputTTLConfig.cardIndex, inputTTLConfig.module, channel, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, enable));
check_status(naibrd_TTL_SetInterruptEnable(inputTTLConfig.cardIndex, inputTTLConfig.module, channel, NAI_TTL_STATUS_BIT_LATCHED, enable));
}
}
/**************************************************************************************************************/
/* basic_ISR_TTL: minimal ISR -- record that an interrupt occurred and capture its vector. */
/**************************************************************************************************************/
#if defined (__VXWORKS__)
void basic_ISR_TTL(uint32_t param)
#else
void basic_ISR_TTL(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
}
/**************************************************************************************************************/
/* checkForTTLInterrupt: interactive loop -- report the interrupt, and optionally clear (re-arm) the status. */
/**************************************************************************************************************/
bool_t checkForTTLInterrupt(TtlConfig inputTTLConfig)
{
bool_t bQuit;
int32_t cardIndex = inputTTLConfig.cardIndex;
int32_t module = inputTTLConfig.module;
uint32_t rawstatus = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
bQuit = FALSE;
interruptOccured = FALSE;
while (!bQuit)
{
printf("\nPress enter to check if Lo-Hi or Hi-Lo interrupt Occurred (press Q to quit):");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (interruptOccured)
{
switch (interruptVector)
{
case NAI_TTL_LOHI_INTERRUPT_VECTOR:
printf("\nLo-Hi Interrupt Occurred");
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &rawstatus));
break;
case NAI_TTL_HILO_INTERRUPT_VECTOR:
printf("\nHi-Lo Interrupt Occurred");
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &rawstatus));
break;
}
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')
{
switch (interruptVector)
{
case NAI_TTL_LOHI_INTERRUPT_VECTOR:
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, rawstatus));
break;
case NAI_TTL_HILO_INTERRUPT_VECTOR:
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, rawstatus));
break;
}
}
}
}
return bQuit;
}