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

AD FifoMenu

AD FifoMenu Sample Application (SSK 1.x)

Overview

The AD FifoMenu sample application demonstrates how to configure and use FIFO-based continuous data capture on analog-to-digital channels using the NAI Software Support Kit (SSK 1.x). Where the AD BasicOps sample performs single-shot reads of instantaneous channel values, AD FifoMenu shows you how to set up buffered, continuous sampling — capturing a stream of AD conversions into a hardware FIFO that your application drains at its own pace.

FIFO capture provides several advantages over single-shot reads:

  • Continuous sampling — the module converts at a configurable sample rate without host intervention, so you capture data at precise intervals regardless of software timing jitter.

  • Buffered data — samples accumulate in a per-channel hardware FIFO. You read them in bulk when convenient rather than polling one value at a time.

  • Configurable thresholds — high, low, almost-full, and almost-empty thresholds let you trigger interrupts or poll intelligently so your application knows when data is ready or when the buffer is about to overflow.

  • Timestamped samples — an optional timestamp word accompanies each sample, giving you a hardware-generated time reference for every conversion.

This sample supports the following AD module types: AD1 through AD6 and ADE through ADG. It also works with combination modules that include AD functionality: CME, CMF, and CMG. It serves as a practical API reference — each menu command maps directly to one or more naibrd_AD_*() API calls that you can lift into your own code.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with an AD module installed (AD1-AD6 or ADE-ADG).

  • 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.

How to Run

Launch the AD_FifoMenu executable from your build output directory. On startup the application looks for a configuration file (default_ADFifoMenu.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, a channel status display and command menu let you exercise each FIFO operation.

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 AD.

The main() function follows a standard SSK 1.x startup flow:

  1. Call naiapp_RunBoardMenu() to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_ADFifoMenu.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.

  2. Query the user for a card index with naiapp_query_CardIndex().

  3. Query for a module slot with naiapp_query_ModuleNumber().

  4. Retrieve the module ID with naibrd_GetModuleID() so downstream code can adapt to the specific AD variant installed.

#if defined (__VXWORKS__)
int32_t AD_FifoMenu(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  RunMenu(cardIndex, module, moduleID);
               }
            }
         }

         printf("\nType Q to quit or Enter key to restart application:\n");
         stop = 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 an AD module. Use the board menu to verify which slots are populated.

Program Structure

Application Parameters

Once connected, the sample populates an naiapp_AppParameters_t struct that every command function receives:

ad_fifoOps_params.cardIndex = cardIndex;
ad_fifoOps_params.module = module;
ad_fifoOps_params.channel = 1;
ad_fifoOps_params.modId = modid;
ad_fifoOps_params.maxChannels = naibrd_AD_GetChannelCount(modid);

In your own application, you will need to track the same values: card index, module number, active channel, module ID, and channel count. The naibrd_AD_GetChannelCount() call returns the number of AD channels available on the installed module variant.

Command Menu

The RunMenu() function displays the current channel configuration, then presents a command menu. The menu system is a sample convenience — in your own code, call these API functions directly.

Command Shortcut Description

Software Trigger

TRG

Issue a software trigger to start FIFO sampling

Read FIFO

RD

Read a specified number of samples from a channel’s FIFO

Display FIFO Status

STAT

Show the FIFO status register flags for all channels

Clear FIFO

CL

Empty a channel’s FIFO buffer

Configure FIFO

CFG

Set up a channel’s range, thresholds, sample rate, buffer control, and trigger control

Before each command prompt, the sample displays a channel configuration summary showing the current state of every channel: words in FIFO, thresholds, sample delay, FIFO size, sample rate, break frequency, buffer control, trigger control, and the status register. This display calls naibrd_AD_GetFIFO*() functions for each channel and gives you a snapshot of the module’s FIFO state.

FIFO Configuration (CFG)

The Configure FIFO command sets up all parameters needed for FIFO-based capture on a single channel. This is the most important step — the FIFO will not collect data until the channel is properly configured and a trigger is issued.

Channel State

To enable or disable a channel for FIFO capture, call naibrd_AD_SetChannelState(). An inactive channel (state 0) does not participate in sampling.

naibrd_AD_SetChannelState(cardIndex, module, channel, chanState);
Important

AD4 bank constraint: On AD4 modules, channels are divided into two banks (channels 1-8 and channels 9-16). Both banks must have the same number of active channels. If the banks are mismatched, the sample prints an error. Ensure you activate the same count of channels in each bank when working with AD4 modules.

Range and Polarity

To configure the input voltage range and polarity on your channel, call naibrd_AD_SetRange():

if ((Range & NAI_AD_RANGE_BIPOLAR) == NAI_AD_RANGE_BIPOLAR)
   mode = NAI_AD_RANGE_MODE_BIPOLAR;
else
   mode = NAI_AD_RANGE_MODE_UNIPOLAR;

naibrd_AD_SetRange(cardIndex, module, channel, mode, Range);

The Range parameter is a numeric code that encodes both voltage range and polarity. Bit 4 selects bipolar (1) or unipolar (0). The lower bits select the voltage range. Available ranges vary by module type — consult your module’s manual for the supported values. For a detailed explanation of AD range and polarity configuration, see the AD BasicOps guide.

FIFO Thresholds

Thresholds control when the module signals that the FIFO has reached significant fill levels. To set the low and high thresholds, call:

naibrd_AD_SetFIFOLoThreshold(cardIndex, module, channel, LoThreshold);
naibrd_AD_SetFIFOHiThreshold(cardIndex, module, channel, HiThreshold);
  • LoThreshold — the FIFO count below which the low-threshold status flag is set. The sample defaults to 10.

  • HiThreshold — the FIFO count above which the high-threshold status flag is set. The sample defaults to 15.

Both values must be between 0 and the maximum FIFO count for your module, which the sample retrieves with naibrd_AD_GetMaxFIFOCount(modid).

On Gen 5 boards, two additional threshold registers are available:

naibrd_AD_SetFIFOAlmostEmpty(cardIndex, module, channel, AlmostEmpty);
naibrd_AD_SetFIFOAlmostFull(cardIndex, module, channel, AlmostFull);

These provide finer-grained buffer management. The sample defaults to 5 for almost-empty and 18 for almost-full.

Sample Rate and Timing

To set the conversion rate, call naibrd_AD_SetFIFORate():

naibrd_AD_SetFIFORate(cardIndex, module, channel, SampleRate);

The valid range depends on your board generation:

  • Gen 5 boards — 0 to 250,000 samples per second.

  • Gen 3 boards — 0 to 65,535.

To introduce a delay before sampling begins after a trigger, call:

naibrd_AD_SetFIFODelay(cardIndex, module, channel, SampleDelay);

On Gen 5 boards, you can also set a skip count to decimate the sample stream:

naibrd_AD_SetFIFOSkip(cardIndex, module, channel, SkipCount);

Break Frequency

To set the analog filter break frequency, call:

naibrd_AD_SetBreakFrequency(cardIndex, module, channel, BreakFreq);
  • Gen 5 boards — 0 to 250,000 Hz.

  • Gen 3 boards — 0 to 10,000 Hz.

A value of 0 typically disables the filter. Consult your module’s manual for the supported break frequencies on your specific AD variant.

