Integrator Resources

The official home for NAI Support

Not sure where to start? Try Quick Start Guide or ask a question below!

Toggle Components with Visual Button
JavaScript Form Processing

TTL Interrupt Basic

TTL Interrupt Basic Sample Application (SSK 1.x)

Overview

The TTL Interrupt Basic sample application demonstrates how to configure and handle hardware interrupts on TTL (Transistor-Transistor Logic) I/O modules using the NAI Software Support Kit (SSK 1.x). TTL channels are bidirectional digital I/O lines — each channel can be independently configured as an input or an output. This sample shows how to monitor a single channel for interrupt events across three status types: BIT (Built-In Test) failures, low-to-high signal transitions, and high-to-low signal transitions. The overcurrent status type is also available on TTL modules but is handled through the same group status mechanism demonstrated here.

Transition interrupts detect edge events on input channels — useful for capturing switch closures, signal assertions, and state changes without polling. BIT interrupts verify the internal logic path of each channel, providing continuous hardware health monitoring. Overcurrent interrupts detect output faults when a channel configured as an output is sourcing or sinking excessive current.

This sample supports the following TTL module types: D7 (Gen3), TL1, TL2, TL3, TL4, TL5, TL6, TL7, and TL8 (Gen5).

For background on I/O direction configuration, output modes, and channel format setup, see the TTL BasicOps guide. For general interrupt concepts — including edge vs. level triggering, interrupt vector numbering, steering architecture, and latency measurement — see the Interrupts API Guide. This guide focuses on how those concepts apply specifically to TTL modules and walks through the practical implementation using the SSK 1.x API.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a TTL module installed (D7, TL1-TL8).

  • 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 signal source or external connection to trigger transition interrupts on the monitored channel, or an overcurrent load condition to trigger overcurrent interrupts on an output channel.

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 will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, the application prompts you for a channel number and interrupt steering mode, then begins waiting for interrupt events.

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. For details on board connection configuration, see the First Time Setup Guide.

The main() function (named TTL_Interrupt_Basic() on VxWorks) follows a standard SSK 1.x startup flow:

  1. Initialize default TTL and interrupt configuration structures with initializeTTLConfigurations() and initializeInterruptConfigurations().

  2. Call naiapp_RunBoardMenu() to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_TTL_Interrupt_Basic.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear.

  3. Query the user for the card index and module number. The application validates the module by calling naibrd_GetModuleID() and proceeds only if a valid TTL module is detected.

  4. Call Run_TTL_Interrupt_Basic() to configure and monitor interrupts on the selected module.

#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;
}
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. Ensure the values you pass match your hardware setup.

  • Module not present at selected slot — the slot you selected does not contain a TTL module. Use the board menu to verify which slots are populated.

Program Structure

The TTL Interrupt Basic sample is split across two source files:

  • TTL_Interrupt_Basic.c — contains the main() entry point, board connection logic, user prompts for channel and steering selection, and the top-level interrupt lifecycle (install ISR, configure, monitor, clean up).

  • nai_ttl_int.c — shared TTL interrupt utilities used by all TTL interrupt samples. Contains the interrupt configuration function (configureTTLToInterrupt()), enable/disable logic (enableTTLInterrupts()), the ISR callback (basic_ISR_TTL()), and the interrupt polling/reporting function (checkForTTLInterrupt()).

The entry point is main() (or TTL_Interrupt_Basic() on VxWorks). After establishing the board connection, the application follows a linear flow:

  1. Query the user for the channel number to monitor. The selected channel is stored in inputTTLConfig.channel, and both minChannel and maxChannel are set to the same value so that only the selected channel is configured for interrupts.

  2. Query the user for interrupt steering mode (onboard, offboard PCI, offboard PCIe).

  3. Install the ISR with naibrd_InstallISR().

  4. Configure the module for interrupts with configureTTLToInterrupt().

  5. Enable interrupts with enableTTLInterrupts().

  6. Enter the polling loop with checkForTTLInterrupt(), which waits for the user to press Enter to check for events or Q to quit.

  7. On exit, disable interrupts and uninstall the ISR.

