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

DIF Measure

DIF Measure Sample Application (SSK 2.x)

Overview

The DIF Measure sample application demonstrates how to use the enhanced FIFO-based measurement modes on DIF (Differential Input Function) channels using the NAI Software Support Kit (SSK 2.x). It serves as a practical API reference for building your own digital signal measurement and timing analysis functionality with NAI hardware.

While basic DIF I/O lets you poll a channel’s current high/low state at a single instant, FIFO-based measurement is fundamentally different. The FPGA on the DIF module continuously monitors incoming signals, detects edges, and records timing data into a per-channel FIFO buffer without host intervention. Your application reads those FIFO entries later to extract pulse widths, periods, frequencies, edge timestamps, or edge counts. This means you can capture signal characteristics that would be impossible to measure by polling — sub-microsecond pulse widths, precise edge-to-edge timing, and accurate frequency counts over defined intervals.

The application supports ten measurement modes, grouped into three categories:

  • Timing modes (modes 1-2, 9) — the hardware measures durations: how long the signal stays high, how long it stays low, or the full period between rising edges. Each measurement is stored as a FIFO entry in hardware time units.

  • Timestamp modes (modes 3-5) — the hardware records the exact time at which each rising edge, falling edge, or any edge occurs. The FIFO fills with a sequence of timestamps, giving you a complete record of when every transition happened.

  • Counting modes (modes 6-8, 10) — the hardware counts rising edges, falling edges, or all edges. Modes 6-8 accumulate counts in a dedicated register rather than the FIFO. Mode 10 (interval counting) gates the count over a user-defined time window, effectively measuring frequency.

Supported modules: DF1, DF2, DF3, and combination module CMH.

For the SSK 1.x version, see DIF Measure (SSK 1.x).

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a supported DIF module installed (DF1, DF2, DF3, or CMH).

  • SSK 2.x installed on your development host.

  • The sample applications built. Refer to the SSK 2.x Software Development Guide for platform-specific build instructions.

  • A digital signal source connected to the channel you want to measure (function generator, another DIF channel in output mode, or any system-level digital signal).

How to Run

Launch the dif_measure executable from your build output directory. On startup the application looks for a configuration file (default_DIF_Measure.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, select a channel, and the application presents a measurement operations menu where you select a FIFO mode, start measurement, read FIFO data, check status, and stop measurement.

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 DIF. For details on board connection configuration, see the SSK 2.x Software Development Guide.

The main() function follows a standard SSK 2.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_DIF_Measure.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_GetModuleName() so downstream code can verify the module is a supported DIF type.

#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t DIF_FIFO(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = NAI_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) == NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(),
            DEF_DIF_CARD_INDEX, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt,
               DEF_DIF_MODULE, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module,
                  &moduleID));
               if ((moduleID != 0))
               {
                  Run_DIF_FIFO(cardIndex, module, moduleID);
               }
            }
         }

         naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer),
            NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   naiapp_access_CloseAllOpenCards();
   return 0;
}

Note the SSK 2.x differences from SSK 1.x in this startup sequence:

  • The VxWorks preprocessor guard uses NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS (SSK 1.x uses __VXWORKS__).

  • The module identifier is retrieved with naibrd_GetModuleName() (SSK 1.x uses naibrd_GetModuleID()).

  • Boolean constants are NAI_TRUE / NAI_FALSE (SSK 1.x uses TRUE / FALSE).

  • Console output uses naiif_printf() from the platform abstraction layer (SSK 1.x uses printf() directly).

After retrieving the module ID, the application passes it to Run_DIF_FIFO(), which validates that the module is a recognized DIF type by calling naibrd_DIF_GetChannelCount(). If the channel count is zero, the module is rejected:

void Run_DIF_FIFO(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
   int32_t MaxChannel;

   MaxChannel = naibrd_DIF_GetChannelCount(ModuleID);

   if (MaxChannel == 0)
   {
      naiif_printf(
         " *** Module selection not recognized as DIF module. ***\r\n\r\n");
   }
   else
   {
      Cfg_DIF_FIFO_Channel(cardIndex, module, ModuleID, MaxChannel);
   }
}

In your own application, use naibrd_GetModuleName() and naibrd_DIF_GetChannelCount() to confirm that a module slot contains a supported DIF module before attempting any measurement operations.

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 — the card index is zero-based; the module number is one-based. Ensure the values you pass match your hardware setup.

  • Module not recognized as DIF — naibrd_DIF_GetChannelCount() returned zero. The slot does not contain a DF1, DF2, DF3, or CMH module. Use the board menu to verify which slots are populated.

Program Structure

Entry Point

On standard platforms (Petalinux, DEOS) the entry point is main(). On VxWorks the entry point is DIF_FIFO() — the SSK 2.x build system selects the correct variant via a preprocessor guard:

#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t DIF_FIFO(void)
#else
int32_t main(void)
#endif

The startup flow is the same in both cases:

  1. Attempt to load the saved configuration file via naiapp_RunBoardMenu(CONFIG_FILE). If the file does not yet exist, the interactive board menu is presented instead.

  2. Enter a loop that queries for card index and module slot.

  3. Validate the module with naibrd_DIF_GetChannelCount() and, if valid, enter Cfg_DIF_FIFO_Channel() for the interactive measurement session.

  4. On exit, close all open board connections with naiapp_access_CloseAllOpenCards().