FIFO Size

To set how many samples the FIFO collects per trigger, call:

naibrd_AD_SetFIFOSize(cardIndex, module, channel, SamplesPerTrigger);

The maximum value is determined by naibrd_AD_GetMaxFIFOCount(modid). The sample defaults to 20.

Buffer Control

The buffer control register determines what data words are stored in the FIFO for each sample. To configure it, call:

naibrd_AD_SetFIFOCtrl(cardIndex, module, channel, BufferControl);

The register is a bitmapped value. The available bits differ by board generation:

Gen 5 boards:

  • Bit 2 — Filter: store filtered data (1) or unfiltered data (0).

  • Bit 4 — Timestamp: append a 16-bit timestamp counter to each sample.

Valid combinations: 0, 4, 16, 20.

Gen 3 boards:

  • Bit 0 — 16-bit high data word.

  • Bit 1 — 8-bit low data word (combine with bit 0 for 24-bit resolution).

  • Bit 2 — Filter: store filtered data (1) or unfiltered data (0).

  • Bit 4 — Timestamp: append a 16-bit timestamp counter to each sample.

Valid combinations: 1, 3, 5, 7, 16, 17, 19, 21, 23.

The buffer control setting directly affects how many FIFO words each sample consumes, which determines how many complete samples fit in the FIFO. The GetSamplesInFifo() helper in the sample calculates this by dividing the FIFO word count by the words-per-sample.

Trigger Control

The trigger control register determines how FIFO sampling is initiated. To configure it, call:

naibrd_AD_SetFIFOTrigCtrl(cardIndex, module, channel, TriggerControl);

Gen 5 boards (bitmapped):

  • Bits 0-1 — Trigger type: 0x0 = continuous, 0x1 = single sample.

  • Bits 4-5 — Trigger edge: 0x00 = hardware positive edge, 0x10 = hardware negative edge, 0x20 = hardware either edge, 0x30 = software trigger.

  • Bit 8 — Trigger enable: 0x000 = disabled, 0x100 = enabled.

Default: 0x130 (single sample, software trigger, enabled).

Gen 3 boards (bitmapped):

  • Bits 0-1 — Source select: 0x00 = external trigger 2, 0x01 = external trigger 1, 0x02 = software trigger.

  • Bit 4 — 0x10 = negative slope.

  • Bit 5 — 0x20 = trigger pulse enable.

  • Bit 6 — 0x40 = trigger pulse/trigger enable select.

  • Bit 7 — 0x80 = trigger clear.

Default: 0x22 (software trigger with trigger pulse enable).

Interrupt Masking

Before configuring a channel, the sample disables FIFO interrupts for that channel since the sample uses polling rather than interrupt-driven reads:

naibrd_AD_SetFIFOInterruptEnable(cardIndex, module, channel, 0);

In your own application, you may want to enable interrupts and register a handler instead of polling. Consult the Interrupts API Guide for details on interrupt-driven FIFO operations.

Important

Common Errors

  • NAI_ERROR_NOT_SUPPORTED — the selected module does not support FIFO operations. Verify that your module type (AD1-AD6, ADE-ADG, CME/CMF/CMG) supports FIFO capture by checking the module manual.

  • Illegal buffer control value — the sample validates buffer control against a fixed set of valid combinations. If you enter an unsupported value, the FIFO word count will not divide evenly into samples and reads will produce incorrect data.

  • AD4 bank mismatch — both channel banks must have equal active channel counts. The sample warns you if they are mismatched, but does not prevent configuration.

Software Trigger (TRG)

To start FIFO sampling, issue a software trigger by calling naibrd_AD_SoftwareTrigger(). This triggers all configured channels on the module simultaneously:

check_status(naibrd_AD_SoftwareTrigger(cardIndex, module));

After the trigger fires, the module begins sampling at the configured rate. Samples accumulate in each active channel’s FIFO until the FIFO size limit is reached (for single-sample trigger mode) or until the FIFO is full (for continuous mode).

You must configure at least one channel (via the CFG command) before triggering. If no channels are active, the trigger has no effect.

Important

Common Errors

  • FIFO stays empty after trigger — verify that the channel is active (state = 1), the trigger control has the trigger enabled (bit 8 on Gen 5, or pulse enable on Gen 3), and the trigger source is set to software trigger.

  • Unexpected sample count — in single-sample mode the FIFO collects up to the configured FIFO size and stops. In continuous mode it keeps filling until full. Check your trigger type setting.

Read FIFO (RD)

To read captured samples from a channel’s FIFO, the sample first checks how many words are available, calculates the number of complete samples, then reads and displays them.

Checking FIFO Contents

The sample retrieves the current word count and computes how many complete samples are available:

naibrd_AD_GetFIFOCount(cardIndex, module, channel, &count);
if (count == 0)
{
   printf("FIFO buffer is empty! No words to read!\n");
   return NAI_ERROR_UNKNOWN;
}

The GetSamplesInFifo() helper divides the raw word count by the words-per-sample (determined by the buffer control setting):

naibrd_AD_GetFIFOCtrl(cardIndex, module, channel, &bufferCtrl);

/* Gen 5: 1 word per sample, +1 if timestamp enabled */
/* Gen 3: count 16-bit, 8-bit, and timestamp words */
if (0 != wordsPerSample)
   *samplesInFifo = count / wordsPerSample;

Reading and Converting Samples

Each sample word is read with naibrd_AD_ReadFIFORaw32() and converted to a voltage with naibrd_AD_ConvertToVoltage():

naibrd_AD_ReadFIFORaw32(cardIndex, module, channel, 1, &Data16Hi, &read);
Data = Data16Hi;
naibrd_AD_ConvertToVoltage(modid, RawRange, Data, &Voltage);

For 24-bit resolution (Gen 3 with both 16-bit and 8-bit data enabled), the sample reads two words and combines them:

naibrd_AD_ReadFIFORaw32(cardIndex, module, channel, 1, &Data16Hi, &read);
naibrd_AD_ReadFIFORaw32(cardIndex, module, channel, 1, &Data8Lo, &read);
Data = (Data16Hi << 16) | Data8Lo;
naibrd_AD_ConvertToVoltage(modid, RawRange, Data, &Voltage);

If timestamps are enabled in the buffer control, an additional word is read after the data word(s):

if (Buffer_Controls[TIME_STAMP])
{
   naibrd_AD_ReadFIFORaw32(cardIndex, module, channel, 1, &Data16Hi, &read);
   printf(" %d ", Data16Hi);
}

The voltage conversion requires the current range setting, which the sample retrieves with naibrd_AD_GetRange() and converts to a raw range code with naibrd_AD_ConvertToVoltageRangeRaw().

Important

Common Errors

  • FIFO buffer is empty — no trigger has been issued, or the trigger completed and the FIFO has already been read. Issue a new software trigger with the TRG command.

  • Incorrect voltage values — the range used for conversion must match the range configured on the channel. If you change the range after capturing samples, the previously captured raw data will convert to incorrect voltages.

  • Incomplete samples — if the buffer control setting changes between configuration and reading, the words-per-sample calculation will be wrong. Always read the FIFO with the same buffer control that was active during capture.

Display FIFO Status (STAT)