The menu system is a sample convenience — in your own code, call these API functions directly.

Shared Data Structures

The sample uses two structures to track user selections and board state:

  • TtlConfig (defined in nai_ttl_cfg.h) — holds cardIndex, module, modid, channel, minChannel, and maxChannel. These identify the target hardware and the range of channels to configure.

  • InterruptConfig (defined in naiapp_interrupt.h) — holds steering, irq, and interrupt_Edge_Trigger. These control how interrupts are routed and triggered.

Both structures are declared as globals (inputTTLConfig and inputInterruptConfig) so the main file and the shared interrupt utilities can reference them.

Interrupt Status Types

The TTL module exposes four distinct interrupt status types. Each type monitors a different hardware condition and latches when that condition is detected. Understanding what each type reports — and the underlying hardware detection mechanism — will help you decide which ones to enable in your application.

BIT (Built-In Test)

NAI_TTL_STATUS_BIT_LATCHED

The module’s internal self-test continuously verifies the read/write logic path on each TTL channel. The BIT circuitry writes a known value through the channel’s data path and reads it back, confirming that the internal FPGA logic, register interface, and driver circuitry are functioning correctly. When the read-back does not match the expected value, BIT latches the corresponding status bit and, if enabled, raises an interrupt. Detection occurs within 10 ms of the fault condition.

Enable BIT interrupts for health monitoring, safety-critical applications, or continuous hardware validation. BIT detects data path faults — not external signal issues — so a BIT failure indicates an internal hardware problem that requires attention. In systems where a failed channel must be flagged immediately rather than discovered during a periodic status poll, BIT interrupts provide the fastest notification path.

Overcurrent

NAI_TTL_STATUS_OVERCURRENT_LATCHED

An output channel detected an overcurrent condition. When a TTL channel is configured as an output, the module’s current-sensing circuitry monitors the current being sourced or sunk by the output driver. The detection mechanism compares the commanded output value against the actual readback from the output pin. If the readback does not match the commanded state — indicating the output driver cannot maintain the correct voltage level due to excessive current draw — the module flags an overcurrent condition. An 80 ms stabilization period is applied before the fault is confirmed, preventing transient load spikes from generating false alarms. If the overcurrent condition persists after stabilization, the channel is automatically reset to input mode to protect the output driver.

Enable overcurrent interrupts for output protection, fault detection, and load monitoring. In applications that drive external loads through TTL output channels, an overcurrent interrupt lets you react immediately — disabling the output, alerting the operator, or switching to a backup channel — before damage occurs. Common causes include wiring shorts, unexpectedly heavy loads, or back-driving from external circuitry.

Note
Overcurrent detection applies only to channels configured as outputs. Channels in input mode do not generate overcurrent interrupts.

Low-to-High Transition

NAI_TTL_STATUS_LO_HI_TRANS_LATCHED

A TTL input channel detected a rising edge — the signal transitioned from a logic low to a logic high. The module’s input detection circuitry captures this edge with a detection time of approximately 100 ns and latches the status bit so the event is not lost even if the signal changes again before software reads the register.

Enable low-to-high transition interrupts for rising-edge detection: switch closures, signal assertion, event counting, or detecting when an external condition becomes active. This is the most common trigger type for applications that need to respond the moment an input asserts. The 100 ns detection time means the input pulse must remain high for at least 100 ns to be reliably captured.

High-to-Low Transition

NAI_TTL_STATUS_HI_LO_TRANS_LATCHED

A TTL input channel detected a falling edge — the signal transitioned from a logic high to a logic low. The detection circuitry captures this edge with a detection time of approximately 40 ns and latches the status bit for reliable software consumption.

Enable high-to-low transition interrupts for falling-edge detection: switch openings, signal de-assertion, or detecting when an external condition clears. Used together with low-to-high interrupts, the two transition types give full visibility into both edges of a signal, which is useful for measuring pulse widths or tracking state changes. The faster detection time (40 ns vs. 100 ns for low-to-high) reflects the asymmetric switching characteristics of TTL input circuitry.

