TTL Measure
Edit this on GitLab
TTL Measure Sample Application (SSK 2.x)
Overview
The TTL Measure sample application demonstrates how to use the enhanced FIFO-based measurement modes on TTL (Transistor-Transistor Logic) 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 TTL 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 TTL 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. This application also supports configurable debounce time to filter out noise on input signals.
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: TL1, TL2.
For detailed register-level information, consult the TL1 Manual.
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with a supported TTL module installed (TL1 or TL2).
-
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 TTL channel in output mode, or any system-level digital signal).
How to Run
Launch the ttl_measure executable from your build output directory. On startup the application looks for a configuration file (default_TTL_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, configure debounce, and stop measurement.
Board Connection and Module Selection
|
Note
|
This startup sequence is common to all NAI sample applications. 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. On VxWorks, the entry point is TTL_Measure() instead.
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t TTL_Measure(void)
#else
int32_t main(void)
#endif
{
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
bool_t stop = NAI_FALSE;
uint32_t moduleID;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == (bool_t)NAI_TRUE)
{
while (stop != NAI_TRUE)
{
/* Select Card Index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), DEF_TTL_CARD_INDEX, &cardIndex);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Select Module */
stop = naiapp_query_ModuleNumber(moduleCnt, DEF_TTL_MODULE, &module);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
if ((moduleID != 0))
{
Run_TTL_FIFO(cardIndex, module, moduleID);
naiif_printf("\r\nType Q to quit or Enter to continue:\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;
}
Unlike the DT Measure sample, this application does not explicitly check for specific module IDs before entering the measurement flow. Instead, the module is validated inside Run_TTL_FIFO() by calling naibrd_TTL_GetChannelCount(). If the channel count is zero, the module is rejected with an error message.
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Command Loop
After selecting a channel, the application enters a command loop with these operations:
| 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 FIFO element count |
R |
Clear all FIFO data |
Debounce |
Set debounce time for the selected channel |
FIFO Mode Selection
To configure a measurement mode on a TTL channel, set the enhanced mode, clear stale data, and enable the enhanced trigger. The sample’s Configure_TTL_FIFO_Mode() function demonstrates this three-step sequence for each mode:
/* Step 1: Set the enhanced mode */
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan,
NAIBRD_TTL_MODE_MEASURE_HIGH_TIME));
/* Step 2: Clear old data from the FIFO */
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
/* Step 3: Enable the enhanced trigger to start measurement */
check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan,
NAIBRD_TTL_ENABLE));
The mode constants map to ten measurement types:
| Mode | Constant | What it measures | Category |
|---|---|---|---|
1 |
|
Duration the signal stays high (rising edge to falling edge). Each FIFO entry is one high-pulse width in hardware time units. |
Timing |
2 |
|
Duration the signal stays low (falling edge to rising edge). Each FIFO entry is one low-pulse width. |
Timing |
3 |
|
Absolute time of each rising edge. The FIFO fills with a sequence of timestamps for low-to-high transitions. |
Timestamp |
4 |
|
Absolute time of each falling edge. The FIFO fills with timestamps for high-to-low transitions. |
Timestamp |
5 |
|
Absolute time of every edge (both rising and falling). Useful for capturing complete signal activity. |
Timestamp |
6 |
|
Running total of rising edges since the counter was cleared. Stored in a counter register, not the FIFO. |
Counting |
7 |
|
Running total of falling edges since the counter was cleared. Stored in a counter register, not the FIFO. |
Counting |
8 |
|
Running total of all edges (rising + falling). Stored in a counter register, not the FIFO. |
Counting |
9 |
|
Time between consecutive rising edges (one full signal period). Each FIFO entry represents one period measurement. |
Timing |
10 |
|
Number of rising edges counted within a user-defined gating interval. With a 1000 ms interval, the count equals the frequency in Hz. |
Counting (interval) |
Counting Modes (6-8): Counter vs. FIFO
Modes 6, 7, and 8 use a dedicated counter register instead of the FIFO. The counter accumulates edge counts continuously until cleared. When switching to one of these modes, clear the counter with naibrd_TTL_ClearCountData() rather than naibrd_TTL_ClearFIFO():
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan,
NAIBRD_TTL_MODE_COUNT_RISING_EDGES));
check_status(naibrd_TTL_ClearCountData(cardIndex, module, chan));
check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan,
NAIBRD_TTL_ENABLE));
To read the current count value, call naibrd_TTL_GetCountData(). The FIFO count (naibrd_TTL_GetFIFOCount()) does not apply to these modes.
Mode 10: Interval Counting
Mode 10 gates the count over a user-defined time interval. At the end of each interval, the hardware writes the accumulated edge count as a FIFO entry and begins a new counting window. The sample calls Configure_TTL_Counter_Interval() to set the interval before starting:
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan,
NAIBRD_TTL_MODE_MEASURE_FREQUENCY));
check_status(Configure_TTL_Counter_Interval(APP_PARAM_COUNT,
(int32_t*)dtParams));
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan,
NAIBRD_TTL_ENABLE));
When the interval is set to 1000 ms, each FIFO entry directly represents the signal frequency in Hz.
Interval Configuration
To configure the gating interval for mode 10, call naibrd_TTL_SetTimebaseInterval(). The interval is specified in milliseconds:
check_status(naibrd_TTL_SetTimebaseInterval(cardIndex, module, chan,
interval));
The valid range depends on the module’s timebase LSB, which is the smallest time increment the hardware can represent. The sample retrieves this value with naibrd_TTL_GetTimebaseLSB() and computes the valid range:
lsb = naibrd_TTL_GetTimebaseLSB(ModuleID);
min = (float64_t)(0x2u * lsb);
max = (float64_t)(0xFFFFFFFF * lsb);
The minimum interval is 2 * LSB (the hardware requires at least two timebase ticks). The maximum interval is 0xFFFFFFFF * LSB, which is the largest value that fits in the 32-bit interval register. If the user enters a value outside this range, the sample rejects it and prints the valid bounds.
Debounce Configuration
The debounce time filters out noise on the input signal by ignoring transitions shorter than the specified duration. This is especially important for TTL signals in electrically noisy environments — without debounce, contact bounce or signal ringing can cause false edge detections that corrupt measurement data.
check_status(naibrd_TTL_SetDebounceTime(cardIndex, module, chan, time));
The debounce time is specified in milliseconds. The valid range uses the same LSB-based calculation as the interval configuration:
lsb = naibrd_TTL_GetTimebaseLSB(ModuleID);
min = (float64_t)(0x0u * lsb); /* 0 = debounce disabled */
max = (float64_t)(0xFFFFFFFE * lsb);
Setting the debounce time to zero disables debounce filtering. After setting, the sample reads back and confirms the value with naibrd_TTL_GetDebounceTime() to verify the hardware accepted the requested value.
Display Functions
Channel Configuration Display
Each time the command loop iterates, Display_TTL_ChannelCfg() prints a status summary for the selected channel. It queries four pieces of state from the hardware:
-
FIFO status — whether the FIFO is empty, full, almost empty, almost full, or contains data (via
naibrd_TTL_GetFIFOEventMappedStatusRaw()). -
Element count — how many entries are currently in the FIFO (via
naibrd_TTL_GetFIFOCount()). -
Enhanced mode — which measurement mode is active (via
naibrd_TTL_GetEnhancedMode()). -
Timebase interval — the gating interval, displayed only when mode 10 is active (via
naibrd_TTL_GetTimebaseInterval()).
For counting modes (6-8), the display also reads and shows the current counter value with naibrd_TTL_GetCountData().
FIFO Status
The Get_TTL_FIFO_Status() function reads the FIFO status register:
check_status(naibrd_TTL_GetFIFOEventMappedStatusRaw(cardIndex, module,
chan, NAI_STATUS_REALTIME, NAIBRD_TTL_EVENT_MAP_FIFO, &fifoStatus));
Status values include: NAIBRD_TTL_EVENT_STATUS_FIFO_EMPTY, NAIBRD_TTL_EVENT_STATUS_FIFO_FULL, NAIBRD_TTL_EVENT_STATUS_FIFO_ALMOST_EMPTY, and NAIBRD_TTL_EVENT_STATUS_FIFO_ALMOST_FULL. A status value of zero means the FIFO has data but is between the almost-empty and almost-full thresholds.
Starting and Stopping Measurement
Reading FIFO Data
The Get_TTL_FIFO_Data() function first checks how many elements are available, then reads them:
check_status(naibrd_TTL_GetFIFOCount(cardIndex, module, chan,
&numberOfElements));
check_status(naibrd_TTL_ReadFIFO(cardIndex, module, chan, count, timeout,
outdata, &numberOfElements, &countRemaining));
The user can choose how many entries to read, or press Enter to read all available entries. Each FIFO entry is a raw 32-bit value printed in hexadecimal. The interpretation of the value depends on the active mode — for timing modes it represents a duration in hardware time units, for timestamp modes it represents an absolute time, and for mode 10 it represents an edge count within the gating interval.
After reading, the function reports how many items remain in the FIFO.
Troubleshooting Reference
| Symptom | Possible Cause and Resolution |
|---|---|
Module not recognized as TTL |
|
Measurement does not start |
The enhanced trigger must be enabled after setting the mode. Call |
Stale data in FIFO after mode change |
Always clear the FIFO ( |
FIFO full, data lost |
The FIFO has a finite depth. High-frequency signals fill it quickly. Read or clear the FIFO frequently to avoid overflow. Monitor the status with |
Invalid mode number |
Only values 1-10 are valid. The application prints an error for any other value. |
Interval out of range (mode 10) |
The valid range is computed from the module’s timebase LSB: minimum is |
Debounce has no effect |
Verify the debounce time is within the valid range for the module. Read back the value with |
Count value does not update (modes 6-8) |
For counting modes 6-8, read the count with |
Full Source
Full Source — ttl_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_ttl.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 *DEF_CONFIG_FILE = (const int8_t *)"default_TTL_Measure.txt";
/* Function prototypes */
static void Verify_TTL_ParamCnt(int32_t paramCnt);
static int32_t Run_TTL_FIFO(int32_t cardIndex, int32_t module, uint32_t modid);
void Cfg_TTL_FIFO_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
static void Display_TTL_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan);
static nai_status_t Configure_TTL_Counter_Interval(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_TTL_FIFO_Mode(int32_t paramCnt, int32_t* p_params);
static nai_status_t Get_TTL_FIFO_Data(int32_t paramCnt, int32_t* p_params);
static nai_status_t Get_TTL_FIFO_Status(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_TTL_Debounce(int32_t paramCnt, int32_t* p_params);
static const int32_t DEF_TTL_CARD_INDEX = 0;
static const int32_t DEF_TTL_MODULE = 1;
static const int32_t DEF_TTL_CHANNEL = 1;
/****** Command Table *******/
enum ttl_fifo_commands
{
TTL_FIFO_CMD_MODE,
TTL_FIFO_CMD_GET_DATA,
TTL_FIFO_CMD_FIFO_FREQ,
TTL_FIFO_CMD_STATUS,
TTL_FIFO_CMD_FIFO_START,
TTL_FIFO_CMD_FIFO_STOP,
TTL_FIFO_CMD_COUNT,
TTL_FIFO_CMD_FIFO_CLEAR,
TTL_CMD_DEBOUNCE,
TTL_FIFO_CMD_LAST
};
/****** Command Tables *******/
static naiapp_cmdtbl_params_t TTL_FIFO_MenuCmds[] = {
{"Mode", "TTL Select FIFO Mode", TTL_FIFO_CMD_MODE, Configure_TTL_FIFO_Mode},
{"Disp", "TTL Display FIFO Data", TTL_FIFO_CMD_GET_DATA, Get_TTL_FIFO_Data},
{"Intv", "TTL Set Counter Interval", TTL_FIFO_CMD_FIFO_FREQ, Configure_TTL_Counter_Interval},
{"Stat", "TTL Display FIFO Status", TTL_FIFO_CMD_STATUS, Get_TTL_FIFO_Status},
{"Go", "TTL Start FIFO/Clear count", TTL_FIFO_CMD_FIFO_START, NULL},
{"STOP", "TTL Stop Measurement", TTL_FIFO_CMD_FIFO_STOP, NULL},
{"Count", "TTL Display FIFO Count", TTL_FIFO_CMD_COUNT, NULL},
{"R", "TTL Clear FIFO", TTL_FIFO_CMD_FIFO_CLEAR, NULL},
{"Debounce", "TTL Set debounce time", TTL_CMD_DEBOUNCE, Configure_TTL_Debounce}
};
/**************************************************************************************************************/
/**
* <summary>
* The purpose of the TTL_Measure is to illustrate the methods to call in the naibrd library to perform basic
* operations with the discrete modules for configuration setup, controlling the drive outputs, 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 (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t TTL_Measure(void)
#else
int32_t main(void)
#endif
{
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
bool_t stop = NAI_FALSE;
uint32_t moduleID;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == (bool_t)NAI_TRUE)
{
while (stop != NAI_TRUE)
{
/* Select Card Index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), DEF_TTL_CARD_INDEX, &cardIndex);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Select Module */
stop = naiapp_query_ModuleNumber(moduleCnt, DEF_TTL_MODULE, &module);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
if ((moduleID != 0))
{
Run_TTL_FIFO(cardIndex, module, moduleID);
naiif_printf("\r\nType Q to quit or Enter to continue:\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>
* Verify_TTL_ParamCnt verifies parameter count and displays error message if invalid.
* </summary>
*/
/**************************************************************************************************************/
static void Verify_TTL_ParamCnt(int32_t paramCnt)
{
if (paramCnt != APP_PARAM_COUNT)
{
naiif_printf(" *** Parameter count specified is incorrect!!! ***\r\n");
}
}
/**************************************************************************************************************/
/**
* <summary>
* Run_TTL_FIFO prompts the user for the card, module and channel to use for the application and calls
* Cfg_TTL_Channel if the card, module, channel is valid for as a discrete module.
* </summary>
*/
/**************************************************************************************************************/
static int32_t Run_TTL_FIFO(int32_t cardIndex, int32_t module, uint32_t modid)
{
bool_t bQuit = NAI_FALSE;
int32_t maxchannel;
if (!bQuit)
{
maxchannel = naibrd_TTL_GetChannelCount(modid);
if (maxchannel == 0)
{
naiif_printf(" *** Module selection not recognized as DT module. ***\r\n\r\n");
}
else
{
Cfg_TTL_FIFO_Channel(cardIndex, module, modid, maxchannel);
}
}
return cardIndex;
}
/**************************************************************************************************************/
/**
<summary>
Cfg_TTL_FIFO_Channel handles calling the Display_TTL_ChannelCfg routine to display the discrete channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
void Cfg_TTL_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 outcount;
naiapp_AppParameters_t dtparams;
p_naiapp_AppParameters_t dtParams = &dtparams;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
while (bContinue)
{
naiif_printf("\r\n\r\n");
naiif_printf("Channel selection\r\n");
naiif_printf("=================\r\n");
defaultchan = DEF_TTL_CHANNEL;
bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &chan);
dtParams->cardIndex = cardIndex;
dtParams->module = module;
dtParams->channel = chan;
naiapp_utils_LoadParamMenuCommands(TTL_FIFO_CMD_LAST, TTL_FIFO_MenuCmds);
while (bContinue)
{
Display_TTL_ChannelCfg(cardIndex, module, chan);
naiapp_display_ParamMenuCommands((int8_t *)"TTL PWM Operation Menu");
naiif_printf("\r\nType DT command or %c to quit : ", 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 TTL_FIFO_CMD_MODE:
case TTL_FIFO_CMD_GET_DATA:
case TTL_FIFO_CMD_FIFO_FREQ:
case TTL_FIFO_CMD_STATUS:
case TTL_CMD_DEBOUNCE:
TTL_FIFO_MenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)dtParams);
break;
case TTL_FIFO_CMD_FIFO_START:
check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
break;
case TTL_FIFO_CMD_FIFO_STOP:
check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_DISABLE));
naiif_printf("Measurement stopped\r\n");
break;
case TTL_FIFO_CMD_COUNT:
check_status(naibrd_TTL_GetFIFOCount(cardIndex, module, chan, &outcount));
naiif_printf("Count is %d\r\n", outcount);
break;
case TTL_FIFO_CMD_FIFO_CLEAR:
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
naiif_printf("Cleared\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_TTL_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for measurement operation.
</summary>
*/
/**************************************************************************************************************/
static void Display_TTL_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan)
{
float64_t interval = 0.0;
int32_t numberOfElements = 0;
uint32_t fifoStatus = 0;
naibrd_ttl_enhanced_mode_t opmode = 0;
int32_t outcount = 0;
check_status(naibrd_TTL_GetFIFOEventMappedStatusRaw(cardIndex, module, chan, NAI_STATUS_REALTIME, NAIBRD_TTL_EVENT_MAP_FIFO, &fifoStatus));
check_status(naibrd_TTL_GetFIFOCount(cardIndex, module, chan, &numberOfElements));
check_status(naibrd_TTL_GetEnhancedMode(cardIndex, module, chan, &opmode));
check_status(naibrd_TTL_GetTimebaseInterval(cardIndex, module, chan, &interval));
naiif_printf("\r\n === Channel %d ===\r\n", chan);
/*read DT FIFO configuration values here, Status, number of elements, interval, and mode */
{
naiif_printf(" Status Count interval Value Mode Selection\r\n");
naiif_printf("--------- ------ ----------- ------- --------------------------------\r\n");
}
/*display configuration settings here- */
switch (fifoStatus)
{
case 0:
naiif_printf(" Data ");
break;
case (uint32_t)NAIBRD_TTL_EVENT_STATUS_FIFO_EMPTY:
naiif_printf(" Empty ");
break;
case (uint32_t)NAIBRD_TTL_EVENT_STATUS_FIFO_FULL:
naiif_printf(" Full ");
break;
case (uint32_t)NAIBRD_TTL_EVENT_STATUS_FIFO_ALMOST_EMPTY:
naiif_printf(" Almost Empty ");
break;
case (uint32_t)NAIBRD_TTL_EVENT_STATUS_FIFO_ALMOST_FULL:
naiif_printf(" Almost 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(" ");
/* if opcode is 6,7,or 8 display the counter value */
if ((opmode > 5) && (opmode < 9))
{
check_status(naibrd_TTL_GetCountData(cardIndex, module, chan, &outcount));
naiif_printf("%7d ", outcount);
}
else
naiif_printf(" ");
switch (opmode)
{
case NAIBRD_TTL_MODE_STD_INPUT_OUTPUT:
naiif_printf(" DT MODE STD INPUT OUTPUT ");
break;
case NAIBRD_TTL_MODE_MEASURE_HIGH_TIME:
naiif_printf(" DT MODE MEASURE HIGH TIME ");
break;
case NAIBRD_TTL_MODE_MEASURE_LOW_TIME:
naiif_printf(" DT MODE MEASURE LOW TIME ");
break;
case NAIBRD_TTL_MODE_TIMESTAMP_RISING_EDGES:
naiif_printf(" DT MODE TIMESTAMP RISING EDGES ");
break;
case NAIBRD_TTL_MODE_TIMESTAMP_FALLING_EDGES:
naiif_printf(" DT MODE TIMESTAMP FALLING EDGES ");
break;
case NAIBRD_TTL_MODE_TIMESTAMP_ALL_EDGES:
naiif_printf(" DT MODE TIMESTAMP ALL EDGES ");
break;
case NAIBRD_TTL_MODE_COUNT_RISING_EDGES:
naiif_printf(" DT MODE COUNT RISING EDGES ");
break;
case NAIBRD_TTL_MODE_COUNT_FALLING_EDGES:
naiif_printf(" DT MODE COUNT FALLING EDGES ");
break;
case NAIBRD_TTL_MODE_COUNT_ALL_EDGES:
naiif_printf(" DT MODE COUNT ALL EDGES ");
break;
case NAIBRD_TTL_MODE_MEASURE_PERIOD_RISING_EDGE:
naiif_printf(" DT MODE MEASURE PERIOD FROM RISING EDGE ");
break;
case NAIBRD_TTL_MODE_MEASURE_FREQUENCY:
naiif_printf(" DT MODE Interval Counter ");
break;
case NAIBRD_TTL_MODE_OUTPUT_PWM_FOREVER:
naiif_printf(" DT MODE PWM Continuous ");
break;
case NAIBRD_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES:
naiif_printf(" DT MODE PWM Burst ");
break;
case NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM:
naiif_printf(" DT MODE PATTERN RAM ");
break;
default:
naiif_printf(" Unknown ");
break;
}
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_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>
*/
/**************************************************************************************************************/
static nai_status_t Configure_TTL_FIFO_Mode(int32_t paramCnt, int32_t* p_params)
{
nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
bool_t bQuit = NAI_FALSE;
uint32_t selection = 0;
p_naiapp_AppParameters_t dtParams = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = dtParams->cardIndex;
int32_t module = dtParams->module;
int32_t chan = dtParams->channel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
Verify_TTL_ParamCnt(paramCnt);
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");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
selection = atoi((const char *)inputBuffer);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
if (selection == 1)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_MEASURE_HIGH_TIME));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else if (selection == 2)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_MEASURE_LOW_TIME));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else if (selection == 3)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_TIMESTAMP_RISING_EDGES));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else if (selection == 4)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_TIMESTAMP_FALLING_EDGES));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else if (selection == 5)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_TIMESTAMP_ALL_EDGES));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else if (selection == 6)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_COUNT_RISING_EDGES));
/* clear old count value since we are changing modes */
check_status(naibrd_TTL_ClearCountData(cardIndex, module, chan));
/* now start the counter in the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else if (selection == 7)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_COUNT_FALLING_EDGES));
/* clear old count value since we are changing modes */
check_status(naibrd_TTL_ClearCountData(cardIndex, module, chan));
/* now start the counter in the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else if (selection == 8)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_COUNT_ALL_EDGES));
/* clear old count value since we are changing modes */
check_status(naibrd_TTL_ClearCountData(cardIndex, module, chan));
/* now start the counter in the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else if (selection == 9)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_MEASURE_PERIOD_RISING_EDGE));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else if (selection == 10)
{
check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_MEASURE_FREQUENCY));
/* Set the interval */
check_status(Configure_TTL_Counter_Interval(APP_PARAM_COUNT, (int32_t*)dtParams));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_TTL_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_TTL_ENABLE));
}
else
{
naiif_printf("Invalid mode %d\r\n", selection);
}
}
}
return status;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_Counter_Interval will configure DT module gating interval for measurement of counts within the user
defined interval.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_TTL_Counter_Interval(int32_t paramCnt, 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;
nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
p_naiapp_AppParameters_t dtParams = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = dtParams->cardIndex;
int32_t module = dtParams->module;
int32_t chan = dtParams->channel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
Verify_TTL_ParamCnt(paramCnt);
naiif_printf("\r\nEnter the desired interval in ms (Enter 1000 for direct frequency reading): ");
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_TTL_GetTimebaseLSB(ModuleID);
min = (float64_t)(0x2u * lsb);
max = (float64_t)(0xFFFFFFFF * lsb);
if (interval > max || interval < min)
naiif_printf(" Entry out of range. Range %7.3f to %7.3f ms\r\n", min, max);
else
{
status = check_status(naibrd_TTL_SetTimebaseInterval(cardIndex, module, chan, interval));
}
}
}
return status;
}
/**************************************************************************************************************/
/**
<summary>
Get_TTL_FIFO_Data reads back the data on the FIFO.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Get_TTL_FIFO_Data(int32_t paramCnt, int32_t* p_params)
{
nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
int32_t numberOfElements, timeout, count, countRemaining, i;
uint32_t outdata[512];
bool_t bQuit = NAI_FALSE;
p_naiapp_AppParameters_t dtParams = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = dtParams->cardIndex;
int32_t module = dtParams->module;
int32_t chan = dtParams->channel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
Verify_TTL_ParamCnt(paramCnt);
timeout = (0xFFFFFFFFu);
/* First check how many elements are on the FIFO */
check_status(naibrd_TTL_GetFIFOCount(cardIndex, module, chan, &numberOfElements));
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;
status = check_status(naibrd_TTL_ReadFIFO(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 status;
}
/**************************************************************************************************************/
/**
<summary>
Get_TTL_FIFO_Status will read back the value of the counter if the FIFO is configured for
* opmode 6,7, or 8.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Get_TTL_FIFO_Status(int32_t paramCnt, int32_t* p_params)
{
nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
uint32_t fifoStatus;
p_naiapp_AppParameters_t dtParams = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = dtParams->cardIndex;
int32_t module = dtParams->module;
int32_t chan = dtParams->channel;
Verify_TTL_ParamCnt(paramCnt);
check_status(naibrd_TTL_GetFIFOEventMappedStatusRaw(cardIndex, module, chan, NAI_STATUS_REALTIME, NAIBRD_TTL_EVENT_MAP_FIFO, &fifoStatus));
switch (fifoStatus)
{
case 0:
naiif_printf("NAIBRD_TTL_EVENT_STATUS_FIFO_BTWN_ALMOST_EMPTY_FULL_REALTIME\r\n");
break;
case (uint32_t)NAIBRD_TTL_EVENT_STATUS_FIFO_EMPTY:
naiif_printf("NAIBRD_TTL_EVENT_STATUS_FIFO_EMPTY\r\n");
break;
case (uint32_t)NAIBRD_TTL_EVENT_STATUS_FIFO_FULL:
naiif_printf("NAIBRD_TTL_EVENT_STATUS_FIFO_FULL\r\n");
break;
case (uint32_t)NAIBRD_TTL_EVENT_STATUS_FIFO_ALMOST_EMPTY:
naiif_printf("NAIBRD_TTL_EVENT_STATUS_FIFO_ALMOST_EMPTY\r\n");
break;
case (uint32_t)NAIBRD_TTL_EVENT_STATUS_FIFO_ALMOST_FULL:
naiif_printf("NAIBRD_TTL_EVENT_STATUS_FIFO_ALMOST_FULL\r\n");
break;
default:
naiif_printf("Unknown");
break;
}
return status;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_Debounce handles the user request to configure the values for debounce time on the selected
channel and calls the method in the naibrd library to set the debounce.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_TTL_Debounce(int32_t paramCnt, int32_t* p_params)
{
nai_status_t status = NAI_ERROR_UNKNOWN;
bool_t bQuit = NAI_FALSE;
float64_t time = 0.0;
float64_t lsb = 0;
float64_t min = 1;
float64_t max = -1;
uint32_t ModuleID;
p_naiapp_AppParameters_t dtParams = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = dtParams->cardIndex;
int32_t module = dtParams->module;
int32_t chan = dtParams->channel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
Verify_TTL_ParamCnt(paramCnt);
naiif_printf("\r\nEnter the desired debounce time in milliseconds: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
naibrd_GetModuleName(cardIndex, module, &ModuleID);
time = atof((const char *)inputBuffer);
lsb = naibrd_TTL_GetTimebaseLSB(ModuleID);
min = (float64_t)(0x0u * lsb);
max = (float64_t)(0xFFFFFFFE * lsb);
if (time > max || time < min)
naiif_printf(" Entry out of range. Range %12.6f to %12.6f ms\r\n", min, max);
else
{
status = check_status(naibrd_TTL_SetDebounceTime(cardIndex, module, chan, time));
}
}
check_status(naibrd_TTL_GetDebounceTime(cardIndex, module, chan, &time));
if (status == NAI_SUCCESS)
naiif_printf("Debounce set to %12.6f milliseconds\r\n", time);
}
return status;
}