To check the status of all channel FIFOs, use the Display FIFO Status command. It reads the FIFO status register for every channel and decodes the individual flag bits:

naibrd_AD_GetFIFOStatus(cardIndex, module, channel, NAI_AD_FIFO_STATUS_REALTIME, &fifoStatus);

The NAI_AD_FIFO_STATUS_REALTIME parameter requests the live status (as opposed to latched status).

Gen 5 status flags:

Flag Meaning

Sample Done

The FIFO has collected the configured number of samples

FIFO Full

The FIFO buffer is completely full

High Limit

The word count has exceeded the high threshold

Low Limit

The word count is below the low threshold

Empty

The FIFO contains no data

Almost Empty

The word count is at or below the almost-empty threshold

Almost Full

The word count is at or above the almost-full threshold

Gen 3 status flags:

Flag Meaning

Sample Done

The FIFO has collected the configured number of samples

FIFO Full

The FIFO buffer is completely full

High Limit

The word count has exceeded the high threshold

Low Limit

The word count is below the low threshold

Empty

The FIFO contains no data

Use these flags to determine when to read the FIFO. In a production application, you would typically poll for Sample Done or High Limit (or register an interrupt) rather than reading blindly.

Important

Common Errors

  • All flags show 0 — no trigger has been issued, or the channel is inactive. Configure and trigger the channel first.

  • FIFO Full flag is set — data is being lost. Read the FIFO more frequently, increase the FIFO size, or reduce the sample rate.

Clear FIFO (CL)

To empty a channel’s FIFO buffer and reset its word count, call naibrd_AD_ClearFIFO():

check_status(naibrd_AD_ClearFIFO(cardIndex, module, channel));

Clearing the FIFO discards all unread samples. This is useful when you want to start a fresh capture without old data in the buffer. After clearing, you will need to issue a new software trigger to begin sampling again.

Important

Common Errors

  • Data still appears after clear — if a trigger is active in continuous mode, the FIFO will immediately begin refilling after being cleared. Disable the trigger or switch to single-sample mode before clearing if you need the FIFO to stay empty.

Troubleshooting Reference

The following table summarizes errors and symptoms you may encounter while using the AD FifoMenu sample. Consult your module’s manual for hardware-specific diagnostics.

Error / Symptom Possible Causes Suggested Resolution

No board found

Board not powered on; incorrect interface or address in config file.

Verify physical connection and configuration file settings. Delete default_ADFifoMenu.txt to force the board menu to reappear.

Connection timeout

Network misconfiguration; firewall blocking traffic; wrong IP address.

Confirm Ethernet settings or PCI/PCIe bus configuration. Check firewalls.

Invalid card or module index

Zero-based card index or one-based module index mismatch.

Cards are zero-based, modules are one-based. Verify your values match the hardware.

Module not present at selected slot

No AD module in the chosen slot.

Use the board menu to verify which slots are populated.

FIFO stays empty after trigger

Channel inactive; trigger not enabled; trigger source not set to software.

Verify channel state is active (1), trigger enable bit is set, and trigger source is software trigger.

FIFO Full — data overflow

Reading too slowly for the configured sample rate.

Increase read frequency, reduce sample rate, or increase FIFO size. Clear the FIFO and re-trigger.

Incorrect voltage readings

Range mismatch between configuration and conversion; buffer control changed between capture and read.

Ensure the range and buffer control settings have not changed since the trigger was issued.

NAI_ERROR_NOT_SUPPORTED

Module does not support the requested FIFO feature.

Verify your module type supports FIFO operations. Check the module manual.

AD4 bank mismatch error

Unequal number of active channels in bank 1 (ch 1-8) and bank 2 (ch 9-16).

Activate the same number of channels in each bank on AD4 modules.

Illegal buffer control value

Unsupported bit combination entered for buffer control register.

Use only the documented valid combinations for your board generation (Gen 3 or Gen 5).

Sample count does not match expected

Single-sample vs. continuous trigger mode confusion; FIFO size configured too small.

Check trigger type (continuous vs. single) and FIFO size setting.

Full Source

Full Source — AD_FifoMenu.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

/* Common Sample Program include files */
#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"
#include "functions/naibrd_ad.h"
#include "advanced/nai_ether_adv.h"

static const int8_t *CONFIG_FILE = (int8_t *)"default_ADFifoMenu.txt";

/* Function prototypes */
static bool_t RunMenu(int32_t cardIndex, int32_t module, uint32_t modid);
static void AD_displayChannelCfg(int32_t cardIndex, int32_t module, int32_t MAX_CHANNELS);

/* AD FIFO Command Functions */
static nai_status_t AD_SwTrigger(int32_t paramCount, int32_t* p_params);
static nai_status_t AD_ReadFifo(int32_t paramCount, int32_t* p_params);
static nai_status_t AD_DisplayFifoStatus(int32_t paramCount, int32_t* p_params);
static nai_status_t AD_ClearFifo(int32_t paramCount, int32_t* p_params);
static nai_status_t AD_ConfigChannel(int32_t paramCount, int32_t* p_params);

/* Additional Helper Functions */
static bool_t AD_getInput(uint32_t *value);
static void printRangeRequest();
static void printBufferRequest(int32_t cardIndex);
static void printTriggerCtrlRequest(int32_t cardIndex);
static void GetSamplesInFifo(int32_t cardIndex, int32_t module, int32_t channel, uint32_t count, uint32_t *samplesInFifo);
static void GetBufferControls(int32_t cardIndex, int32_t module, int32_t channel, bool_t Buffer_Controls[]);
static void PrintSamplesInFifo(int32_t cardIndex, int32_t module, int32_t channel, uint32_t samplesToRead, bool_t Buffer_Controls[]);

/****** Buffer Controls *******/
enum ad_buffer_options {DATA_16BIT, DATA_8BIT, DATA_RAW, TIME_STAMP, BUFFER_OPTIONS };

/****** Command Table *******/
/*** Invariant: enumeration of cmd table starts from 0 and increments by 1 ***/
enum ad_fifo_commands
{
   AD_FIFO_CMD_SW_TRIGGER,
   AD_FIFO_CMD_READ_FIFO,
   AD_FIFO_CMD_DISPLAY_FIFO_STATUS,
   AD_FIFO_CMD_CLEAR_FIFO,
   AD_FIFO_CMD_CONFIG,
   AD_FIFO_CMD_COUNT
};

naiapp_cmdtbl_params_t AD_FifoMenuCmds[] = {
   {"TRG",  "Execute Software Trigger",         AD_FIFO_CMD_SW_TRIGGER,             AD_SwTrigger},
   {"RD",   "Read data from the FIFO",          AD_FIFO_CMD_READ_FIFO,              AD_ReadFifo},
   {"STAT", "Display FIFO Status",              AD_FIFO_CMD_DISPLAY_FIFO_STATUS,    AD_DisplayFifoStatus},
   {"CL",   "Clear FIFO",                       AD_FIFO_CMD_CLEAR_FIFO,             AD_ClearFifo},
   {"CFG",  "Configure FIFO",                   AD_FIFO_CMD_CONFIG,                 AD_ConfigChannel},
};