Note
Transition interrupts apply to channels configured as inputs. Channels configured as outputs will not detect external transitions because the output driver is actively driving the pin. Consult the TL1/TL2 module manual for detailed detection timing specifications and voltage threshold values.

The sample enables BIT, low-to-high, and high-to-low status types for the selected channel. In your own application, enable only the status types relevant to your use case to reduce interrupt traffic and simplify your handler logic. For I/O direction configuration, see the TTL BasicOps guide.

Interrupt Configuration

The configureTTLToInterrupt() function in nai_ttl_int.c performs the complete interrupt setup sequence. The same function is shared by all TTL interrupt samples. It takes the user’s interrupt settings (InterruptConfig) and the target module information (TtlConfig) and configures the module registers in five steps.

Step 1: Disable Interrupts Before Reconfiguring

Always disable interrupts before changing configuration to avoid spurious interrupts during setup. The function begins by calling enableTTLInterrupts(inputTTLConfig, FALSE), which iterates over the configured channel range and disables all three interrupt status types.

enableTTLInterrupts(inputTTLConfig, FALSE);

Step 2: Clear All Status Registers

Stale latched status from a previous run will trigger an immediate interrupt if not cleared. The pattern is: read the current raw status, then write back the value to clear it. The sample repeats this read-and-clear sequence for all three status types — low-to-high transition, high-to-low transition, and BIT.

