TTL Interrupt Sample Application (SSK 1.x)

Overview

The TTL Interrupt sample application demonstrates a fuller interrupt workflow for an NAI TTL (Transistor-Transistor Logic) discrete I/O module than TTL Interrupt Basic. It configures a module to raise a hardware interrupt on a logic transition, but adds the options a real application usually needs:

  • interrupts across a range of channels, not just one;
  • a choice of edge- or level-triggered latched status;
  • a prompt asking whether to clear (re-arm) after each interrupt;
  • a choice of onboard or offboard interrupt processing; and
  • a background thread that dispatches each interrupt to a handler, instead of a manual “press Enter to check” poll.

The underlying naibrd_TTL_*() interrupt calls are the same ones used by TTL Interrupt Basic — the difference is how they are driven. If you have not read the Basic guide, start there for the eight-step interrupt recipe and the shared configure/enable/re-arm helpers; this guide focuses on what TTL Interrupt adds. For the same interrupts delivered over Ethernet, see TTL Interrupt Ethernet.

Note

As in the Basic sample, the interrupt plumbing lives in the shared helpers nai_ttl_int.c / nai_ttl_cfg.c (under AppSrc/TTL/NAI_TTL_Common_Utils/), and the threading and onboard/offboard ISR helpers (IntOnboardIsr, IntOffboardIsr, InitInterruptAppThread, thread-state routines) live in the common naiapp_interrupt.* files shared by every module’s interrupt sample.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a TTL module installed (TL1–TL8), able to raise onboard (and, for offboard mode, host-serviced) interrupts.
  • 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 logic transitions on the selected channel range.

How to Run

Launch the TTL_Interrupt executable from your build output directory. On startup the application looks for a configuration file (default_TTL_Interrupt.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 answer a short series of prompts (channel range, trigger mode, clear-prompt, onboard/offboard, steering), then trigger transitions and watch the interrupts reported.

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.

main() zeroes the shared TTL and interrupt configuration structures, then runs the standard SSK 1.x board menu / card / module selection, storing the result in inputTTLConfig and handing off to Run_TTL_Interrupt():

initializeTTLConfigurations(0, 0, 0, 0, 0, 0);
initializeInterruptConfigurations(FALSE, FALSE, FALSE, 0, 0, 0, 0);
 
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
   /* ... query card index, module count, module number ... */
   inputTTLConfig.modid = naibrd_GetModuleID(cardIndex, module);
   if ((inputTTLConfig.modid != 0))
      Run_TTL_Interrupt();
}

Important

Common connection errors you may encounter at this stage:

  • No board found / connection timeout — verify the board is powered and connected; check default_TTL_Interrupt.txt or reconfigure in the board menu.
  • Invalid card or module index — indices are zero-based for cards and one-based for modules.
  • No interrupt ever arrives — confirm the steering destination matches how your host receives interrupts, and that transitions are actually occurring on the channel range. See the troubleshooting table below.

What This Sample Adds Over TTL Interrupt Basic

Run_TTL_Interrupt() follows the same eight-step recipe, but with more configuration up front and a threaded wait instead of a manual poll:

minChannel = 1;
maxChannel = naibrd_TTL_GetChannelCount(inputTTLConfig.modid);
 
/* 1. Gather options */
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)
{
   /* 2. Install ISR (onboard or offboard) */
   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 interrupt (shared helper, same as Basic) */
   configureTTLToInterrupt(inputInterruptConfig, inputTTLConfig);
 
   /* Start the interrupt-processing thread */
   InitInterruptAppThread(ONBOARD_INT, 0);
   nai_msDelay(10);
   UpdateThreadState(RUN);
 
   /* 4. Enable interrupts across the channel range */
   enableTTLInterrupts(inputTTLConfig, TRUE);
 
   /* 5 & 6. Dispatch each interrupt to handleTTLInterrupt until the thread terminates */
   ttlIntProcessFunc = handleTTLInterrupt;
   DisplayMessage_TTLInterrupt(MSG_USER_TRIGGER_TTL_INT);
   while (!isThreadStateTerminated()) {}
   bQuit = TRUE;
 
   /* 7 & 8. Disable interrupts and uninstall the ISR */
   enableTTLInterrupts(inputTTLConfig, FALSE);
   check_status(naibrd_UninstallISR(inputInterruptConfig.cardIndex));
}