/**************************************************************************************************************/
/**
<summary>
The purpose of the AD_FifoMenu is to illustrate the methods to call in the naibrd library to perform FIFO
 operations with the AD modules for configuration setup and reading the channels.

The following system configuration routines from the nai_sys_cfg.c file are called to assist with the configuration
setup for this program prior to calling the naibrd DT routines.
 - ClearDeviceCfg
 - QuerySystemCfg
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - SaveDeviceCfg
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t AD_FifoMenu(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         /* Query the user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Query the user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  RunMenu(cardIndex, module, moduleID);
               }
            }
         }

         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>
RunMenu illustrates the channel configuration and prepares the menu which will handle user command requests.
Returns TRUE if the user enters the Quit Command at any point within its scope.
</summary>
*/
/**************************************************************************************************************/
static bool_t RunMenu(int32_t cardIndex, int32_t module, uint32_t modid)
{
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   bool_t bCmdFound = FALSE;
   naiapp_AppParameters_t  ad_fifoOps_params;
   int32_t cmd;

   ad_fifoOps_params.cardIndex = cardIndex;
   ad_fifoOps_params.module = module;
   ad_fifoOps_params.channel = 1;
   ad_fifoOps_params.modId = modid;
   ad_fifoOps_params.maxChannels = naibrd_AD_GetChannelCount(modid);

   naiapp_utils_LoadParamMenuCommands(AD_FIFO_CMD_COUNT, AD_FifoMenuCmds);
   do
   {
      AD_displayChannelCfg(cardIndex, module, ad_fifoOps_params.maxChannels);
      naiapp_display_ParamMenuCommands((int8_t*)"A/D FIFO MENU");
      printf("\n\nPlease enter a command or 'q' to quit:");
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);

      if (inputResponseCnt > 0)
         {
            bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
            if (bCmdFound)
            {
               AD_FifoMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)&ad_fifoOps_params);
            }
            else
            {
               printf("Invalid command entered\n");
            }
         }

   } while (!bQuit);
   return bQuit;
}
/**************************************************************************************************************/
/**
<summary>
AD_displayChannelCfg display each channel's settings and values for:
   words in fifo, high threshold, low threshold, sample delay, size of fifo, sample rate,
   break frequency, buffer control, trigger control, and the status register.
</summary>
*/
/**************************************************************************************************************/
static void AD_displayChannelCfg(int32_t cardIndex, int32_t module, int32_t MAX_CHANNELS)
{
   uint32_t LoThreshold, HiThreshold, WordsInFifo, SampleDelay, AlmostEmpty, AlmostFull;
   uint32_t FifoSize, SampleRate, BreakFreq, BufferControl, TriggerControl, SkipCount;
   nai_ad_fifo_status_t StatusReg;
   nai_ad_state_t chanState = NAI_AD_STATE_ACTIVE;
   int32_t channel;
   uint32_t modid, modver, modrev, special, boardgen;

   naibrd_GetModuleInfo(cardIndex, module, &modid, &modver, &modrev, &special);

   naibrd_GetBoardGen(cardIndex, &boardgen);
   if ( NAI_XILINX_GEN5_ID == boardgen )
   {
      uint32_t bank1ActiveChannels = 0, bank2ActiveChannels = 0;

      printf( "\n            Words   High    Low     Almost   Almost                    Size");
      printf( "\n             in     Thres-  Thres-  Empty    Full     Sample   Skip     of    Sample  Break  Buffer Trig   Status");
      printf( "\nChan Active Fifo    hold    hold                      Delay    Count   FIFO   Rate    Freq   Ctrl   Ctrl  Register");
      printf( "\n------------------------------------------------------------------------------------------------------------------");
      for ( channel = 1; channel <= MAX_CHANNELS; channel++ )
      {
         if ( channel <= 8 )
         {
            if ( 0 < chanState )
               bank1ActiveChannels++;
         }
         else
         {
            if ( 0 < chanState )
               bank2ActiveChannels++;
         }

         naibrd_AD_GetFIFOCount(cardIndex, module, channel, &WordsInFifo);
         naibrd_AD_GetFIFOLoThreshold(cardIndex, module, channel, &LoThreshold);
         naibrd_AD_GetFIFOHiThreshold(cardIndex, module, channel, &HiThreshold);
         naibrd_AD_GetFIFOAlmostEmpty(cardIndex, module, channel, &AlmostEmpty);
         naibrd_AD_GetFIFOAlmostFull(cardIndex, module, channel, &AlmostFull);
         naibrd_AD_GetFIFODelay(cardIndex, module, channel, &SampleDelay);
         naibrd_AD_GetFIFOSkip(cardIndex, module, channel, &SkipCount);
         naibrd_AD_GetFIFOSize(cardIndex, module, channel, &FifoSize);
         naibrd_AD_GetFIFORate(cardIndex, module, channel, &SampleRate);
         naibrd_AD_GetBreakFrequency(cardIndex, module, channel, &BreakFreq);
         naibrd_AD_GetFIFOCtrl(cardIndex, module, channel, &BufferControl);
         naibrd_AD_GetFIFOTrigCtrl(cardIndex, module, channel, &TriggerControl);
         naibrd_AD_GetFIFOStatus(cardIndex, module, channel, NAI_AD_FIFO_STATUS_REALTIME, &StatusReg);
         printf( "\n %2d    %d     %-6u  %-5d   %-5d   %-5d   %-5d      %-5d   %-5d  %-5d  %-5d   %-5d  0x%02X    0x%02X   0x%02X",
            channel, chanState, WordsInFifo, HiThreshold, LoThreshold, AlmostEmpty, AlmostFull, SampleDelay,
            SkipCount, FifoSize, SampleRate, BreakFreq, BufferControl, TriggerControl, StatusReg );
      }

      if (modid == NAI_MODULE_ID_AD4)
      {
         if ( (bank1ActiveChannels == 0) || (bank2ActiveChannels == 0) )
         {
            printf( "\n\n**ERROR - At least 1 channel per bank MUST be active!\n" );
            printf( "  - Bank 1 = channels 1..8, Bank 2 = channels 9..16\n" );
         }
         else if ( bank1ActiveChannels != bank2ActiveChannels )
         {
            printf( "\n\n**ERROR - Same number of channels MUST be active in both banks!\n" );
            printf( "  - Bank 1 (channels 1..8) Active Channels: %d, Bank 2 (channels 9..16) Active Channels: %d\n", bank1ActiveChannels, bank2ActiveChannels);
         }
      }
   }
   else
   {
      printf( "\n            Words   High    Low              Size");
      printf( "\n             in     Thres-  Thres-  Sample    of    Sample  Break  Buffer Trig   Status");
      printf( "\nChan Active Fifo    hold    hold    Delay    FIFO   Rate    Freq   Ctrl   Ctrl  Register");
      printf( "\n----------------------------------------------------------------------------------------");
      for ( channel = 1; channel <= MAX_CHANNELS; channel++ )
      {
         naibrd_AD_GetChannelState(cardIndex, module, channel, &chanState);
         naibrd_AD_GetFIFOCount(cardIndex, module, channel, &WordsInFifo);
         naibrd_AD_GetFIFOLoThreshold(cardIndex, module, channel, &LoThreshold);
         naibrd_AD_GetFIFOHiThreshold(cardIndex, module, channel, &HiThreshold);
         naibrd_AD_GetFIFODelay(cardIndex, module, channel, &SampleDelay);
         naibrd_AD_GetFIFOSize(cardIndex, module, channel, &FifoSize);
         naibrd_AD_GetFIFORate(cardIndex, module, channel, &SampleRate);
         naibrd_AD_GetBreakFrequency(cardIndex, module, channel, &BreakFreq);
         naibrd_AD_GetFIFOCtrl(cardIndex, module, channel, &BufferControl);
         naibrd_AD_GetFIFOTrigCtrl(cardIndex, module, channel, &TriggerControl);
         naibrd_AD_GetFIFOStatus(cardIndex, module, channel, NAI_AD_FIFO_STATUS_REALTIME, &StatusReg);
         printf( "\n %2d    %d     %-6u  %-5d   %-5d   %-5d   %-5d  %-5d   %-5d  0x%02X    0x%02X   0x%02X",
            channel, chanState, WordsInFifo, HiThreshold, LoThreshold, SampleDelay, FifoSize, SampleRate,
            BreakFreq, BufferControl, TriggerControl, StatusReg );
      }
   }
}
/**************************************************************************************************************/
/**
<summary>
AD_configChannel initiates all the channels for writing and handles the user requests to configure the channels.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t AD_ConfigChannel(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t channel = p_ad_params->channel;
   uint32_t Range = 0, LoThreshold = 0, HiThreshold = 0, SamplesPerTrigger = 0, SampleDelay = 0, AlmostEmpty = 0, AlmostFull = 0;
   uint32_t SkipCount = 0, SampleRate = 0, BreakFreq = 0, BufferControl = 0, TriggerControl = 0, MAX_FIFO_COUNT;
   nai_ad_range_mode_t mode;
   nai_ad_state_t chanState;
   bool_t success = FALSE;
   uint32_t modid, modver, modrev, special, boardgen;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif


   naibrd_GetModuleInfo(cardIndex, module, &modid, &modver, &modrev, &special);
   MAX_FIFO_COUNT = naibrd_AD_GetMaxFIFOCount(modid);

   /* Query the user for the channel number */
   naiapp_query_ChannelNumber(p_ad_params->maxChannels, 1, &channel);

   naibrd_AD_SetFIFOInterruptEnable(cardIndex, module, channel, 0);

   naibrd_AD_SetRaw(cardIndex, module, NAI_AD_RAW_CLK_RATE_ADDER_HI, 0x0000);
   naibrd_AD_SetRaw(cardIndex, module, NAI_AD_RAW_CLK_RATE_ADDER_LO, 0xAC44);

   naibrd_GetBoardGen(cardIndex, &boardgen);
   if ( NAI_BLACKFIN_GEN3_ID == boardgen )
   {
   }

   do
   {
      printf("Set channel %d to Active(1) or Inactive(0)?", channel);
      success = AD_getInput(&chanState);
   } while ( !success || ((chanState != 0) && (chanState != 1)) );

   if ( 0 != chanState )
   {
      do
      {
         printRangeRequest();
         success = AD_getInput(&Range);
         if ( TRUE != success )
            Range = 16;
         success = TRUE;
      } while ( !(success) || !(( Range <= 3) || (Range >= 9 && Range <= 10) ||
                  (Range >= 16 && Range <= 19) || (Range >=25 && Range <= 26 )) );

      if ((Range & NAI_AD_RANGE_BIPOLAR) == NAI_AD_RANGE_BIPOLAR)
         mode = NAI_AD_RANGE_MODE_BIPOLAR;
      else
         mode = NAI_AD_RANGE_MODE_UNIPOLAR;
      do
      {
         printf( "\nPlease enter low threshold (0-%d) [default=10]:\n>>", MAX_FIFO_COUNT);
         success = AD_getInput(&LoThreshold);
         if ( TRUE != success )
            LoThreshold = 10;
         success=TRUE;
      } while (!success || (LoThreshold > MAX_FIFO_COUNT));
      do
      {
         printf( "\nPlease enter high threshold (0-%d) [default=15]:\n>>", MAX_FIFO_COUNT);
         success = AD_getInput(&HiThreshold);
         if ( TRUE != success )
            HiThreshold = 15;
         success= TRUE;
      } while (!success || (HiThreshold > MAX_FIFO_COUNT));

      if ( NAI_XILINX_GEN5_ID == boardgen )
      {
         do
         {
            printf( "\nPlease enter Almost Empty threshold (0-%d) [default=5]:\n>>", MAX_FIFO_COUNT);
            success = AD_getInput(&AlmostEmpty);
            if ( TRUE != success )
               AlmostEmpty = 5;
            success = TRUE;
         } while (!success || (AlmostFull > MAX_FIFO_COUNT));
         do
         {
            printf( "\nPlease enter Almost Full threshold (0-%d) [default=18]:\n>>", MAX_FIFO_COUNT);
            success = AD_getInput(&AlmostFull);
            if ( TRUE != success )
               AlmostFull = 18;
            success = TRUE;
         } while (!success || (AlmostFull > MAX_FIFO_COUNT));
         do
         {
            printf( "\nPlease enter the sample rate (0-250000) [default=250000]:\n>>");
            success = AD_getInput(&SampleRate);
            if ( TRUE != success )
               SampleRate = 250000;
            success = TRUE;
         } while (!success || (SampleRate > 250000));
         do
         {
            printf( "\nPlease enter the delay (0-4294967295 (0xFFFFFFFF)) [default=0]:\n>>");
            success = AD_getInput(&SampleDelay);
            if ( TRUE != success )
               SampleDelay = 0;
            success = TRUE;
         } while (!success || (SampleDelay > 4294967295U));
         do
         {
            printf( "\nPlease enter the Break Frequency (0-250000) [default=0]:\n>>");
            success = AD_getInput(&BreakFreq);
            if ( TRUE != success )
               BreakFreq = 0;
            success = TRUE;
         } while (!success || (BreakFreq > 250000));
         do
         {
            printf( "\nPlease enter the Skip Count (0-4294967295 (0xFFFFFFFF)) [default=0]:\n>>");
            success = AD_getInput(&SkipCount);
            if ( TRUE != success )
               SkipCount = 0;
            success = TRUE;
         } while (!success || (SkipCount > 4294967295U));
      }
      else
      {
         do
         {
            printf( "\nPlease enter the sample rate (0-65,535) [default=65535]:\n>>");
            success = AD_getInput(&SampleRate);
            if ( TRUE != success )
               SampleRate = 65535;
            success = TRUE;
         } while (!success || (SampleRate > 65535));
         do
         {
            printf( "\nPlease enter the delay (0-65,535) [default=0]:\n>>");
            success = AD_getInput(&SampleDelay);
            if ( TRUE != success )
               SampleDelay = 0;
            success = TRUE;
         } while (!success || (SampleDelay > 65535));
         do
         {
            printf( "\nPlease enter the Break Frequency (0-10,000) [default=0]:\n>>");
            success = AD_getInput(&BreakFreq);
            if ( TRUE != success )
               BreakFreq = 0;
            success = TRUE;
         } while (!success || (BreakFreq > 10000));
      }

      do
      {
         printf( "\nPlease enter the fifo size (0-%d) [default=20]:\n>>", MAX_FIFO_COUNT);
         success = AD_getInput(&SamplesPerTrigger);
         if ( TRUE != success )
               SamplesPerTrigger = 20;
         success = TRUE;
      } while (!success || (SamplesPerTrigger > MAX_FIFO_COUNT));
      do
      {
         printBufferRequest(cardIndex);
         success = AD_getInput(&BufferControl);
         if ( NAI_XILINX_GEN5_ID == boardgen )
         {
            if ( TRUE != success )
               BufferControl = 0;

            success = (BufferControl == 0 || BufferControl == 4 || BufferControl == 16 ||
               BufferControl == 20);
         }
         else
         {
            if ( TRUE != success )
               BufferControl = 1;

            success = (BufferControl == 1 || BufferControl == 3 || BufferControl == 5 || BufferControl == 7) ||
               (BufferControl == 16 || BufferControl == 17 || BufferControl == 19 || BufferControl == 21) ||
               (BufferControl == 23);
         }
      } while (!success);
      do
      {
         printTriggerCtrlRequest(cardIndex);
         success = AD_getInput(&TriggerControl);
         if ( TRUE != success )
         {
            if ( NAI_XILINX_GEN5_ID == boardgen )
               TriggerControl = 0x130;
            else
               TriggerControl = 0x22;

            success = TRUE;
         }
      } while (!success);

      naibrd_AD_SetChannelState(cardIndex, module, channel, chanState);
      naibrd_AD_SetRange(cardIndex, module, channel, mode, Range);
      naibrd_AD_SetFIFOLoThreshold(cardIndex, module, channel, LoThreshold);
      naibrd_AD_SetFIFOHiThreshold(cardIndex, module, channel, HiThreshold);
      naibrd_AD_SetFIFODelay(cardIndex, module, channel, SampleDelay);
      naibrd_AD_SetFIFOSize(cardIndex, module, channel, SamplesPerTrigger);
      naibrd_AD_SetFIFORate(cardIndex, module, channel, SampleRate);
      naibrd_AD_SetBreakFrequency(cardIndex, module, channel, BreakFreq);
      naibrd_AD_SetFIFOCtrl(cardIndex, module, channel, BufferControl);
      naibrd_AD_SetFIFOTrigCtrl(cardIndex, module, channel, TriggerControl);

      if ( NAI_XILINX_GEN5_ID == boardgen )
      {
         naibrd_AD_SetFIFOAlmostEmpty(cardIndex, module, channel, AlmostEmpty);
         naibrd_AD_SetFIFOAlmostFull(cardIndex, module, channel, AlmostFull);
         naibrd_AD_SetFIFOSkip(cardIndex, module, channel, SkipCount );
      }
   }
   else
      naibrd_AD_SetChannelState(cardIndex, module, channel, chanState);

   return NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