/* 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));

The naibrd_TTL_GetGroupStatusRaw() call reads all channel statuses for the specified type as a bitmask. Writing that same bitmask back with naibrd_TTL_ClearGroupStatusRaw() clears exactly the bits that were set. The group number 1 refers to the first (and typically only) channel group on TTL modules.

Step 3: Set Interrupt Vector

The vector identifies which interrupt source generated the event. Unlike the DT interrupt sample which uses a single shared vector, the TTL sample assigns a distinct vector to each status type — NAI_TTL_LOHI_INTERRUPT_VECTOR, NAI_TTL_HILO_INTERRUPT_VECTOR, and NAI_TTL_BIT_INTERRUPT_VECTOR. This allows the ISR and polling handler to determine which status type fired by examining the vector value alone.

/* 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));

Step 4: Set Trigger Mode

The trigger mode is set per-channel for each status type. The user’s selection (interrupt_Edge_Trigger) is cast to nai_ttl_interrupt_t and passed to naibrd_TTL_SetEdgeLevelInterrupt(). A value of 0 selects edge-triggered mode, where the interrupt fires once when the condition is first detected. A value of 1 selects level-triggered mode, where the interrupt continues to assert as long as the condition remains active. For detailed theory on edge vs. level triggering and when to use each mode, see the Interrupts API Guide.

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));
}

Step 5: Set Interrupt Steering

Interrupt steering determines how the interrupt signal is delivered from the module to your application. The sample applies the user-selected steering mode to all three status types:

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));

The steering options are:

  • Onboard (NAIBRD_INT_STEERING_ON_BOARD_0) — handled locally on the board’s processor. The ISR runs directly on the board without traversing a bus.

  • cPCI offboard (NAIBRD_INT_STEERING_CPCI_APP) — routes the interrupt to the CompactPCI backplane host.

  • PCIe offboard (NAIBRD_INT_STEERING_PCIE_APP) — routes the interrupt to the PCIe host. Standard choice for desktop or rack-mount systems with a PCIe backplane connection.

For a full description of each steering mode and the hardware paths involved, refer to your module manual and the Interrupts API Guide.

Enable Interrupts Per Channel

After configureTTLToInterrupt() returns, the main application calls enableTTLInterrupts() to turn on interrupt generation for the selected channel. This function iterates from minChannel to maxChannel (both set to the user’s selected channel in this sample) and enables all three status types:

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));
   }
}

In your own application, you can selectively enable only the status types and channels you need rather than enabling everything. For example, if you only need to detect rising edges on channel 3, call naibrd_TTL_SetInterruptEnable() once with NAI_TTL_STATUS_LO_HI_TRANS_LATCHED for channel 3 only.

Important

Common interrupt configuration errors:

  • ISR installation failure — naibrd_InstallISR() returns an error when the steering mode does not match your hardware configuration or bus type. Verify that your steering selection matches the physical bus connection.

  • Interrupts not firing after enable — if latched status registers are not cleared before enabling interrupts, stale status bits from a previous run will not generate a new edge and the interrupt controller will never fire. Always perform the read-and-clear sequence in Step 2 before enabling.

  • Wrong steering mode — selecting onboard steering (ON_BOARD_0) when the ISR is installed as offboard (or vice versa) results in interrupts being routed to a path with no handler. Double-check that the steering mode matches the IRQ ID used in naibrd_InstallISR().

Interrupt Handler and Polling

This sample uses two complementary interrupt handling mechanisms: the ISR callback that fires when the hardware interrupt arrives, and a user-driven polling loop that checks and reports the interrupt state.

ISR Callback

The basic_ISR_TTL() function is the interrupt service routine installed with naibrd_InstallISR(). It is intentionally minimal — ISRs must execute quickly and avoid blocking operations.

#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
}

The ISR sets two global variables: interruptOccured (a boolean flag) and interruptVector (the vector value that identifies which status type fired). On VxWorks, the vector must be retrieved explicitly via nai_Onboard_GetInterruptVector() and the interrupt cleared with nai_Onboard_ClearInterrupt(). On Windows and Linux, the vector is passed directly as a parameter.

Polling and Reporting

The checkForTTLInterrupt() function runs in a loop, prompting the user to press Enter to check whether an interrupt has occurred. When the ISR has set interruptOccured to TRUE, the function examines interruptVector to determine which status type fired, reads the raw group status for that type, and reports the vector and status values.

bool_t checkForTTLInterrupt(TtlConfig inputTTLConfig) {
   bool_t bQuit;
   int32_t cardIndex;
   int32_t module;
   uint32_t rawstatus = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   cardIndex = inputTTLConfig.cardIndex;
   module = inputTTLConfig.module;
   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;
}

The polling handler works as follows:

  1. Check the ISR flag — if interruptOccured is TRUE, the ISR has fired since the last check.

  2. Identify the source — the interruptVector value distinguishes between low-to-high (NAI_TTL_LOHI_INTERRUPT_VECTOR), high-to-low (NAI_TTL_HILO_INTERRUPT_VECTOR), and BIT (NAI_TTL_BIT_INTERRUPT_VECTOR) events.

  3. Read the group status — naibrd_TTL_GetGroupStatusRaw() returns a bitmask indicating which channels in the group triggered. Each set bit corresponds to a channel that latched the status condition.

  4. Report — the vector and raw status values are printed so you can see which interrupt type fired and which channels are affected.

  5. Clear to re-arm — the user is prompted to clear the status register. Answering Y calls naibrd_TTL_ClearGroupStatusRaw() with the previously read status value, which clears exactly the bits that were set and re-arms the interrupt for the next event. If you skip the clear step with edge-triggered interrupts, no new edge will occur and the interrupt will never fire again.

In your own application, you would typically clear the status immediately in the handler rather than prompting the user. The prompt-to-clear approach used here is a learning tool that lets you observe the latched status before it is cleared.

Important

Common interrupt handling errors:

  • Handler never called — the ISR was installed with the wrong IRQ ID for the steering mode, or the steering configuration does not match the physical interrupt path. Verify that the IRQ ID matches the steering mode.

  • Interrupts stop after first event (edge-triggered) — the handler did not clear the latched status register. With edge triggering, the interrupt fires on the transition into the latched state. If the status is never cleared, no new edge occurs. Always call naibrd_TTL_ClearGroupStatusRaw() to re-arm.

  • Interrupts fire continuously (level-triggered) — this is expected behavior. In level-triggered mode, the interrupt re-asserts as long as the condition remains active. Switch to edge-triggered mode or resolve the underlying hardware condition.

  • BIT vector not handled in polling loop — note that the checkForTTLInterrupt() polling loop only has explicit cases for low-to-high and high-to-low vectors. BIT interrupts will still set interruptOccured to TRUE via the ISR, but the polling loop will not read or report BIT status. The more complete handleTTLInterrupt() function in the same file handles all three vector types including BIT. In your own application, handle all enabled status types.

Troubleshooting Reference

This table summarizes common errors and symptoms covered in the sections above. For detailed context, refer to the relevant section. Consult your module’s manual for hardware-specific diagnostic procedures.

Debugging Interrupts That Are Not Firing

When interrupts are not being delivered, use this two-step approach to isolate the problem:

  1. Check whether the status registers are changing. Call naibrd_TTL_GetGroupStatusRaw() to read the latched status registers for the interrupt type you expect. If the status bits are changing when the hardware condition occurs, the module is detecting the event correctly — the issue is in your interrupt delivery path (steering, ISR installation, or IRQ routing).

  2. If the status registers are NOT changing, the issue is at the hardware or channel configuration level. For transition interrupts, verify that the channel is configured as an input (output channels cannot detect external transitions). For overcurrent, verify the channel is configured as an output with a load connected. For BIT, check that the module is healthy and no FPGA errors are present. Consult your module’s manual for the specific register addresses for each status type.

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. If the configuration file exists, check that it lists the correct interface and address. If it does not exist, the board menu will appear — configure and save your connection settings.

Module not detected or not recognized as TTL

No TTL module installed at the selected slot, incorrect module number, or a non-TTL module is present

Verify hardware configuration. naibrd_TTL_GetChannelCount() returning 0 indicates the selected module is not a TTL type.

ISR installation failure

Steering mode does not match hardware configuration, driver not loaded, or bus access issue

Verify steering mode matches your bus architecture. On Linux, check that the NAI driver is loaded. On Windows, verify the device appears in Device Manager.

Interrupts not firing after enable

Status registers not cleared before enabling, wrong steering mode, ISR not installed

Follow the full setup sequence: disable, clear status, set vector, set trigger mode, set steering, install ISR, enable. See the debugging technique above.

Overcurrent interrupts on output channels

Load impedance too low (excessive current draw), wiring short, or back-driving from external circuitry

Measure the load current and verify it is within the module’s rated output current. Check wiring for shorts. The module applies an 80 ms stabilization window before confirming the fault — transient spikes shorter than 80 ms will not trigger the interrupt.

Transition interrupts not firing on channels configured as output

Output channels actively drive the pin and cannot detect external transitions

Reconfigure the channel as an input using the TTL BasicOps API (naibrd_TTL_SetIOFormat()), or monitor a different channel that is already configured as an input. See the TTL BasicOps guide.

BIT failures on healthy hardware

Transient power fluctuation, FPGA initialization not complete, or actual hardware degradation

Retry after power cycling the board. If BIT failures persist, the channel may have a genuine hardware fault — consult the module manual for diagnostic procedures.

Wrong steering mode

Using onboard steering from an external host, or offboard steering from the onboard processor

Match steering to where your application executes. Onboard: ON_BOARD_0. External PCI: CPCI_APP. External PCIe: PCIE_APP.

ISR fires but polling loop reports "No Interrupt Occurred"

Multiple interrupts arrived between user checks and interruptOccured was reset, or the vector did not match a handled case

The polling approach in this sample can miss rapid successive interrupts. In production, use a threaded handler (as shown in the DT Interrupt sample) or read status registers on every ISR invocation.

Edge vs. level mismatch

Edge mode selected but the condition is persistent (interrupt fires once then stops); or level mode selected but only a single notification was expected

Use edge triggering when you want one notification per event and will clear status in the handler. Use level triggering when you need the interrupt to persist until the underlying condition is resolved. See the Interrupts API Guide.

Status registers not changing (debugging)

Channel not configured correctly, trigger mode mismatch, no physical signal present, or channel direction wrong

Verify channel I/O direction, trigger mode, and that the expected signal is present at the input. For transition interrupts, confirm the channel is an input. Read registers directly — consult module manual for addresses.

Full Source

The complete source for this sample is provided below for reference. The sections above explain each part in detail. This sample consists of two source files: the main application and shared TTL interrupt utilities.

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"

InterruptConfig inputInterruptConfig;

/* Extern Functions or Variables*/
extern TtlConfig inputTTLConfig;