Application Parameters

The Cfg_DIF_FIFO_Channel() function populates an naiapp_AppParameters_t struct that is passed to every command handler. Your application will need to track these same values to identify which board, module, and channel you are targeting:

naiapp_AppParameters_t  dif_params;
p_naiapp_AppParameters_t dif_measure_params = &dif_params;
dif_measure_params->cardIndex = cardIndex;
dif_measure_params->module = module;
dif_measure_params->modId = ModuleID;
dif_measure_params->channel = chan;
  • cardIndex — identifies which board in a multi-board system.

  • module — the slot number where the DIF module is installed.

  • modId — the module identifier returned by naibrd_GetModuleName(). Used by API functions to apply module-specific behavior.

  • channel — the currently selected channel for measurement operations.

Command Loop

After selecting a channel, the application enters a command loop. On each iteration it displays the current channel configuration via Display_DIF_ChannelCfg(), prints the command menu, and dispatches the user’s selection to the matching handler function:

naiapp_utils_LoadParamMenuCommands(DIF_FIFO_CMD_LAST, DIF_FIFO_MenuCmds);
while (bContinue)
{
   Display_DIF_ChannelCfg(cardIndex, module, chan, ModuleID);
   naiapp_display_ParamMenuCommands(
      (int8_t *)"DIF Measurement Operations Menu");
   naiif_printf("\r\nType DIF command or %c to quit :\r\n > ",
      NAI_QUIT_CHAR);
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer),
      NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         bCmdFound = naiapp_utils_GetParamMenuCmdNum(
            inputResponseCnt, inputBuffer, &cmd);
         if (bCmdFound)
         {
            DIF_FIFO_MenuCmds[cmd].func(APP_PARAM_COUNT,
               (int32_t*)dif_measure_params);
         }
      }
   }
   else
      bContinue = NAI_FALSE;
}

The available commands are registered in the DIF_FIFO_MenuCmds[] table:

Command Description

Mode

Select the FIFO measurement mode (1-10)

Disp

Read and display FIFO data entries

Intv

Set the counter interval for mode 10 (frequency measurement)

Stat

Display current FIFO status (empty, full, element count)

Go

Start FIFO measurement / clear edge count

STOP

Stop measurement and disable enhanced trigger

Count

Display the edge counter value (modes 6-8)

R

Clear all FIFO data

The menu-driven structure is a convenience of the sample application. In your own application, you would call the same underlying naibrd_DIF_*() API functions directly — for example, calling naibrd_DIF_SetOpMode() and naibrd_DIF_SetEnhanceTriggerEnable() instead of navigating to the "Mode" and "Go" menu commands.

FIFO Mode Selection

This is the central operation of the sample. To configure a measurement mode on a DIF channel, you set the operating mode, clear stale data, and enable the enhanced trigger.

Selecting a Measurement Mode

To set a measurement mode in your own application, call naibrd_DIF_SetOpMode() with the desired mode constant, then clear the FIFO (or counter) and enable the enhanced trigger to begin capturing data.

The sample’s Configure_DIF_FIFO_Mode() function demonstrates the three-step sequence that applies to every mode:

/* Step 1: Set the operating mode */
check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan,
   NAIBRD_DIF_MODE_MEASURE_HIGH_TIME));

/* Step 2: Clear old data from the FIFO */
check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));

/* Step 3: Enable the enhanced trigger to start measurement */
check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan,
   NAIBRD_DIF_ENHANCE_OP_ENABLE));

The mode constants map to ten measurement types:

Mode Constant Category

1

NAIBRD_DIF_MODE_MEASURE_HIGH_TIME

Timing

2

NAIBRD_DIF_MODE_MEASURE_LOW_TIME

Timing

3

NAIBRD_DIF_MODE_TIMESTAMP_RISING_EDGES

Timestamp

4

NAIBRD_DIF_MODE_TIMESTAMP_FALLING_EDGES

Timestamp

5

NAIBRD_DIF_MODE_TIMESTAMP_ALL_EDGES

Timestamp

6

NAIBRD_DIF_MODE_COUNT_RISING_EDGES

Counting

7

NAIBRD_DIF_MODE_COUNT_FALLING_EDGES

Counting

8

NAIBRD_DIF_MODE_COUNT_ALL_EDGES

Counting

9

NAIBRD_DIF_MODE_MEASURE_PERIOD_FROM_RISING_EDGE

Timing

10

NAIBRD_DIF_MODE_MEASURE_FREQUENCY

Counting (interval)

Counting Modes (6-8): Counter vs. FIFO

Modes 6, 7, and 8 use a dedicated counter register instead of the FIFO. When switching to one of these modes, clear the counter with naibrd_DIF_ClearCountData() instead of naibrd_DIF_ClearFIFO():

/* Set mode to count rising edges */
check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan,
   NAIBRD_DIF_MODE_COUNT_RISING_EDGES));

/* Clear the counter, not the FIFO */
check_status(naibrd_DIF_ClearCountData(cardIndex, module, chan));

/* Enable enhanced trigger to start counting */
check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan,
   NAIBRD_DIF_ENHANCE_OP_ENABLE));

To read the accumulated count at any time, call naibrd_DIF_GetCountData():

uint32_t outcount;
check_status(naibrd_DIF_GetCountData(cardIndex, module, chan, &outcount));
naiif_printf("Count is %d\r\n", outcount);