AD_SwTrigger calls the SoftwareTrigger API which causes the FIFO to start sampling.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t AD_SwTrigger(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   check_status(naibrd_AD_SoftwareTrigger(cardIndex, module));

   return NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
AD_DisplayFifoStatus illustrates which of the following flags have been raised:
   Sample Done, FIFO Full, High Limit, Low Limit, Empty.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t AD_DisplayFifoStatus(int32_t paramCount, int32_t* p_params)
{
   uint32_t modid, modver, modrev, special, boardgen;
   nai_ad_fifo_status_t fifoStatus;
   int32_t MAX_CHANNELS;
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t channel = p_ad_params->channel;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   naibrd_GetModuleInfo(cardIndex, module, &modid, &modver, &modrev, &special);
   naibrd_GetBoardGen(cardIndex, &boardgen);
   MAX_CHANNELS = naibrd_AD_GetChannelCount(modid);

   printf( "\n\n\n" );
   if ( NAI_XILINX_GEN5_ID == boardgen )
   {
      uint16_t SampleDone, FifoFull, HiLimit, LoLimit, Empty, AlmostEmpty, AlmostFull;

      printf( "| Ch | Status Register| Sample Done | FIFO Full | Hi Limit | Lo Limit | Empty | Almost | Almost |\n" );
      printf( "|    |   (hex value)  |             |           |          |          |       | empty  |  full  |\n" );
      printf( "|----|----------------|-------------|-----------|----------|----------|-------|--------|--------|\n" );

      for ( channel = 1; channel <= MAX_CHANNELS; channel++ )
      {
         naibrd_AD_GetFIFOStatus(cardIndex,  module,  channel, NAI_AD_FIFO_STATUS_REALTIME, &fifoStatus);

         Empty = (NAI_AD_GEN5_FIFO_STATUS_EMPTY == (fifoStatus & NAI_AD_GEN5_FIFO_STATUS_EMPTY));
         AlmostEmpty = (NAI_AD_GEN5_FIFO_STATUS_ALMOSTEMPTY == (fifoStatus & NAI_AD_GEN5_FIFO_STATUS_ALMOSTEMPTY));
         LoLimit = (NAI_AD_GEN5_FIFO_STATUS_LOWMARK == (fifoStatus & NAI_AD_GEN5_FIFO_STATUS_LOWMARK));
         HiLimit = (NAI_AD_GEN5_FIFO_STATUS_HIGHMARK == (fifoStatus & NAI_AD_GEN5_FIFO_STATUS_HIGHMARK));
         AlmostFull = (NAI_AD_GEN5_FIFO_STATUS_ALMOSTFULL == (fifoStatus & NAI_AD_GEN5_FIFO_STATUS_ALMOSTFULL));
         FifoFull = (NAI_AD_GEN5_FIFO_STATUS_FULL == (fifoStatus & NAI_AD_GEN5_FIFO_STATUS_FULL));
         SampleDone = (NAI_AD_GEN5_FIFO_STATUS_DONE == (fifoStatus & NAI_AD_GEN5_FIFO_STATUS_DONE));

         printf( "| %2d |     0x%02X       |      %d      |     %d     |    %d     |    %d     |   %d   |   %d    |   %d    |\n",
            channel, fifoStatus, SampleDone, FifoFull, HiLimit, LoLimit, Empty, AlmostEmpty, AlmostFull );
      }
   }
   else
   {
      uint16_t SampleDone, FifoFull, HiLimit, LoLimit, Empty;

      printf( "| Ch | Status Register| Sample Done | FIFO Full | Hi Limit | Lo Limit | Empty |\n" );
      printf( "|    |   (hex value)  |             |           |          |          |       |\n" );
      printf( "|----|----------------|-------------|-----------|----------|----------|-------|\n" );

      for ( channel = 1; channel <= MAX_CHANNELS; channel++ )
      {
         naibrd_AD_GetFIFOStatus(cardIndex,  module,  channel, NAI_AD_FIFO_STATUS_REALTIME, &fifoStatus);

         Empty = (NAI_AD_GEN3_FIFO_STATUS_EMPTY == (fifoStatus & NAI_AD_GEN3_FIFO_STATUS_EMPTY));
         LoLimit = (NAI_AD_GEN3_FIFO_STATUS_LOW == (fifoStatus & NAI_AD_GEN3_FIFO_STATUS_LOW));
         HiLimit = (NAI_AD_GEN3_FIFO_STATUS_HIGH == (fifoStatus & NAI_AD_GEN3_FIFO_STATUS_HIGH));
         FifoFull = (NAI_AD_GEN3_FIFO_STATUS_FULL == (fifoStatus & NAI_AD_GEN3_FIFO_STATUS_FULL));
         SampleDone = (NAI_AD_GEN3_FIFO_STATUS_DONE == (fifoStatus & NAI_AD_GEN3_FIFO_STATUS_DONE));

         printf( "| %2d |     0x%02X       |      %d      |     %d     |    %d     |    %d     |   %d   |\n",
            channel, fifoStatus, SampleDone, FifoFull, HiLimit, LoLimit, Empty );
      }
   }

   return NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
AD_ClearFifo empties the specified channel's FIFO buffer.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t AD_ClearFifo(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t channel = p_ad_params->channel;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
   check_status(naibrd_AD_ClearFIFO(cardIndex, module, channel));
   return NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
AD_ReadFifo handles the user request to read a certain number of samples from the FIFO.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t AD_ReadFifo(int32_t paramCount, int32_t* p_params)
{
   uint32_t count, samplesInFifo, samplesToRead;
   bool_t BufferControls[BUFFER_OPTIONS] = {FALSE, FALSE, FALSE, FALSE};
   uint32_t modid, modver, modrev, special;
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t channel = p_ad_params->channel;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   naibrd_GetModuleInfo( cardIndex, module, &modid, &modver, &modrev, &special);
   naibrd_AD_GetFIFOCount(cardIndex, module, channel, &count);
   if (count == 0)
   {
      printf("FIFO buffer is empty! No words to read!\n");
      return NAI_ERROR_UNKNOWN;
   }
   GetSamplesInFifo(cardIndex, module, channel, count, &samplesInFifo);
   GetBufferControls(cardIndex, module, channel, BufferControls);
   do
   {
      printf( "\nHow many samples would you like to read from the FIFO? Enter\n" );
      printf( "a number less than or equal to %d:\n>>", samplesInFifo);
      AD_getInput(&samplesToRead);
   } while (samplesToRead == 0 || (samplesToRead > samplesInFifo));

   PrintSamplesInFifo(cardIndex, module, channel, samplesToRead, BufferControls);
   return NAI_SUCCESS;
}
static void GetSamplesInFifo(int32_t cardIndex, int32_t module, int32_t channel, uint32_t count, uint32_t *samplesInFifo)
{
   uint32_t wordsPerSample = 0, bufferCtrl, boardgen;

   naibrd_AD_GetFIFOCtrl(cardIndex, module, channel, &bufferCtrl);
   naibrd_GetBoardGen(cardIndex, &boardgen);

   if ( NAI_XILINX_GEN5_ID == boardgen )
   {
      wordsPerSample = 1;

      if ((bufferCtrl & NAI_AD_FIFO_CTRL_TIMESTAMP) == NAI_AD_FIFO_CTRL_TIMESTAMP)
         wordsPerSample++;
   }
   else
   {
      if ((bufferCtrl & NAI_AD_FIFO_CTRL_TIMESTAMP) == NAI_AD_FIFO_CTRL_TIMESTAMP)
         wordsPerSample++;
      if ((bufferCtrl & NAI_AD_FIFO_CTRL_8BIT) == NAI_AD_FIFO_CTRL_8BIT)
         wordsPerSample++;
      if ((bufferCtrl & NAI_AD_FIFO_CTRL_16BIT) == NAI_AD_FIFO_CTRL_16BIT)
         wordsPerSample++;
   }

   if ( 0 != wordsPerSample )
      *samplesInFifo = count / wordsPerSample;
   else
      printf( "BufferControl is %d, which is an illegal value! Please re-enter a value for BufferControl via the CFG selection.\n",
         bufferCtrl);
}
static void GetBufferControls(int32_t cardIndex, int32_t module, int32_t channel, bool_t BufferControls[])
{
   uint32_t bufferCtrl;
   naibrd_AD_GetFIFOCtrl(cardIndex, module, channel, &bufferCtrl);

   if ((bufferCtrl & NAI_AD_FIFO_CTRL_TIMESTAMP) == NAI_AD_FIFO_CTRL_TIMESTAMP)
      BufferControls[TIME_STAMP] = TRUE;
   if ((bufferCtrl & NAI_AD_FIFO_CTRL_8BIT) == NAI_AD_FIFO_CTRL_8BIT)
      BufferControls[DATA_8BIT] = TRUE;
   if ((bufferCtrl & NAI_AD_FIFO_CTRL_16BIT) == NAI_AD_FIFO_CTRL_16BIT)
      BufferControls[DATA_16BIT] = TRUE;
}
static void PrintSamplesInFifo(int32_t cardIndex, int32_t module, int32_t channel, uint32_t samplesToRead, bool_t Buffer_Controls[])
{
   uint32_t modid, modver, modrev, special, boardgen;
   float64_t range;
   nai_ad_range_mode_t mode;
   nai_ad_range_t RawRange;

   naibrd_GetModuleInfo(cardIndex, module, &modid, &modver, &modrev, &special);
   naibrd_GetBoardGen(cardIndex, &boardgen);

   naibrd_AD_GetRange(cardIndex, module, channel, &mode, &range);
   naibrd_AD_ConvertToVoltageRangeRaw(modid, mode, range, &RawRange);
   printf( "DATA\t\tVOLTAGE\t\t" );
   if(Buffer_Controls[TIME_STAMP])
      printf( "TIME_STAMP" );
   printf("\n");
   do
   {
      float64_t Voltage = 0;
      uint32_t Data16Hi = 0, Data8Lo = 0;
      uint32_t read, Data = 0;

      if (Buffer_Controls[DATA_16BIT] && Buffer_Controls[DATA_8BIT])
      {
         naibrd_AD_ReadFIFORaw32(cardIndex, module, channel, 1, &Data16Hi, &read);
         naibrd_AD_ReadFIFORaw32(cardIndex, module, channel, 1, &Data8Lo, &read);
         Data = (Data16Hi << 16) | Data8Lo;
         naibrd_AD_ConvertToVoltage(modid, RawRange, Data, &Voltage);
      }
      else if ( Buffer_Controls[DATA_16BIT] || (NAI_XILINX_GEN5_ID == boardgen) )
      {
         naibrd_AD_ReadFIFORaw32(cardIndex, module, channel, 1, &Data16Hi, &read);
         Data = Data16Hi;
         naibrd_AD_ConvertToVoltage(modid, RawRange, Data, &Voltage);
      }
      printf("0x%08X\t%+7.6f\t", Data, Voltage);
      if (Buffer_Controls[TIME_STAMP])
      {
         naibrd_AD_ReadFIFORaw32(cardIndex, module, channel, 1, &Data16Hi, &read);
         printf(" %d ", Data16Hi);
      }
      printf("\n");
      samplesToRead--;
   } while (samplesToRead > 0);
}
static bool_t AD_getInput(uint32_t *value)
{
      int8_t sUserInput[15];

      memset( sUserInput, 0x00, sizeof( sUserInput ) );
      fgets( (char *)sUserInput, sizeof(sUserInput), stdin);
      if ('\n' != sUserInput[0])
      {
         sscanf((const char*)sUserInput, "%d", value);
         return TRUE;
      }
      else
         return FALSE;
}
static void printRangeRequest()
{
    printf( "\nPlease select the range an polarity for this channel. Refer to the table\n" );
    printf( "  below for valid values: \n\n");
    printf( "                          BIT  | D4 | D3 | D2 | D1 | D0 |\n" );
    printf( "MODULE |   C4  |   C2  |   C1  |    |    |    |    |    |  Bipolar/Unipolar\n" );
    printf( "-----------------------------------------------------------------------------\n");
    printf( "RANGE  | 50.0V | 40.0V |   N/A |  * |  1 |  0 |  1 | 0  | (decimal: 26/10)\n" );
    printf( "       | 25.0V | 20.0V |   N/A |  * |  1 |  0 |  0 | 1  | (decimal: 25/9)\n" );
    printf( "       | 12.5V | 10.0V | 10.0V |  * |  0 |  0 |  0 | 0  | (decimal: 16/0)\n" );
    printf( "       | 6.25V | 5.00V | 5.00V |  * |  0 |  0 |  0 | 1  | (decimal: 17/1)\n" );
    printf( "       |   N/A |   N/A | 2.50V |  * |  0 |  0 |  1 | 0  | (decimal: 18/2)\n" );
    printf( "       |   N/A |   N/A | 1.25V |  * |  0 |  0 |  1 | 1  | (decimal: 19/3)\n" );
    printf( "-----------------------------------------------------------------------------\n");
    printf( "  KA  |   AD4  |   AD5 |  AD6  |    |    |    |    |    | \n");
    printf( "-----------------------------------------------------------------------------\n");
    printf( "  N/A |   N/A |    N/A |  N/A  |  * |  1 |  0 |  1 | 0  | (decimal: 26/10)\n");
    printf( "  N/A |   N/A |    N/A |  N/A  |  * |  1 |  0 |  0 | 1  | (decimal: 25/9)\n" );
    printf( "10.00 | 10.00 |  50.00 |100.00 |  * |  0 |  0 |  0 | 0  | (decimal: 16/0)\n" );
    printf( " 5.00 |  5.00 |  25.00 | 50.00 |  * |  0 |  0 |  0 | 1  | (decimal: 17/1)\n" );
    printf( "  N/A |  2.50 |  12.50 | 25.00 |  * |  0 |  0 |  1 | 0  | (decimal: 18/2)\n" );
    printf( "  N/A |  1.25 |   6.25 | 12.50 |  * |  0 |  0 |  1 | 1  | (decimal: 19/3)\n" );
    printf( "-----------------------------------------------------------------------------\n");
    printf( "\n\n * For bipolar/unipolar selection, program D4 as '0' for unipolar and '1' for\n     bipolar\n\n" );
    printf( "Please enter in decimal (26,10,25,9,16,0,17,1,18,2,19,3) [default=16]: \n>>");
}
static void printBufferRequest(int32_t cardIndex)
{
   uint32_t boardgen;

   naibrd_GetBoardGen(cardIndex, &boardgen);
   if ( NAI_XILINX_GEN5_ID == boardgen )
   {
      printf( "\nPlease enter a value for the Buffer Control register. Refer to the\n" );
      printf( "bit-map table below:\n\n" );
      printf( "B0 = Reserved\n" );
      printf( "B1 = Reserved\n" );
      printf( "B2 = Filter. Filter Data (1) or Unfiltered data (0)\n" );
      printf( "B3 = Reserved\n" );
      printf( "B4 = Time Stamp. An integer counter that counts from 0 to 65,535 and wraps\n" );
      printf( "       around when it overflows.\n" );
      printf( "B5 = Reserved\n" );
      printf( "B6 = Reserved\n" );
      printf( "B7 = Reserved\n" );
      printf( "\nPlease enter the Buffer Control (0,4,16,20 ?) [default=0]:\n>>");
   }
   else
   {
      printf( "\nPlease enter a value for the Buffer Control register. Refer to the\n" );
      printf( "bit-map table below:\n\n" );
      printf( "B0 = Data (16 Bit Hi). 16 bit resolution data for unipolar and bipolar.\n" );
      printf( "B1 = Data (8 Bit Lo). Combine with B0 to form a 24 bit resolution for unipolar\n" );
      printf( "       and bipolar data.\n" );
      printf( "B2 = Filter. Filter Data (1) or Unfiltered data (0)\n" );
      printf( "B3 = Reserved\n" );
      printf( "B4 = Time Stamp. An integer counter that counts from 0 to 65,535 and wraps\n" );
      printf( "       around when it overflows.\n" );
      printf( "B5 = Reserved\n" );
      printf( "B6 = Reserved\n" );
      printf( "B7 = Reserved\n" );
      printf( "\nPlease enter the Buffer Control (1,3,5,7,16,17,19,21,23 ?) [default=1]:\n>>");
   }
}
static void printTriggerCtrlRequest(int32_t cardIndex)
{
   uint32_t boardgen;

   naibrd_GetBoardGen(cardIndex, &boardgen);
   if ( NAI_XILINX_GEN5_ID == boardgen )
   {
      printf( "\nTrigger Control- Please refer to the bit map below:\n\n" );
      printf( "B0-B1 = Trigger Type (choose one only)\n" );
      printf( "   0xXXX0 = Continuos\n" );
      printf( "   0xXXX1 = Single Sample\n" );
      printf( "B2-B3 = Reserved\n" );
      printf( "B4-B5 = Trigger Edge (Choose one only)\n" );
      printf( "   0xXX0X = RESERVED for Hardware Trigger (Positive Edge)\n" );
      printf( "   0xXX1X = RESERVED for Hardware Trigger (Negative Edge)\n" );
      printf( "   0xXX2X = RESERVED for Hardware Trigger (Either Edge)\n" );
      printf( "   0xXX3X = Software Trigger\n" );
      printf( "B6-B7 = Reserved\n" );
      printf( "B8 = Trigger Enable (choose one only)\n" );
      printf( "   0xX0XX = Disable/Stop Trigger\n" );
      printf( "   0xX1XX = Enable\n" );
      printf( "B9-B31 = Reserved\n" );

      printf( "\nBy default, we will set the Trigger Control to:\n" );
      printf( "304 (0x0130) - Single Sample | Software Trigger | Enable.");
      printf( "Press 'Enter' to continue or enter a new value in decimal.\n" );
   }
   else
   {
      printf( "\nTrigger Control- Please refer to the bit map below:\n\n" );
      printf( "B0-B1 = Source Select (choose one only)\n" );
      printf( "   0x00 = Ext. Trigger 2\n" );
      printf( "   0x01 = Ext. Trigger 1\n" );
      printf( "   0x02 = Software Trigger\n" );
      printf( "B3 = Reserved\n" );
      printf( "B4-B7 = Trigger Type (Choose one only)\n" );
      printf( "   0x10 = Negative Slope\n" );
      printf( "   0x20 = Trigger Pulse Enable\n" );
      printf( "   0x40 = Trigger Pulse/Trigger Enable Select\n" );
      printf( "   0x80 = Trigger Clear\n" );
      printf( "\nBy defualt, we will set the Trigger Control to:\n" );
      printf( "34 (0x22) - Software Trigger. Press 'Enter' to continue or enter a new value in decimal.\n" );
   }
}

Help Bot

X