/*********************************************/
/* 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                                                   *****/
/**************************************************************************************************************/
/**************************************************************************************************************/
/**
<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_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;
}
Full Source — nai_ttl_int.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.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"

/* Common TTL Sample Program include files */
#include "nai_ttl_int.h"
#include "nai_ttl_cfg.h"

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "naibrd_ether.h"
#include "functions/naibrd_ttl.h"
#include "maps/nai_map_ttl.h"

bool_t interruptOccured; /* used by checkForInterrupt to see if interrupt occurred */
int32_t frameCount;	/* counter increment when frames are found */
uint32_t interruptVector; /* used by checkForInterrupt to get vector of the interrupt that occurred in myIsr */

/* Extern Functions or Variables*/
extern InterruptConfig inputInterruptConfig;
extern TtlConfig inputTTLConfig;

/**************************************************************************************************************/
/**
<summary>
This function configures an interrupt to occur when a message is received on any of the ttl channels.
</summary>
*/
/**************************************************************************************************************/
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 */

   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));

}

/**************************************************************************************************************/
/**
<summary>
Enables the channels within the (minChannel,maxChannel) range to interrupt
if enable is true and disables them otherwise.
</summary>
*/
/**************************************************************************************************************/
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));
   }
}

/**************************************************************************************************************/
/**
<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_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
}
/**************************************************************************************************************/
/**
<summary>
Prompts user to check if an interrupt has occurred. MyIsr() should be installed if using this function.
</summary>
*/
/**************************************************************************************************************/
bool_t checkForTTLInterrupt(TtlConfig inputTTLConfig) {
   bool_t bQuit;
   int32_t cardIndex;
   int32_t module;
   uint32_t rawstatus = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   cardIndex = inputTTLConfig.cardIndex;
   module = inputTTLConfig.module;
   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;
}
/**************************************************************************************************************/
/**
<summary>
GetTTLLatchStatusTriggerMode handles prompting the user for the trigger mode for the latched status register
(Edge Triggered or Level Triggered).
</summary>
*/
/**************************************************************************************************************/
bool_t GetTTLLatchStatusTriggerMode(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 TTL 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 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);
}
void promptUserToClearInterrupt_TTL()
{
   /* Prompt the user to clear the interrupt received */
   SetUserRequestClearInt(FALSE);
   printf("\n");
   DisplayMessage_TTLInterrupt(MSG_USER_CLEAR_TTL_INT);

   /* Wait for the user to respond */
   while (!GetUserRequestClearInt())
   {
      nai_msDelay(10);
   }
}
/**************************************************************************************************************/
/**
<summary>
DisplayMessage_TTLInterrupt handles displaying the messages associated with the msgId passed in.
</summary>
*/
/**************************************************************************************************************/