Mode 10: Interval Counting (Frequency Measurement)

Mode 10 extends counting by gating the count over a user-defined time interval. This effectively measures frequency: if you set the interval to 1000 ms, the count value equals the number of edges per second.

When selecting mode 10, the sample sets the operating mode, then calls Configure_DIF_Counter_Interval() to configure the gating interval before clearing the FIFO and enabling measurement:

check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan,
   NAIBRD_DIF_MODE_MEASURE_FREQUENCY));

/* Set the interval -- see next section */
check_status(Configure_DIF_Counter_Interval(paramCount, p_params));

check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));
check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan,
   NAIBRD_DIF_ENHANCE_OP_ENABLE));
Important

Common Errors

  • Invalid mode number — only values 1-10 are valid. Values outside this range are rejected by the sample with an "Invalid mode" message. In your own code, pass only the defined NAIBRD_DIF_MODE_* constants.

  • Stale FIFO data — always clear the FIFO (or counter) when changing modes. Old entries from a previous mode will produce meaningless values if not cleared.

  • Measurement does not start — the enhanced trigger must be enabled after setting the mode. Calling naibrd_DIF_SetOpMode() alone does not begin data capture.

Interval Configuration

To configure the gating interval for mode 10 in your own application, call naibrd_DIF_SetTimebaseInterval(). The interval is specified in milliseconds. Setting it to 1000 ms causes the counter to count edges for exactly one second, so the result directly represents frequency in Hz.

float64_t interval = 1000.0; /* 1000 ms = direct frequency reading */
check_status(naibrd_DIF_SetTimebaseInterval(cardIndex, module, chan,
   interval));

The valid interval range is module-specific. The sample retrieves the timebase LSB for the detected module using naibrd_DIF_GetTimebaseLSB() and computes the valid range:

float64_t lsb = naibrd_DIF_GetTimebaseLSB(ModuleID);
/* For DF2: min = 2 * lsb, max = 0xFFFFFFFF * lsb */

Consult your module’s manual for the exact timebase resolution and supported interval range: DF1 Manual, DF2 Manual.

Important

Common Errors

  • Interval out of range — the minimum and maximum interval values depend on the module’s timebase LSB. If your value falls outside the valid range, the write may be clamped or rejected. Always retrieve the LSB with naibrd_DIF_GetTimebaseLSB() and validate before writing.

  • Mode 10 not selected — the interval register only applies to NAIBRD_DIF_MODE_MEASURE_FREQUENCY. Setting it has no effect in other modes.

Starting and Stopping Measurement

Start Measurement

To start measurement on a channel in your own application, call naibrd_DIF_SetEnhanceTriggerEnable() with NAIBRD_DIF_ENHANCE_OP_ENABLE. The channel must already have a valid operating mode set via naibrd_DIF_SetOpMode().

check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan,
   NAIBRD_DIF_ENHANCE_OP_ENABLE));

The "Go" command in the sample calls this function directly. Note that the "Mode" command also enables the trigger automatically as part of the mode selection sequence — this means you do not need to issue a separate "Go" command after selecting a mode.

Stop Measurement

To stop measurement, call naibrd_DIF_SetEnhanceTriggerEnable() with NAIBRD_DIF_ENHANCE_OP_DISABLE:

nai_status_t status;
status = check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex,
   module, chan, NAIBRD_DIF_ENHANCE_OP_DISABLE));
if (status == NAI_SUCCESS)
   naiif_printf("Measurement stopped, mode reset\r\n");

Stopping measurement disables the enhanced trigger. The FIFO retains any data that was captured before the stop — you can still read it with naibrd_DIF_ReadFIFORawEx(). To discard the captured data, explicitly clear the FIFO after stopping.

Reading FIFO Data

To read measurement data from the FIFO in your own application, first check the FIFO status to determine how many entries are available, then read the entries with naibrd_DIF_ReadFIFORawEx().

Check FIFO Status

Call naibrd_DIF_GetFIFOStatus() to retrieve the current element count and status flag:

uint32_t numberOfElements = 0;
naibrd_dif_fifo_status_t fifoStatus = 0;

check_status(naibrd_DIF_GetFIFOStatus(cardIndex, module, chan,
   &numberOfElements, &fifoStatus));

The status flag indicates the FIFO fill level:

Status Constant Meaning

NAIBRD_DIF_FIFO_STATUS_EMPTY

FIFO contains no entries

NAIBRD_DIF_FIFO_STATUS_ALMOST_EMPTY

FIFO has a small number of entries

NAIBRD_DIF_FIFO_STATUS_BTWN_ALMOST_EMPTY_FULL

FIFO is partially filled

NAIBRD_DIF_FIFO_STATUS_ALMOST_FULL

FIFO is nearly full

NAIBRD_DIF_FIFO_STATUS_FULL

FIFO is full — new entries may be lost

Read FIFO Entries

Call naibrd_DIF_ReadFIFORawEx() to retrieve raw data from the FIFO. The function reads up to the requested number of entries and reports how many remain:

uint32_t count = numberOfElements;   /* read all available entries */
uint32_t outdata[512];
uint32_t countRemaining;
uint32_t timeout = 0xFFFFFFFFu;

check_status(naibrd_DIF_ReadFIFORawEx(cardIndex, module, chan,
   count, timeout, outdata, &numberOfElements, &countRemaining));

