DT Measure
Edit this on GitLab
DT Measure Sample Application (SSK 2.x)
Overview
The DT Measure sample application demonstrates how to use the enhanced FIFO-based measurement modes on DT (Discrete) 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 DT 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 DT 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 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.
-
Timestamp modes (modes 3-5) — the hardware records the exact time at which each rising edge, falling edge, or any edge occurs.
-
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. Mode 10 (interval counting) gates the count over a user-defined time window.
Supported modules: DT4, and combination modules CM1, CM2, CM8.
For detailed register-level information, consult the DT1 Manual.
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with a supported DT module installed (DT4, CM1, CM2, or CM8).
-
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 DT channel in output mode, or any system-level digital signal).
How to Run
Launch the dt_measure executable from your build output directory. On startup the application looks for a configuration file (default_DT_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:
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t DT_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)
{
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(),
DEF_DT_CARD_INDEX, &cardIndex);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
stop = naiapp_query_ModuleNumber(moduleCnt,
DEF_DT_MODULE, &module);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleName(cardIndex, module,
&moduleID));
if ((moduleID != 0))
{
if (moduleID == NAIBRD_MODULE_ID_DT4
|| moduleID == NAIBRD_MODULE_ID_CM1
|| moduleID == NAIBRD_MODULE_ID_CM2
|| moduleID == NAIBRD_MODULE_ID_CM8)
Run_DT_FIFO(cardIndex, module, moduleID);
else
naiif_printf("\r\nModule does have DT enhanced "
"functionality\r\n");
}
}
}
}
}
naiapp_access_CloseAllOpenCards();
return 0;
}
Note that this application explicitly checks for specific module IDs (NAIBRD_MODULE_ID_DT4, NAIBRD_MODULE_ID_CM1, NAIBRD_MODULE_ID_CM2, NAIBRD_MODULE_ID_CM8) before allowing enhanced measurement operations. Not all DT modules support the enhanced FIFO measurement feature set.
The module is further validated with naibrd_DT_GetChannelCount() in Run_DT_FIFO().
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Entry Point
On standard platforms the entry point is main(). On VxWorks the entry point is DT_Measure().
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 DT channel, set the enhanced mode, clear stale data, and enable the enhanced trigger. The sample’s Configure_DT_FIFO_Mode() function demonstrates this three-step sequence for each mode:
/* Step 1: Set the enhanced mode */
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan,
NAIBRD_DT_MODE_MEASURE_HIGH_TIME));
/* Step 2: Clear old data from the FIFO */
check_status(naibrd_DT_ClearFIFO(cardIndex, module, chan));
/* Step 3: Enable the enhanced trigger to start measurement */
check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan,
NAIBRD_DT_ENABLE));
The mode constants map to ten measurement types:
| Mode | Constant | Category |
|---|---|---|
1 |
|
Timing |
2 |
|
Timing |
3 |
|
Timestamp |
4 |
|
Timestamp |
5 |
|
Timestamp |
6 |
|
Counting |
7 |
|
Counting |
8 |
|
Counting |
9 |
|
Timing |
10 |
|
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_DT_ClearCountData():
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan,
NAIBRD_DT_MODE_COUNT_RISING_EDGES));
check_status(naibrd_DT_ClearCountData(cardIndex, module, chan));
check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan,
NAIBRD_DT_ENABLE));
Mode 10: Interval Counting
Mode 10 gates the count over a user-defined time interval. The sample calls Configure_DT_Counter_Interval() to set the interval before starting:
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan,
NAIBRD_DT_MODE_MEASURE_FREQUENCY));
check_status(Configure_DT_Counter_Interval(APP_PARAM_COUNT,
(int32_t*)dtParams));
check_status(naibrd_DT_ClearFIFO(cardIndex, module, chan));
check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan,
NAIBRD_DT_ENABLE));
Interval Configuration
To configure the gating interval for mode 10, call naibrd_DT_SetTimebaseInterval(). The interval is specified in milliseconds:
float64_t interval = 1000.0; /* 1000 ms = direct frequency reading */
check_status(naibrd_DT_SetTimebaseInterval(cardIndex, module, chan,
interval));
The valid range depends on the module’s timebase LSB, retrieved with naibrd_DT_GetTimebaseLSB().
Debounce Configuration
The debounce time filters out noise on the input signal by ignoring transitions shorter than the specified duration:
check_status(naibrd_DT_SetDebounceTime(cardIndex, module, chan, time));
The debounce time is specified in milliseconds. After setting, the sample reads back and confirms the value with naibrd_DT_GetDebounceTime().
Starting and Stopping Measurement
Reading FIFO Data
The Get_DT_FIFO_Data() function first checks how many elements are available, then reads them:
check_status(naibrd_DT_GetFIFOCount(cardIndex, module, chan,
&numberOfElements));
status = check_status(naibrd_DT_ReadFIFO(cardIndex, module, chan,
count, timeout, outdata, &numberOfElements, &countRemaining));
FIFO Status
The Get_DT_FIFO_Status() function reads the FIFO status register:
check_status(naibrd_DT_GetFIFOEventMappedStatusRaw(cardIndex, module,
chan, NAI_STATUS_REALTIME, NAIBRD_DT_EVENT_MAP_FIFO, &fifoStatus));
Status values include: NAIBRD_DT_EVENT_STATUS_FIFO_EMPTY, NAIBRD_DT_EVENT_STATUS_FIFO_FULL, NAIBRD_DT_EVENT_STATUS_FIFO_ALMOST_EMPTY, and NAIBRD_DT_EVENT_STATUS_FIFO_ALMOST_FULL.
Troubleshooting Reference
| Symptom | Possible Cause and Resolution |
|---|---|
Module does not have DT enhanced functionality |
Only DT4, CM1, CM2, and CM8 modules support enhanced FIFO modes. Check the module ID. |
Measurement does not start |
The enhanced trigger must be enabled after setting the mode. Call |
Stale data in FIFO |
Always clear the FIFO or counter when changing modes. |
FIFO full, data lost |
Read the FIFO frequently or clear it to avoid overflow. |
Invalid mode number |
Only values 1-10 are valid. |
Interval out of range |
Check the valid range using |
Debounce has no effect |
Verify the debounce time is within the valid range for the module. Read back with |
Count value does not update |
For modes 6-8, read with |
Full Source
Full Source — dt_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_dt.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_DT_Measure.txt";
/* Function prototypes */
static void Verify_DT_ParamCnt(int32_t paramCnt);
static int32_t Run_DT_FIFO(int32_t cardIndex, int32_t module, uint32_t modid);
void Cfg_DT_FIFO_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
static void Display_DT_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan);
static nai_status_t Configure_DT_Counter_Interval(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_DT_FIFO_Mode(int32_t paramCnt, int32_t* p_params);
static nai_status_t Get_DT_FIFO_Data(int32_t paramCnt, int32_t* p_params);
static nai_status_t Get_DT_FIFO_Status(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_DT_Debounce(int32_t paramCnt, int32_t* p_params);
static const int32_t DEF_DT_CARD_INDEX = 0;
static const int32_t DEF_DT_MODULE = 1;
static const int32_t DEF_DT_CHANNEL = 1;
static const int32_t DEF_DT_KA_CHANNEL = 13;
/****** Command Table *******/
enum dt_fifo_commands
{
DT_FIFO_CMD_MODE,
DT_FIFO_CMD_GET_DATA,
DT_FIFO_CMD_FIFO_FREQ,
DT_FIFO_CMD_STATUS,
DT_FIFO_CMD_FIFO_START,
DT_FIFO_CMD_FIFO_STOP,
DT_FIFO_CMD_COUNT,
DT_FIFO_CMD_FIFO_CLEAR,
DT_CMD_DEBOUNCE,
DT_FIFO_CMD_LAST
};
/****** Command Tables *******/
static naiapp_cmdtbl_params_t DT_FIFO_MenuCmds[] = {
{"Mode", "DT Select FIFO Mode", DT_FIFO_CMD_MODE, Configure_DT_FIFO_Mode},
{"Disp", "DT Display FIFO Data", DT_FIFO_CMD_GET_DATA, Get_DT_FIFO_Data},
{"Intv", "DT Set Counter Interval", DT_FIFO_CMD_FIFO_FREQ, Configure_DT_Counter_Interval},
{"Stat", "DT Display FIFO Status", DT_FIFO_CMD_STATUS, Get_DT_FIFO_Status},
{"Go", "DT Start FIFO/Clear count", DT_FIFO_CMD_FIFO_START, NULL},
{"STOP", "DT Stop Measurement", DT_FIFO_CMD_FIFO_STOP, NULL},
{"Count", "DT Display FIFO Count", DT_FIFO_CMD_COUNT, NULL},
{"R", "DT Clear FIFO", DT_FIFO_CMD_FIFO_CLEAR, NULL},
{"Debounce", "DT Set debounce time", DT_CMD_DEBOUNCE, Configure_DT_Debounce}
};
/**************************************************************************************************************/
/**
* <summary>
* The purpose of the DT_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 DT_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_DT_CARD_INDEX, &cardIndex);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Select Module */
stop = naiapp_query_ModuleNumber(moduleCnt, DEF_DT_MODULE, &module);
if (stop != NAI_TRUE)
{
check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
if ((moduleID != 0))
{
if(moduleID == NAIBRD_MODULE_ID_DT4 || moduleID == NAIBRD_MODULE_ID_CM1 || moduleID == NAIBRD_MODULE_ID_CM2 || moduleID == NAIBRD_MODULE_ID_CM8)
Run_DT_FIFO(cardIndex, module, moduleID);
else naiif_printf("\r\nModule does have DT enhanced functionality\r\n");
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_DT_ParamCnt verifies parameter count and displays error message if invalid.
* </summary>
*/
/**************************************************************************************************************/
static void Verify_DT_ParamCnt(int32_t paramCnt)
{
if (paramCnt != APP_PARAM_COUNT)
{
naiif_printf(" *** Parameter count specified is incorrect!!! ***\r\n");
}
}
/**************************************************************************************************************/
/**
* <summary>
* Run_DT_FIFO prompts the user for the card, module and channel to use for the application and calls
* Cfg_DT_Channel if the card, module, channel is valid for as a discrete module.
* </summary>
*/
/**************************************************************************************************************/
static int32_t Run_DT_FIFO(int32_t cardIndex, int32_t module, uint32_t modid)
{
bool_t bQuit = NAI_FALSE;
int32_t maxchannel;
if (!bQuit)
{
maxchannel = naibrd_DT_GetChannelCount(modid);
if (maxchannel == 0)
{
naiif_printf(" *** Module selection not recognized as DT module. ***\r\n\r\n");
}
else
{
Cfg_DT_FIFO_Channel(cardIndex, module, modid, maxchannel);
}
}
return cardIndex;
}
/**************************************************************************************************************/
/**
<summary>
Cfg_DT_FIFO_Channel handles calling the Display_DT_ChannelCfg routine to display the discrete channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
void Cfg_DT_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");
if (ModuleID == NAIBRD_MODULE_ID_KA)
{
naiif_printf("\r\n For KA modules, only Channels 13-16 are configurable.");
naiif_printf("\r\n Ch.01-12 are output only, Ch.17-28 are input only.\r\n");
defaultchan = DEF_DT_KA_CHANNEL;
}
else
{
defaultchan = DEF_DT_CHANNEL;
}
bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &chan);
dtParams->cardIndex = cardIndex;
dtParams->module = module;
dtParams->channel = chan;
naiapp_utils_LoadParamMenuCommands(DT_FIFO_CMD_LAST, DT_FIFO_MenuCmds);
while (bContinue)
{
Display_DT_ChannelCfg(cardIndex, module, chan);
naiapp_display_ParamMenuCommands((int8_t *)"DT 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 DT_FIFO_CMD_MODE:
case DT_FIFO_CMD_GET_DATA:
case DT_FIFO_CMD_FIFO_FREQ:
case DT_FIFO_CMD_STATUS:
case DT_CMD_DEBOUNCE:
DT_FIFO_MenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)dtParams);
break;
case DT_FIFO_CMD_FIFO_START:
check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
break;
case DT_FIFO_CMD_FIFO_STOP:
check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_DISABLE));
naiif_printf("Measurement stopped\r\n");
break;
case DT_FIFO_CMD_COUNT:
check_status(naibrd_DT_GetFIFOCount(cardIndex, module, chan, &outcount));
naiif_printf("Count is %d\r\n", outcount);
break;
case DT_FIFO_CMD_FIFO_CLEAR:
check_status(naibrd_DT_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_DT_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for measurement operation.
</summary>
*/
/**************************************************************************************************************/
static void Display_DT_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan)
{
float64_t interval = 0.0;
int32_t numberOfElements = 0;
uint32_t fifoStatus = 0;
naibrd_dt_enhanced_mode_t opmode = 0;
int32_t outcount = 0;
check_status(naibrd_DT_GetFIFOEventMappedStatusRaw(cardIndex, module, chan, NAI_STATUS_REALTIME, NAIBRD_DT_EVENT_MAP_FIFO, &fifoStatus));
check_status(naibrd_DT_GetFIFOCount(cardIndex, module, chan, &numberOfElements));
check_status(naibrd_DT_GetEnhancedMode(cardIndex, module, chan, &opmode));
check_status(naibrd_DT_GetTimebaseInterval(cardIndex, module, chan, &interval));
naiif_printf("\r\n === Channel %d ===\r\n\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_DT_EVENT_STATUS_FIFO_EMPTY:
naiif_printf(" Empty ");
break;
case (uint32_t)NAIBRD_DT_EVENT_STATUS_FIFO_FULL:
naiif_printf(" Full ");
break;
case (uint32_t)NAIBRD_DT_EVENT_STATUS_FIFO_ALMOST_EMPTY:
naiif_printf(" Almost Empty ");
break;
case (uint32_t)NAIBRD_DT_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_DT_GetCountData(cardIndex, module, chan, &outcount));
naiif_printf("%7d ", outcount);
}
else
naiif_printf(" ");
switch (opmode)
{
case NAIBRD_DT_MODE_STD_INPUT_OUTPUT:
naiif_printf(" DT MODE STD INPUT OUTPUT ");
break;
case NAIBRD_DT_MODE_MEASURE_HIGH_TIME:
naiif_printf(" DT MODE MEASURE HIGH TIME ");
break;
case NAIBRD_DT_MODE_MEASURE_LOW_TIME:
naiif_printf(" DT MODE MEASURE LOW TIME ");
break;
case NAIBRD_DT_MODE_TIMESTAMP_RISING_EDGES:
naiif_printf(" DT MODE TIMESTAMP RISING EDGES ");
break;
case NAIBRD_DT_MODE_TIMESTAMP_FALLING_EDGES:
naiif_printf(" DT MODE TIMESTAMP FALLING EDGES ");
break;
case NAIBRD_DT_MODE_TIMESTAMP_ALL_EDGES:
naiif_printf(" DT MODE TIMESTAMP ALL EDGES ");
break;
case NAIBRD_DT_MODE_COUNT_RISING_EDGES:
naiif_printf(" DT MODE COUNT RISING EDGES ");
break;
case NAIBRD_DT_MODE_COUNT_FALLING_EDGES:
naiif_printf(" DT MODE COUNT FALLING EDGES ");
break;
case NAIBRD_DT_MODE_COUNT_ALL_EDGES:
naiif_printf(" DT MODE COUNT ALL EDGES ");
break;
case NAIBRD_DT_MODE_MEASURE_PERIOD_RISING_EDGE:
naiif_printf(" DT MODE MEASURE PERIOD FROM RISING EDGE ");
break;
case NAIBRD_DT_MODE_MEASURE_FREQUENCY:
naiif_printf(" DT MODE Interval Counter ");
break;
case NAIBRD_DT_MODE_OUTPUT_PWM_FOREVER:
naiif_printf(" DT MODE PWM Continuous ");
break;
case NAIBRD_DT_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES:
naiif_printf(" DT MODE PWM Burst ");
break;
case NAIBRD_DT_MODE_OUTPUT_PATTERN_RAM:
naiif_printf(" DT MODE PATTERN RAM ");
break;
default:
naiif_printf(" Unknown ");
break;
}
}
/**************************************************************************************************************/
/**
<summary>
Configure_DT_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_DT_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_DT_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_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_MEASURE_HIGH_TIME));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_DT_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else if (selection == 2)
{
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_MEASURE_LOW_TIME));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_DT_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else if (selection == 3)
{
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_TIMESTAMP_RISING_EDGES));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_DT_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else if (selection == 4)
{
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_TIMESTAMP_FALLING_EDGES));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_DT_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else if (selection == 5)
{
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_TIMESTAMP_ALL_EDGES));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_DT_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else if (selection == 6)
{
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_COUNT_RISING_EDGES));
/* clear old count value since we are changing modes */
check_status(naibrd_DT_ClearCountData(cardIndex, module, chan));
/* now start the counter in the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else if (selection == 7)
{
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_COUNT_FALLING_EDGES));
/* clear old count value since we are changing modes */
check_status(naibrd_DT_ClearCountData(cardIndex, module, chan));
/* now start the counter in the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else if (selection == 8)
{
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_COUNT_ALL_EDGES));
/* clear old count value since we are changing modes */
check_status(naibrd_DT_ClearCountData(cardIndex, module, chan));
/* now start the counter in the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else if (selection == 9)
{
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_MEASURE_PERIOD_RISING_EDGE));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_DT_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else if (selection == 10)
{
check_status(naibrd_DT_SetEnhancedMode(cardIndex, module, chan, NAIBRD_DT_MODE_MEASURE_FREQUENCY));
/* Set the interval */
check_status(Configure_DT_Counter_Interval(APP_PARAM_COUNT, (int32_t*)dtParams));
/* clear old data from FIFO since we are changing modes */
check_status(naibrd_DT_ClearFIFO(cardIndex, module, chan));
/* now start the FIFO */
status = check_status(naibrd_DT_SetEnhanceTriggerEnable(cardIndex, module, chan, NAIBRD_DT_ENABLE));
}
else
{
naiif_printf("Invalid mode %d\r\n", selection);
}
}
}
return status;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DT_Counter_Interval will configure DT module gating interval for measurement of counts within the user
defined interval.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DT_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_DT_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_DT_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAIBRD_MODULE_ID_DT4:
case NAIBRD_MODULE_ID_CM8:
min = (float64_t)(0x2u * lsb);
max = (float64_t)(0xFFFFFFFF * lsb);
break;
default:
break;
}
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_DT_SetTimebaseInterval(cardIndex, module, chan, interval));
}
}
}
return status;
}
/**************************************************************************************************************/
/**
<summary>
Get_DT_FIFO_Data reads back the data on the FIFO.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Get_DT_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_DT_ParamCnt(paramCnt);
timeout = (0xFFFFFFFFu);
/* First check how many elements are on the FIFO */
check_status(naibrd_DT_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_DT_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_DT_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_DT_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_DT_ParamCnt(paramCnt);
check_status(naibrd_DT_GetFIFOEventMappedStatusRaw(cardIndex, module, chan, NAI_STATUS_REALTIME, NAIBRD_DT_EVENT_MAP_FIFO, &fifoStatus));
switch (fifoStatus)
{
case 0:
naiif_printf("NAIBRD_DT_EVENT_STATUS_FIFO_BTWN_ALMOST_EMPTY_FULL_REALTIME\r\n");
break;
case (uint32_t)NAIBRD_DT_EVENT_STATUS_FIFO_EMPTY:
naiif_printf("NAIBRD_DT_EVENT_STATUS_FIFO_EMPTY\r\n");
break;
case (uint32_t)NAIBRD_DT_EVENT_STATUS_FIFO_FULL:
naiif_printf("NAIBRD_DT_EVENT_STATUS_FIFO_FULL\r\n");
break;
case (uint32_t)NAIBRD_DT_EVENT_STATUS_FIFO_ALMOST_EMPTY:
naiif_printf("NAIBRD_DT_EVENT_STATUS_FIFO_ALMOST_EMPTY\r\n");
break;
case (uint32_t)NAIBRD_DT_EVENT_STATUS_FIFO_ALMOST_FULL:
naiif_printf("NAIBRD_DT_EVENT_STATUS_FIFO_ALMOST_FULL\r\n");
break;
default:
naiif_printf("Unknown");
break;
}
return status;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DT_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_DT_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_DT_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_DT_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAIBRD_MODULE_ID_DT4:
case NAIBRD_MODULE_ID_CM8:
min = (float64_t)(0x0u * lsb);
max = (float64_t)(0xFFFFFFFE * lsb);
break;
default:
break;
}
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_DT_SetDebounceTime(cardIndex, module, chan, time));
}
}
check_status(naibrd_DT_GetDebounceTime(cardIndex, module, chan, &time));
if (status == NAI_SUCCESS)
naiif_printf("Debounce set to %12.6f milliseconds\r\n", time);
}
return status;
}