void DisplayMessage_TTLInterrupt(int32_t msgId)
{
   switch (msgId)
   {
      case (int32_t)MSG_BANNER_TTL_INT:
      {
         printf("\n********************************************************************************");
         printf("\n******                        TTL INTERRUPT                               ******");
         printf("\nAn interrupt will occur when the TTL Module receives an interrupt status  ");
         printf("\n********************************************************************************");
      }
      break;

      case (int32_t)MSG_USER_TRIGGER_TTL_INT:
      {
         printf("\nPress \"Q\" to quit the application.\nPlease trigger TTL Lo-Hi,Hi-Lo or BIT status interrupt:");
      }
      break;

      case (int32_t)MSG_USER_CLEAR_TTL_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_TTL(int32_t interruptID, uint32_t status, bool_t isEther)
{
   printf("-----------------------------------\n");
   if (isEther)
      printf("\nIDR ID = %#x \n", interruptID);
   else
      printf("\nVector = %#x \n", interruptID);
   printf("Status = %#x \n", status);
}

void ClearInterrupt_TTL()
{
   uint32_t status;
   if (inputInterruptConfig.bPromptForInterruptClear)
   {
      promptUserToClearInterrupt_TTL();
   }
   naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &status);
   naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, status);
   naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &status);
   naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, status);
}

Help Bot

X