for (uint32_t i = 0; i < count; i++)
{
   naiif_printf("FIFO element %d 0x%x\r\n", i, outdata[i]);
}
naiif_printf("%d items left in the FIFO\r\n", countRemaining);
  • count — number of entries to read. If this exceeds the available entries, the function reads only what is available.

  • timeout — maximum wait time in hardware-defined ticks. The sample uses 0xFFFFFFFF for an effectively unlimited wait.

  • outdata — buffer to receive the raw 32-bit FIFO entries. Ensure this buffer is large enough for the requested count.

  • numberOfElements — on return, the actual number of entries read.

  • countRemaining — entries still in the FIFO after the read completes.

The raw data values represent different quantities depending on the active mode: time durations for timing modes, timestamps for timestamp modes, or counts for interval mode. Consult your module’s manual for the conversion from raw register values to engineering units: DF1 Manual, DF2 Manual.

Clear FIFO

To discard all entries in the FIFO, call naibrd_DIF_ClearFIFO():

check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));

Always clear the FIFO when switching between measurement modes. Stale entries from a previous mode produce meaningless data.

Important

Common Errors

  • FIFO full, data lost — if the FIFO reaches NAIBRD_DIF_FIFO_STATUS_FULL, new measurements may overwrite or discard the oldest entries (depending on module behavior). Read the FIFO frequently or clear it to avoid overflow.

  • Empty read — calling naibrd_DIF_ReadFIFORawEx() when the FIFO is empty returns zero entries. Always check naibrd_DIF_GetFIFOStatus() first to confirm data is available.

  • Buffer overrun — ensure your outdata buffer is at least as large as the count you request. The sample uses a 512-element buffer.

Channel Configuration Display

Each iteration of the command loop calls Display_DIF_ChannelCfg() to show the current state of the selected channel. This function reads back multiple configuration values and presents them in a summary line:

naibrd_dif_fifo_status_t fifoStatus = 0;
naibrd_dif_enhanced_mode_t opmode = (naibrd_dif_enhanced_mode_t)0;
uint32_t numberOfElements = 0;
float64_t interval = 0.0;
uint32_t outcount = 0;

check_status(naibrd_DIF_GetFIFOStatus(cardIndex, module, chan,
   &numberOfElements, &fifoStatus));
check_status(naibrd_DIF_GetOpMode(cardIndex, module, chan, &opmode));
check_status(naibrd_DIF_GetTimebaseInterval(cardIndex, module, chan,
   &interval));

The display includes:

  • FIFO status — the current fill state (empty, almost empty, between, almost full, full).

  • Element count — number of entries currently in the FIFO.

  • Interval — the timebase interval in milliseconds. Shown as "NA" for modes other than 10.

  • Counter value — the accumulated edge count. Shown only for counting modes 6-8, read via naibrd_DIF_GetCountData().

  • Enhanced mode — the currently selected measurement mode name.

In your own application, you can call these same readback functions — naibrd_DIF_GetFIFOStatus(), naibrd_DIF_GetOpMode(), naibrd_DIF_GetTimebaseInterval(), and naibrd_DIF_GetCountData() — to monitor channel state programmatically.

Troubleshooting Reference

Note
This section summarizes errors covered in the preceding sections and provides a quick-reference table. Consult your DIF module’s manual for hardware-specific diagnostics: DF1 Manual, DF2 Manual, CMH Manual.
Error / Symptom Possible Causes Suggested Resolution

No board found

Board not powered, incorrect interface type in configuration, physical connection issue.

Verify power and cabling. Re-run the board menu and confirm the interface and address settings.

Connection timeout

Network misconfiguration, firewall blocking traffic, incorrect board IP address.

Ping the board from the host. Check firewall rules. Confirm IP settings in the board menu.

Module not recognized as DIF

Selected slot does not contain a DF1, DF2, DF3, or CMH module. naibrd_DIF_GetChannelCount() returned zero.

Use the board menu to check which module types are installed in each slot.

Measurement does not start

Enhanced trigger not enabled after setting the operating mode.

Call naibrd_DIF_SetEnhanceTriggerEnable() with NAIBRD_DIF_ENHANCE_OP_ENABLE after naibrd_DIF_SetOpMode().

FIFO returns stale or meaningless data

FIFO was not cleared before changing measurement modes.

Always call naibrd_DIF_ClearFIFO() (or naibrd_DIF_ClearCountData() for modes 6-8) when switching modes.

FIFO full, data lost

Application is not reading the FIFO frequently enough; signal frequency exceeds read rate.

Increase read frequency or clear the FIFO periodically. Consider using interrupt-driven reads for high-frequency signals.

Interval out of range

Value passed to naibrd_DIF_SetTimebaseInterval() exceeds the module’s valid range.

Retrieve the timebase LSB with naibrd_DIF_GetTimebaseLSB() and compute valid min/max before writing.

Counter value does not update

Operating mode is not set to a counting mode (6, 7, or 8). Counter register is only used in those modes.

Verify the mode with naibrd_DIF_GetOpMode(). Edge counts are only available in modes 6-8; mode 10 uses the FIFO.

Invalid mode number

A value outside 1-10 was passed.

Use only the defined NAIBRD_DIF_MODE_* constants.

Empty FIFO read