Gathering Interrupt Options

Five queries populate the shared inputTTLConfig / inputInterruptConfig structures before anything is armed:

  • naiapp_query_ForChannelRange() — selects a minChannel..maxChannel range instead of a single channel. Every channel in the range is configured and enabled.
  • GetTTLLatchStatusTriggerMode() — sets interrupt_Edge_Trigger to 0 (edge) or 1 (level). Edge mode interrupts once per transition; level mode interrupts while the condition persists.
  • QueryUserForClearingInterruptPrompts() — sets bPromptForInterruptClear; when true, the handler pauses to ask you to clear each interrupt.
  • QueryUserForOnboardOffboardInterrupts() — sets bProcessOnboardInterrupts, choosing which ISR is installed (see below).
  • GetIntSteeringTypeFromUser() — chooses the interrupt steering destination, which setIRQ() converts to an IRQ id.

These are common (non-TTL) helpers shared across the module interrupt samples.

Installing the ISR: Onboard vs Offboard

The onboard/offboard choice selects which handler is registered with naibrd_InstallISR():

if (inputInterruptConfig.bProcessOnboardInterrupts == TRUE)
   naibrd_InstallISR(inputInterruptConfig.cardIndex, inputInterruptConfig.irq, (nai_isr_t)IntOnboardIsr, NULL);
else
   naibrd_InstallISR(inputInterruptConfig.cardIndex, inputInterruptConfig.irq, (nai_isr_t)IntOffboardIsr, (void*)&inputTTLConfig.cardIndex);
  • nai_status_t naibrd_InstallISR(int32_t cardIndex, naibrd_irq_id_t irq_id, nai_isr_t isr, void* param) — registers the interrupt handler. IntOnboardIsr handles interrupts serviced on the board itself; IntOffboardIsr handles interrupts serviced by the host application, and is passed the card index as its param so it knows which card interrupted.
  • nai_status_t naibrd_UninstallISR(int32_t cardIndex) — removes the handler during teardown.

Both IntOnboardIsr and IntOffboardIsr are common framework routines; the sample casts them to nai_isr_t when installing.

Configuring and Enabling

configureTTLToInterrupt() and enableTTLInterrupts() are the same shared helpers used by TTL Interrupt Basic — see that guide for the full walkthrough. The only difference here is that the channel range spans minChannel..maxChannel, so configureTTLToInterrupt() sets the edge/level mode for every channel in range and enableTTLInterrupts() enables interrupts on all of them. The key naibrd_TTL_*() calls, all operating on group 1, are:

  • 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 a vector to each transition/BIT status type.
  • 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) — edge vs level, per channel in range.
  • 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 the chosen destination.
  • nai_status_t naibrd_TTL_SetInterruptEnable(int32_t cardIndex, int32_t module, int32_t channel, nai_ttl_status_type_t type, bool_t enable) — arms/disarms each channel.

Threaded Interrupt Handling

Instead of the Basic sample’s manual “press Enter to check” loop, this sample runs a background interrupt-processing thread and hands it a per-interrupt callback:

InitInterruptAppThread(ONBOARD_INT, 0);
nai_msDelay(10);
UpdateThreadState(RUN);
/* ... */
ttlIntProcessFunc = handleTTLInterrupt;   /* callback the thread invokes per interrupt */
while (!isThreadStateTerminated()) {}      /* run until the user quits */

When an interrupt fires, the thread calls handleTTLInterrupt() (in nai_ttl_int.c), which optionally prompts you to clear, then reads and clears the raw group status for whichever transition fired — re-arming that condition:

void handleTTLInterrupt(uint32_t nVector)
{
   uint32_t rawstatus = 0;
 
   if (inputInterruptConfig.bPromptForInterruptClear)
      promptUserToClearInterrupt_TTL();
 
   switch (nVector)
   {
      case NAI_TTL_LOHI_INTERRUPT_VECTOR:
         naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &rawstatus);
         naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, rawstatus);
         break;
      case NAI_TTL_HILO_INTERRUPT_VECTOR:
         naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &rawstatus);
         naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, rawstatus);
         break;
      case NAI_TTL_BIT_INTERRUPT_VECTOR:
         naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_BIT_LATCHED, &rawstatus);
         naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_BIT_LATCHED, rawstatus);
         break;
   }
   printInterruptInformation_TTL(nVector, rawstatus, FALSE);
}
  • 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 which channels in the group latched the status, as a raw bitmask.
  • 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 (re-arms) the latched status by writing the mask back.

The vector distinguishes Lo-Hi, Hi-Lo, and BIT interrupts so the handler reads and clears the right status type.

Troubleshooting Reference

This table summarizes common errors and symptoms covered above. Consult your module’s manual and the naibrd SSK Quick Guide (Interrupts) for more detail.

Error / SymptomPossible CausesSuggested Resolution
No board found or connection timeoutBoard not powered, incorrect or missing config file, network issueVerify hardware; check default_TTL_Interrupt.txt or reconfigure in the board menu.
No interrupt is ever reportedInterrupt steered where the host does not service it, or no transition occurringMatch the steering destination to your host; confirm transitions on the channel range; in offboard mode confirm the host-side path.
Interrupt fires once, then stopsLatched status not clearedLet the handler clear it, or answer “yes” to the clear prompt; naibrd_TTL_ClearGroupStatusRaw() re-arms the condition.
Continuous interrupt stormLevel-triggered mode with a persistent conditionChoose edge-triggered mode (0) unless level behavior is required.
Only some channels interruptChannel range too narrowWiden the minChannel..maxChannel range so every channel of interest is configured and enabled.
Offboard interrupts not handledWrong onboard/offboard choice for your setupRe-run and select the mode that matches whether the board or the host services the interrupt.

Full Source

The top-level sample source is shown first, followed by the shared interrupt-helper routines it calls (the same helpers described in TTL Interrupt Basic, reproduced here for reference).

Full Source — TTL_Interrupt.c (SSK 1.x)
/**************************************************************************************************************/
/**
<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 *CONFIG_FILE = (int8_t *)"default_TTL_Interrupt.txt";
 
/********************************/
/* Internal Function Prototypes */
/********************************/
static bool_t Run_TTL_Interrupt();
 
/**************************************************************************************************************/
/*****                                     Main Routine                                                   *****/
/**************************************************************************************************************/
#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;
}
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));
   }
}
 
/**************************************************************************************************************/
/* handleTTLInterrupt: called per interrupt by the processing thread -- report, then read & clear (re-arm).  */
/**************************************************************************************************************/
void handleTTLInterrupt(uint32_t nVector)
{
   uint32_t rawstatus = 0;
 
   printf("\n\nInterrupt Occurred \n\n");
   if (inputInterruptConfig.bPromptForInterruptClear)
      promptUserToClearInterrupt_TTL();
 
   switch (nVector)
   {
      case NAI_TTL_LOHI_INTERRUPT_VECTOR:
         printf("LoHi Transition Interrupt\n");
         check_status(naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &rawstatus));
         check_status(naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, rawstatus));
         break;
      case NAI_TTL_HILO_INTERRUPT_VECTOR:
         printf("HiLo Transition Interrupt\n");
         check_status(naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &rawstatus));
         check_status(naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, rawstatus));
         break;
      case NAI_TTL_BIT_INTERRUPT_VECTOR:
         printf("BIT Interrupt\n");
         check_status(naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_BIT_LATCHED, &rawstatus));
         check_status(naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_BIT_LATCHED, rawstatus));
         break;
   }
   printInterruptInformation_TTL(nVector, rawstatus, FALSE);
}