No signal transitions have occurred since measurement started, or FIFO was recently cleared.

Verify that a digital signal is connected and toggling on the selected channel. Check naibrd_DIF_GetFIFOStatus() before reading.

Full Source

Full Source — dif_measure.c (SSK 2.x)
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"

/* naibrd include files */
#include "nai_libs/naibrd/include/naibrd.h"
#include "nai_libs/naibrd/include/functions/naibrd_dif.h"

/* naiif include files */
#include "nai_libs/naiif/include/naiif_stdio.h"

/* Common Sample Program include files */
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_menu.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_query.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_access.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_display.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_utils.h"

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

/* Function prototypes */
void Run_DIF_FIFO(int32_t cardIndex, int32_t module, int32_t ModuleID);
void Cfg_DIF_FIFO_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);

static void Display_DIF_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID);
nai_status_t Configure_DIF_FIFO_Mode(int32_t paramCount, int32_t* p_params);
nai_status_t Start_DIF_FIFO(int32_t paramCount, int32_t* p_params);
nai_status_t Clear_DIF_FIFO(int32_t paramCount, int32_t* p_params);
nai_status_t Get_DIF_FIFO_Data(int32_t paramCount, int32_t* p_params);
nai_status_t Configure_DIF_Counter_Interval(int32_t paramCount, int32_t* p_params);
nai_status_t Get_DIF_FIFO_Status(int32_t paramCount, int32_t* p_params);
nai_status_t Get_DIF_FIFO_Count(int32_t paramCount, int32_t* p_params);

static const int32_t DEF_DIF_CARD_INDEX    = 0;
static const int32_t DEF_DIF_MODULE        = 1;
static const int32_t DEF_DIF_CHANNEL       = 1;

/****** Command Table *******/
enum dif_fifo_commands
{
   DIF_FIFO_CMD_MODE,
   DIF_FIFO_CMD_GET_DATA,
   DIF_FIFO_CMD_FIFO_FREQ,
   DIF_FIFO_CMD_STATUS,
   DIF_FIFO_CMD_FIFO_START,
   DIF_FIFO_CMD_FIFO_STOP,
   DIF_FIFO_CMD_COUNT,
   DIF_FIFO_CMD_FIFO_CLEAR,
   DIF_FIFO_CMD_LAST

};
/****** Command Tables *******/
naiapp_cmdtbl_params_t DIF_FIFO_MenuCmds[] = {
   {"Mode",          "DIF Select FIFO Mode",       DIF_FIFO_CMD_MODE,            Configure_DIF_FIFO_Mode},
   {"Disp",          "DIF Display FIFO Data",      DIF_FIFO_CMD_GET_DATA,        Get_DIF_FIFO_Data},
   {"Intv",          "DIF Set Counter Interval",   DIF_FIFO_CMD_FIFO_FREQ,       Configure_DIF_Counter_Interval},
   {"Stat",          "DIF Display FIFO Status",    DIF_FIFO_CMD_STATUS,          Get_DIF_FIFO_Status},
   {"Go",            "DIF Start FIFO/Clear count", DIF_FIFO_CMD_FIFO_START,      Start_DIF_FIFO},
   {"STOP",          "DIF Stop Measurement",       DIF_FIFO_CMD_FIFO_STOP,       NULL},
   {"Count",         "DIF Display FIFO Count",     DIF_FIFO_CMD_COUNT,           Get_DIF_FIFO_Count},
   {"R",             "DIF Clear FIFO",             DIF_FIFO_CMD_FIFO_CLEAR,      Clear_DIF_FIFO}
};

/**************************************************************************************************************/
/**
<summary>
The purpose of the DIF_FIFO is to illustrate the methods to call in the naibrd library to perform DIF enhanced
FIFO mode. This example code will configure DIF FIFO to desired mode, start, stop and display the DIF FIFO

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 DIF routines.
 - ClearDeviceCfg
 - QuerySystemCfg
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - SaveDeviceCfg
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t DIF_FIFO(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = NAI_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) == NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         /* Query the user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), DEF_DIF_CARD_INDEX, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Query the user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, DEF_DIF_MODULE, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               if ((moduleID != 0))
               {
                  Run_DIF_FIFO(cardIndex, module, moduleID);
               }
            }
         }

         naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   naiif_printf("\r\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();

   return 0;
}

/**************************************************************************************************************/
/**
<summary>
Run_DIF_FIFO prompts the user for the card, module and channel to use for the application and calls
Cfg_DIF_Channel if the card, module, channel is valid for as a discrete module.
</summary>
*/
/**************************************************************************************************************/
void Run_DIF_FIFO(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
   int32_t MaxChannel;

   MaxChannel = naibrd_DIF_GetChannelCount(ModuleID);

   if (MaxChannel == 0)
   {
      naiif_printf(" *** Module selection not recognized as DIF module. ***\r\n\r\n");
   }
   else
   {
      Cfg_DIF_FIFO_Channel(cardIndex, module, ModuleID, MaxChannel);
   }
}

/**************************************************************************************************************/
/**
<summary>
Cfg_DIF_FIFO_Channel handles calling the Display_DIF_ChannelCfg routine to display the discrete channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
void Cfg_DIF_FIFO_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel)
{
   bool_t bQuit = NAI_FALSE;
   bool_t bContinue = NAI_TRUE;
   bool_t bCmdFound = NAI_FALSE;
   int32_t chan, defaultchan = 1;
   int32_t cmd;
   int32_t status;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   naiapp_AppParameters_t  dif_params;
   p_naiapp_AppParameters_t dif_measure_params = &dif_params;
   dif_measure_params->cardIndex = cardIndex;
   dif_measure_params->module = module;
   dif_measure_params->modId = ModuleID;

   while (bContinue)
   {
      naiif_printf("    \r\r\n\r\r\n");
      naiif_printf("Channel selection \r\r\n");
      naiif_printf("================= \r\r\n");
      defaultchan = DEF_DIF_CHANNEL;
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &chan);
      dif_measure_params->channel = chan;

      naiapp_utils_LoadParamMenuCommands(DIF_FIFO_CMD_LAST, DIF_FIFO_MenuCmds);
      while (bContinue)
      {
         Display_DIF_ChannelCfg(cardIndex, module, chan, ModuleID);
         naiapp_display_ParamMenuCommands((int8_t *)"DIF Measurement Operations Menu");
         naiif_printf("\r\nType DIF command or %c to quit :\r\n > ", NAI_QUIT_CHAR);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
               if (bCmdFound)
               {
                  switch (cmd)
                  {
                        case DIF_FIFO_CMD_MODE:
                        case DIF_FIFO_CMD_FIFO_START:
                        case DIF_FIFO_CMD_FIFO_CLEAR:
                        case DIF_FIFO_CMD_GET_DATA:
                        case DIF_FIFO_CMD_FIFO_FREQ:
                        case DIF_FIFO_CMD_STATUS:
                        case DIF_FIFO_CMD_COUNT:
                              DIF_FIFO_MenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)dif_measure_params);
                        break;
                        case DIF_FIFO_CMD_FIFO_STOP:
                           {
                              status = check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_DISABLE));
                              if (status == NAI_SUCCESS)
                                 naiif_printf("Measurement stopped, mode reset\r\n");
                           }
                           break;
                     default:
                                 naiif_printf("Invalid command entered\r\n");
                        break;
                  }
               }
               else
                  naiif_printf("Invalid command entered\r\n");
            }
         }
         else
            bContinue = NAI_FALSE;
      }
   }
}

/**************************************************************************************************************/
/**
<summary>
Display_DIF_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for measurement operation.
</summary>
*/
/**************************************************************************************************************/
static void Display_DIF_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID)
{
   float64_t interval= 0.0;
   uint32_t numberOfElements = 0;
   naibrd_dif_fifo_status_t fifoStatus = 0;
   naibrd_dif_enhanced_mode_t opmode = (naibrd_dif_enhanced_mode_t)0;
   uint32_t outcount = 0;

   naibrd_GetModuleName(cardIndex, module, &ModuleID);
   check_status(naibrd_DIF_GetFIFOStatus( cardIndex, module, chan, &numberOfElements, &fifoStatus ));
   check_status(naibrd_DIF_GetOpMode(cardIndex, module, chan, &opmode));
   check_status(naibrd_DIF_GetTimebaseInterval( cardIndex, module, chan, &interval ));

   naiif_printf("\r\n === Channel %d ===\r\n\r\n", chan);

   /*read DIF FIFO configuration values here, Status, number of elements, interval, and mode */
   {
      naiif_printf("  Status          Count      Interval      Value     Enhanced Mode Selection\r\n");
      naiif_printf("-------------    -------   ---- mS -----   -------  ---------------------------\r\n");
   }

   /*display configuration settings here- */
   switch (fifoStatus)
   {
   case NAIBRD_DIF_FIFO_STATUS_ALMOST_EMPTY:
      naiif_printf(" FIFO almost Empty ");
      break;
   case NAIBRD_DIF_FIFO_STATUS_EMPTY:
      naiif_printf("  FIFO Empty  ");
      break;
   case NAIBRD_DIF_FIFO_STATUS_FULL:
      naiif_printf("  FIFO Full   ");
      break;
   case NAIBRD_DIF_FIFO_STATUS_ALMOST_FULL:
      naiif_printf(" FIFO Almost Full ");
      break;
   case NAIBRD_DIF_FIFO_STATUS_BTWN_ALMOST_EMPTY_FULL:
      naiif_printf(" FIFO Btwn Empty and Full ");
      break;
   default:
      naiif_printf("    Unknown   ");
      break;
   }

   /* display number of elements on FIFO */
   naiif_printf("     %3d  ", numberOfElements);

   /* if opcode is 10 display the interval */
   if( opmode == 10 )
         naiif_printf("%12.3f   ", interval);
   else
         naiif_printf("%12.3f NA", interval);

   /* if opcode is 6,7,or 8 display the counter value */
   if( (opmode > 5) && (opmode < 9) )
   {
      check_status(naibrd_DIF_GetCountData( cardIndex, module, chan, &outcount ));
      naiif_printf("%7d         ", outcount);
   }
   else
      naiif_printf("%7d NA      ", outcount);

   switch (opmode)
   {
   case NAIBRD_DIF_MODE_STD_INPUT_OUTPUT:
      naiif_printf("STD_INPUT_OUTPUT   ");
      break;
   case NAIBRD_DIF_MODE_MEASURE_HIGH_TIME:
      naiif_printf("MEASURE_HIGH_TIME   ");
      break;
   case NAIBRD_DIF_MODE_MEASURE_LOW_TIME:
      naiif_printf("MEASURE_LOW_TIME   ");
      break;
   case NAIBRD_DIF_MODE_TIMESTAMP_RISING_EDGES:
      naiif_printf("TIMESTAMP_RISING_EDGES   ");
      break;
   case NAIBRD_DIF_MODE_TIMESTAMP_FALLING_EDGES:
      naiif_printf("Record TIMESTAMP_FALLING_EDGES   ");
      break;
   case NAIBRD_DIF_MODE_TIMESTAMP_ALL_EDGES:
      naiif_printf("Record TIMESTAMP_ALL_EDGES   ");
      break;
   case NAIBRD_DIF_MODE_COUNT_RISING_EDGES:
      naiif_printf("MODE_COUNT_RISING_EDGES   ");
      break;
   case NAIBRD_DIF_MODE_COUNT_FALLING_EDGES:
      naiif_printf("MODE_COUNT_FALLING_EDGES   ");
      break;
   case NAIBRD_DIF_MODE_COUNT_ALL_EDGES:
      naiif_printf("MODE_COUNT_ALL_EDGES   ");
      break;
   case NAIBRD_DIF_MODE_MEASURE_PERIOD_FROM_RISING_EDGE:
      naiif_printf("MEASURE_PERIOD_FROM_RISING_EDGE   ");
      break;
   case NAIBRD_DIF_MODE_MEASURE_FREQUENCY:
      naiif_printf("Measure Interval Count ");
      break;
   case NAIBRD_DIF_MODE_OUTPUT_PWM_FOREVER:
      naiif_printf("Continuous PWM Output");
      break;
   case NAIBRD_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES:
      naiif_printf("Burst PWM Output");
      break;
   case NAIBRD_DIF_MODE_OUTPUT_PATTERN_RAM:
      naiif_printf("NAIBRD_DIF_MODE_OUTPUT_PATTERN_RAM   ");
      break;
   default:
      naiif_printf("Unknown    ");
      break;
   }
}

/**************************************************************************************************************/
/**
<summary>
Configure_DIF_FIFO_Mode handles the user request to select the FIFO mode for the selected channel
and calls the method in the naibrd library to set the mode.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_DIF_FIFO_Mode(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   uint32_t selection = 0;
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   naiif_printf("\r\n == FIFO Mode Selection == \r\n");
   naiif_printf(" 1 Measure high time\r\n");
   naiif_printf(" 2 Measure low time\r\n");
   naiif_printf(" 3 Timestamp of all rising edges\r\n");
   naiif_printf(" 4 Timestamp of all falling edges\r\n");
   naiif_printf(" 5 Timestamp of all edges\r\n");
   naiif_printf(" 6 Count total number of rising edges\r\n");
   naiif_printf(" 7 Count total number of falling edges\r\n");
   naiif_printf(" 8 Count total number of all edges\r\n");
   naiif_printf(" 9 Measure period from rising edge\r\n");
   naiif_printf("10 Measure Interval count / frequency\r\n");
   naiif_printf(" > ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   selection = atoi((const char *)inputBuffer);

   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
        /* Must be in enhanced mode to use DIF FIFO */
         if (selection == 1)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_MEASURE_HIGH_TIME));
            /* clear old data from FIFO since we are changing modes */
            check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));
            /* now start the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else if (selection == 2)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_MEASURE_LOW_TIME));
            /* clear old data from FIFO since we are changing modes */
            check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));
            /* now start the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else if (selection == 3)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_TIMESTAMP_RISING_EDGES));
            /* clear old data from FIFO since we are changing modes */
            check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));
            /* now start the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else if (selection == 4)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_TIMESTAMP_FALLING_EDGES));
            /* clear old data from FIFO since we are changing modes */
            check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));
            /* now start the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else if (selection == 5)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_TIMESTAMP_ALL_EDGES));
            /* clear old data from FIFO since we are changing modes */
            check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));
            /* now start the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else if (selection == 6)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_COUNT_RISING_EDGES));
            /* clear old count value since we are changing modes */
            check_status(naibrd_DIF_ClearCountData(cardIndex, module, chan));
            /* now start the counter in the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else if (selection == 7)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_COUNT_FALLING_EDGES));
            /* clear old count value since we are changing modes */
            check_status(naibrd_DIF_ClearCountData(cardIndex, module, chan));
            /* now start the counter in the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else if (selection == 8)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_COUNT_ALL_EDGES));
            /* clear old count value since we are changing modes */
            check_status(naibrd_DIF_ClearCountData(cardIndex, module, chan));
            /* now start the counter in the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else if (selection == 9)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_MEASURE_PERIOD_FROM_RISING_EDGE));
            /* clear old data from FIFO since we are changing modes */
            check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));
            /* now start the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else if (selection == 10)
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAIBRD_DIF_MODE_MEASURE_FREQUENCY));
            /* Set the interval */
            check_status(Configure_DIF_Counter_Interval(paramCount, p_params));
            /* clear old data from FIFO since we are changing modes */
            check_status(naibrd_DIF_ClearFIFO(cardIndex, module, chan));
            /* now start the FIFO */
            check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DIF_ENHANCE_OP_ENABLE));
         }
         else
         {
          naiif_printf("Invalid mode %d\r\n", selection);
       }
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Start_DIF_FIFO must be called in order to start the FIFO in a particular mode.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Start_DIF_FIFO(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   check_status(naibrd_DIF_SetEnhanceTriggerEnable(p_dif_params->cardIndex, p_dif_params->module, p_dif_params->channel, NAIBRD_DIF_ENHANCE_OP_ENABLE));
   return NAI_ERROR_UNKNOWN;
}

/**************************************************************************************************************/
/**
<summary>
Clear_DIF_FIFO should be called before naibrd_DIF_StartMeasurement to clear out old data.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Clear_DIF_FIFO(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   check_status(naibrd_DIF_ClearFIFO( p_dif_params->cardIndex, p_dif_params->module, p_dif_params->channel ));
   return NAI_ERROR_UNKNOWN;
}

/**************************************************************************************************************/
/**
<summary>
Get_DIF_FIFO_Data reads back the data on the FIFO.
</summary>
*/
/**************************************************************************************************************/

nai_status_t Get_DIF_FIFO_Data(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   uint32_t count, numberOfElements, i, countRemaining, timeout;
   uint32_t outdata[512];
   bool_t bQuit = NAI_FALSE;
   naibrd_dif_fifo_status_t outstatus;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   timeout = (0xFFFFFFFFu);

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

   /* First check how many elements are on the FIFO */
   check_status(naibrd_DIF_GetFIFOStatus( cardIndex, module, chan, &numberOfElements, &outstatus ));

      naiif_printf("\r\nThere is %d elements on FIFO, please enter number to display (Hit Enter for all):\r\n > ", numberOfElements);

      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);

      count = atoi((const char *)inputBuffer);

      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            count = atoi((const char *)inputBuffer);
            if( count > numberOfElements )
               count = numberOfElements;
            if( count < 0 )
               count = 0;
         }
         else
            count = numberOfElements;
            check_status(naibrd_DIF_ReadFIFORawEx(cardIndex, module, chan, count, timeout, outdata, &numberOfElements, &countRemaining));
            for (i = 0;i < count;i++)
            {
               naiif_printf("FIFO element %d 0x%x\r\n", i, outdata[i]);
            }
            if (count>0)
               naiif_printf("\r\n%d items left in the FIFO\r\n", countRemaining);
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DIF_Counter_Interval will configure DIF module gating interval for measurement of counts within the user defined interval.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_DIF_Counter_Interval(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   float64_t interval = 0.0;
   float64_t lsb = 0;
   float64_t min = 1;
   float64_t max = -1;
   uint32_t ModuleID;
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   naiif_printf("\r\nEnter the desired interval in ms \r\n(Enter 1000 for direct frequency reading):\r\n > ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         naibrd_GetModuleName(cardIndex, module, &ModuleID);
         interval = atof((const char *)inputBuffer); /*entry in milliseconds*/
         lsb = naibrd_DIF_GetTimebaseLSB(ModuleID);
         switch (ModuleID)
         {
         case NAIBRD_MODULE_ID_DF2:
            min =(float64_t)(0x2u * lsb);
            max =(float64_t)(0xFFFFFFFF * lsb);
         default:
               break;
         }
         if (interval > max || interval < min)
            naiif_printf(" Entry out of range.  Range %7.7f to %7.3f ms\r\n", min, max);
         else
         {
         check_status(naibrd_DIF_SetTimebaseInterval(cardIndex, module, chan, interval ));
         }
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Get_DIF_FIFO_Count will read back the value of the counter if the FIFO is configured for
* opmode 6,7, or 8.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Get_DIF_FIFO_Count(int32_t paramCount, int32_t* p_params)
{
   uint32_t outcount;
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;

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

   check_status(naibrd_DIF_GetCountData(p_dif_params->cardIndex, p_dif_params->module, p_dif_params->channel, &outcount ));
   naiif_printf("Count is %d\r\n",outcount);
   return NAI_ERROR_UNKNOWN;
}

/**************************************************************************************************************/
/**
<summary>
Get_DIF_FIFO_Status will read back the value of the counter if the FIFO is configured for
* opmode 6,7, or 8.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Get_DIF_FIFO_Status(int32_t paramCount, int32_t* p_params)
{
   uint32_t numberOfElements;
   naibrd_dif_fifo_status_t fifoStatus;
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;

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

   check_status(naibrd_DIF_GetFIFOStatus( cardIndex, module, chan, &numberOfElements, &fifoStatus ));
   switch (fifoStatus)
   {
   case NAIBRD_DIF_FIFO_STATUS_ALMOST_EMPTY:
      naiif_printf(" FIFO almost Empty ");
      break;
   case NAIBRD_DIF_FIFO_STATUS_EMPTY:
      naiif_printf("  FIFO Empty  ");
      break;
   case NAIBRD_DIF_FIFO_STATUS_FULL:
      naiif_printf("  FIFO Full   ");
      break;
   case NAIBRD_DIF_FIFO_STATUS_ALMOST_FULL:
      naiif_printf(" FIFO Almost Full ");
      break;
   case NAIBRD_DIF_FIFO_STATUS_BTWN_ALMOST_EMPTY_FULL:
      naiif_printf(" FIFO Btwn Empty and Full ");
      break;
   default:
      naiif_printf("    Unknown   ");
      break;
   }
   return NAI_ERROR_UNKNOWN;
}

Help Bot

X