DIF PatternGenerator
Edit this on GitLab
DIF PatternGenerator Sample Application (SSK 1.x)
Overview
The DIF PatternGenerator sample application demonstrates how to generate digital output patterns from a memory-based pattern RAM on DIF (Digital Input/Function) module channels. Pattern generation works at the hardware level: your application loads a sequence of digital output states into the module’s pattern RAM, configures a playback period that controls how fast the hardware steps through the data, and then enables output. The module autonomously sequences through the RAM contents at the configured rate, driving the channel outputs without further software intervention.
This is fundamentally different from setting individual output states with naibrd_DIF_SetOutputState(). With pattern generation, you define an entire sequence of output states in advance and the hardware replays them at a precise, programmable rate. This makes it possible to generate complex timing patterns, test stimulus sequences, or protocol-like waveforms that would be impractical to produce through repeated software writes.
The application provides an interactive command menu for configuring all aspects of pattern generation: selecting between continuous and burst playback modes, setting the pattern period, defining the active RAM address range, loading pattern data from a file, and enabling/pausing/resuming output. It also includes commands for resetting individual channels or all channels, and for viewing the current configuration and status.
For basic DIF channel configuration (I/O direction, output state, input reading), see the DIF BasicOps sample. For PWM output generation on DIF channels, see the DIF PWM sample.
Supported Modules
This sample supports the following DIF module types:
-
D8
-
DF1, DF2, DF3
-
CMH (combination module with DIF channels)
The application calls naibrd_DIF_GetChannelCount() at startup. If the selected module returns zero channels, it is not recognized as a DIF module and the application prints an error.
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with a supported DIF module installed (see list above).
-
SSK 1.x installed on your development host.
-
The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.
-
A pattern data file named
TestRAMPattern.txtplaced in the same directory as the executable (see Pattern Data File for the expected format).
How to Run
Launch the DIF_PatternGenerator executable from your build output directory. On startup, the application looks for a configuration file (default_DIF_PatternGenerator.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, the application prompts for a DIF channel, automatically sets that channel to output pattern RAM mode, and presents a command menu for configuring and controlling pattern generation.
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 First Time Setup Guide. |
The main() function follows a standard SSK 1.x startup flow:
-
Call
naiapp_RunBoardMenu()to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_DIF_PatternGenerator.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. -
Query the user for a card index with
naiapp_query_CardIndex(). -
Query for a module slot with
naiapp_query_ModuleNumber(). -
Retrieve the module ID with
naibrd_GetModuleID()and pass it toRun_DIF_PatternGenerator().
#if defined (__VXWORKS__)
int32_t DIF_PatternGenerator(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
while (stop != TRUE)
{
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
if (stop != TRUE)
{
moduleID = naibrd_GetModuleID(cardIndex, module);
if ((moduleID != 0))
{
Run_DIF_PatternGenerator(cardIndex, module, moduleID);
}
}
}
printf("\nType Q to quit or Enter key to restart application:\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
printf("\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
The Run_DIF_PatternGenerator() function checks the channel count to verify the module is a valid DIF module:
void Run_DIF_PatternGenerator(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
int32_t MaxChannel;
MaxChannel = naibrd_DIF_GetChannelCount(ModuleID);
if (MaxChannel == 0)
{
printf(" *** Module selection not recognized as DIF module. ***\n\n");
}
else
{
Cfg_DIF_PatternGen_Channel(cardIndex, module, ModuleID, MaxChannel);
}
}
|
Important
|
Common Connection Errors
|
Program Structure
After board connection and module validation, the application enters the channel configuration loop in Cfg_DIF_PatternGen_Channel(). This function:
-
Prompts the user to select a channel.
-
Automatically configures the selected channel for pattern generation output mode.
-
Presents an interactive command menu.
The channel is immediately set to pattern RAM output mode and output I/O format upon selection:
/* Configure the selected channel for Pattern Generator Mode and output mode */
check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan, NAI_DIF_MODE_OUTPUT_PATTERN_RAM));
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
In your own application, you must call both of these before starting pattern generation:
-
naibrd_DIF_SetOpMode()withNAI_DIF_MODE_OUTPUT_PATTERN_RAMswitches the channel’s enhanced mode to pattern RAM output. -
naibrd_DIF_SetIOFormat()withNAI_DIF_GEN5_IOFORMAT_OUTPUTconfigures the channel as a high-side output driver.
The application tracks parameters through a naiapp_AppParameters_t structure:
naiapp_AppParameters_t dif_params;
p_naiapp_AppParameters_t dif_patgen_params = &dif_params;
dif_patgen_params->cardIndex = cardIndex;
dif_patgen_params->module = module;
dif_patgen_params->modId = ModuleID;
dif_patgen_params->maxChannels = MaxChannel;
dif_patgen_params->channel = chan;
The menu system is a sample convenience — in your own code, call the same naibrd_DIF_* API functions directly.
Command Menu
The application presents these commands:
| Command | Description |
|---|---|
Mode |
Select between continuous and burst pattern generation modes. |
StartAddr |
Set the pattern RAM start address. |
EndAddr |
Set the pattern RAM end address. |
Period |
Set the pattern generation period (time between output updates) in milliseconds. |
Count |
Set the burst count (number of pattern cycles in burst mode). |
Load |
Load pattern data from the |
CONtrol |
Enable or disable pattern generation output. |
Pause/Play |
Pause or resume pattern generation output. |
Reset |
Reset the current channel back to standard I/O mode and disable all pattern controls. |
RAll |
Reset all channels back to standard I/O mode. |
SEtall |
Set all channels to pattern generation output mode. |
Display |
Display the current pattern generation configuration (period, burst count, start/end addresses). |
Stat |
Display the channel status (BIT, overcurrent, transition latches). |
How Pattern Generation Works
Understanding the hardware pattern generation mechanism is essential for using this sample effectively.
DIF pattern generation operates on a shared pattern RAM that spans all channels on the module. Each 32-bit word in the RAM represents the output states for all channels simultaneously — bit 0 corresponds to channel 1, bit 1 to channel 2, and so on. The hardware steps through the RAM from the start address to the end address at a rate determined by the pattern period register, driving all configured output channels in parallel.
The key hardware registers are:
-
Start Address — the RAM address where playback begins.
-
End Address — the RAM address where playback ends (and wraps back to start in continuous mode).
-
Period — the time between successive RAM reads, in milliseconds. This controls the output update rate.
-
Burst Count — in burst mode, the number of complete cycles through the pattern before stopping.
-
Control register — enable/disable, burst/continuous mode selection, and pause/resume bits.
The maximum pattern RAM size is 4,092 entries (MAX_DIF_PATTERN_GENERATOR_ENTRIES in the source). Each entry is a 32-bit word where each bit represents one channel’s output state. This means you can define up to 4,092 time steps in a single pattern sequence.
The pattern period determines the timing resolution. For example, with a period of 1.0 ms and 100 entries in the pattern, one complete cycle takes 100 ms (10 Hz repetition rate). With a period of 0.1 ms and the same 100 entries, one cycle takes 10 ms (100 Hz). Consult your module’s manual for the minimum and maximum period values supported by your specific hardware.
Configuring Pattern Mode
The Mode command lets you select between two pattern generation modes: continuous and burst.
if ((toupper(inputBuffer[0]) == 'C'))
{
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_BURST, NAI_DIF_ENHANCE_OP_DISABLE);
}
else if ((toupper(inputBuffer[0]) == 'B'))
{
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_BURST, NAI_DIF_ENHANCE_OP_ENABLE);
}
To select the mode in your own application, call naibrd_DIF_SetPatternGenCtrl() with NAI_DIF_PATTERN_RAM_CONTROL_BURST:
-
Pass
NAI_DIF_ENHANCE_OP_DISABLEfor continuous mode — the hardware loops through the pattern indefinitely until you disable output. -
Pass
NAI_DIF_ENHANCE_OP_ENABLEfor burst mode — the hardware plays through the pattern a specified number of times (set by the burst count) and then stops.
Continuous mode is appropriate for generating repeating test signals or clock-like patterns. Burst mode is useful when you need a finite number of pattern cycles, for example to send a specific number of stimulus pulses.
Setting Pattern RAM Addresses
The start and end addresses define which portion of the pattern RAM contains your data. The hardware reads from the start address to the end address during playback.
static nai_status_t Configure_DIF_PatternGen_StartAddr(int32_t paramCount, int32_t* p_params)
{
/* ... parameter extraction ... */
printf("\nEnter the desired Start Address: 0x");
/* ... user input ... */
startAddr = strtol(((const char *)inputBuffer), NULL, 16);
/* Validate against module limits */
switch (ModuleID)
{
case NAI_MODULE_ID_DF2:
min = naibrd_DIF_GetValidPatternGenStart(ModuleID);
max = naibrd_DIF_GetValidPatternGenEnd(ModuleID);
default:
break;
}
if (startAddr > max || startAddr < min)
printf(" Entry out of range. Range %08X to %08X \n", min, max);
else
check_status(naibrd_DIF_SetPatternGenStartAddr(cardIndex, module, startAddr));
}
To set the addresses in your own application:
-
Call
naibrd_DIF_GetValidPatternGenStart()andnaibrd_DIF_GetValidPatternGenEnd()to query the valid address range for your module type. -
Call
naibrd_DIF_SetPatternGenStartAddr()to set where playback begins. -
Call
naibrd_DIF_SetPatternGenEndAddr()to set where playback ends.
The addresses are specified in hexadecimal and represent offsets into the pattern RAM. Typically, you set the start address to 0 and the end address to (number_of_entries - 1) * 4 (since each 32-bit entry occupies 4 bytes). The valid range depends on the module type — use the API query functions to determine the limits at runtime rather than hardcoding values.
|
Important
|
Common Address Errors
|
Setting the Pattern Period
The pattern period controls the time between successive output updates — how fast the hardware steps through the pattern RAM.
nai_status_t Configure_DIF_PatternGen_Period(int32_t paramCount, int32_t* p_params)
{
/* ... parameter extraction ... */
printf("\nEnter the desired period in ms: ");
/* ... user input ... */
time = atof((const char *)inputBuffer);
lsb = naibrd_DIF_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAI_MODULE_ID_DF2:
min = (float64_t)(0x2u * lsb);
max = (float64_t)(0xFFFFFFFF * lsb);
break;
default:
break;
}
if (time > max || time < min)
printf(" Entry out of range. Range %7.3f to %7.3f ms\n", min, max);
else
check_status(naibrd_DIF_SetPatternGenPeriod(cardIndex, module, time));
}
To set the period in your own application, call naibrd_DIF_SetPatternGenPeriod() with the desired period in milliseconds. The valid range is determined by the module’s timebase LSB (least significant bit), which you can query with naibrd_DIF_GetTimebaseLSB(). The minimum period is 2 * LSB and the maximum is 0xFFFFFFFF * LSB.
The period directly affects the output timing:
-
Shorter period = faster output updates = higher pattern repetition rate.
-
Longer period = slower output updates = lower pattern repetition rate.
For example, if you load 100 entries and set a period of 0.5 ms, one complete pattern cycle takes 50 ms (20 Hz). If you set the period to 0.01 ms, the same pattern cycles at 1 kHz.
|
Important
|
Common Period Errors
|
Setting the Burst Count
In burst mode, the burst count determines how many complete cycles the hardware plays through the pattern before stopping.
burstcount = atoi((const char *)inputBuffer);
switch (ModuleID)
{
case NAI_MODULE_ID_DF2:
if (burstcount < 1)
{
burstcount = 1;
printf("Setting burstcount to minimum of 1.\n");
}
check_status(naibrd_DIF_SetPatternGen_BurstNum(cardIndex, module, burstcount));
break;
default:
printf("Unsupported function for this module.\n");
break;
}
To set the burst count in your own application, call naibrd_DIF_SetPatternGen_BurstNum() with the desired number of cycles. The minimum value is 1. The burst count only takes effect when the module is in burst mode (see Configuring Pattern Mode).
Note that burst count support may be module-specific. In the sample source, only DF2 modules have explicit burst count handling. Other module types print "Unsupported function for this module." Check your module’s manual to confirm burst mode support.
Loading Pattern Data
The Load command reads pattern data from a file named TestRAMPattern.txt and writes it to the module’s pattern RAM. This file must be in the same directory as the executable.
Pattern Data File
The TestRAMPattern.txt file contains one hexadecimal data value per line. Each value is a 32-bit word where each bit represents the output state for one channel. For example:
0000000F 00000000 0000000F 00000000
This pattern drives channels 1-4 high, then low, then high, then low (a simple toggle pattern for the first four channels). Bit 0 corresponds to channel 1, bit 1 to channel 2, and so on. The upper bits control higher-numbered channels.
The file can contain up to 4,092 entries (the MAX_DIF_PATTERN_GENERATOR_ENTRIES limit). Lines with no valid hex characters are skipped.
When designing your pattern data, think of each line as one time step. At each step, the hardware drives all output channels simultaneously according to the bit pattern. The period register controls how long each step lasts. So a four-line file with a 1 ms period produces a 4 ms pattern cycle; the same file with a 0.1 ms period produces a 0.4 ms cycle.
How Data is Loaded
The Load_DIF_PatternGenArray() function reads the file, parses each line as a hexadecimal value, and writes the entire array to the pattern RAM in a single API call:
nai_status_t Load_DIF_PatternGenArray(int32_t paramCount, int32_t* p_params)
{
/* ... parameter extraction ... */
uint32_t dataPattern[MAX_DIF_PATTERN_GENERATOR_ENTRIES];
int32_t entryCnt = 0;
int8_t* filename = (int8_t*)"TestRAMPattern.txt";
for (i = 0; i < MAX_DIF_PATTERN_GENERATOR_ENTRIES; i++)
dataPattern[i] = 0;
patternfile = fopen((const char *)filename, "r");
if (patternfile != NULL)
{
while (fgets((char*)buffer, sizeof(buffer), patternfile))
{
if (entryCnt > MAX_DIF_PATTERN_GENERATOR_ENTRIES)
break;
/* Parse hex value from line */
/* ... character parsing ... */
if (strlen((const char*)data) > 0)
{
dataPattern[entryCnt] = naiapp_utils_HexStrToDecUInt32(data);
entryCnt++;
}
}
if (entryCnt > 0)
{
check_status(naibrd_DIF_SetPatternGenBuf(cardIndex, module, entryCnt, &dataPattern[0]));
}
fclose(patternfile);
}
else
printf("ERROR: Unable to open Pattern file: %s\n", filename);
}
The key API call is naibrd_DIF_SetPatternGenBuf(), which writes the entire pattern array to the module’s pattern RAM in one operation. The parameters are:
-
cardIndex— the board index. -
module— the module slot number. -
entryCnt— the number of 32-bit entries to write. -
&dataPattern[0]— pointer to the array of pattern data.
In your own application, you can populate the dataPattern array programmatically rather than reading from a file. Each array element is a 32-bit bitmask of channel output states for one time step. For example, to create a walking-ones pattern across 8 channels:
dataPattern[0] = 0x01; /* Channel 1 high */ dataPattern[1] = 0x02; /* Channel 2 high */ dataPattern[2] = 0x04; /* Channel 3 high */ /* ... and so on */
|
Important
|
Common Data Loading Errors
|
Enabling and Disabling Output
The CONtrol command enables or disables pattern generation output.
switch (toupper(inputBuffer[0]))
{
case 'E':
enState = NAI_DIF_ENHANCE_OP_ENABLE;
bUpdateOutput = TRUE;
break;
case 'D':
enState = NAI_DIF_ENHANCE_OP_DISABLE;
bUpdateOutput = TRUE;
break;
default:
printf("ERROR: Invalid switch state selection\n");
break;
}
if (bUpdateOutput)
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_ENABLE, enState));
To control pattern output in your own application, call naibrd_DIF_SetPatternGenCtrl() with NAI_DIF_PATTERN_RAM_CONTROL_ENABLE:
-
Pass
NAI_DIF_ENHANCE_OP_ENABLEto start pattern playback. -
Pass
NAI_DIF_ENHANCE_OP_DISABLEto stop it.
Before enabling output, make sure you have:
-
Set the channel to output pattern RAM mode (
naibrd_DIF_SetOpMode()withNAI_DIF_MODE_OUTPUT_PATTERN_RAM). -
Set the I/O format to output (
naibrd_DIF_SetIOFormat()withNAI_DIF_GEN5_IOFORMAT_OUTPUT). -
Loaded pattern data into RAM (
naibrd_DIF_SetPatternGenBuf()). -
Set the start and end addresses to bracket your data.
-
Set the pattern period.
-
Selected the mode (continuous or burst).
Pausing and Resuming Output
The Pause/Play command lets you temporarily suspend and resume pattern output without disabling it entirely. When paused, the outputs hold their current state. When resumed, playback continues from where it left off.
switch (toupper(inputBuffer[0]))
{
case 'P':
enState = NAI_DIF_ENHANCE_OP_ENABLE;
bUpdateOutput = TRUE;
break;
case 'R':
enState = NAI_DIF_ENHANCE_OP_DISABLE;
bUpdateOutput = TRUE;
break;
}
if (bUpdateOutput)
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_PAUSE, enState));
To pause and resume in your own application, call naibrd_DIF_SetPatternGenCtrl() with NAI_DIF_PATTERN_RAM_CONTROL_PAUSE:
-
Pass
NAI_DIF_ENHANCE_OP_ENABLEto pause output (note: "enable" the pause bit = paused). -
Pass
NAI_DIF_ENHANCE_OP_DISABLEto resume output (disable the pause bit = running).
Pausing is useful when you need to synchronize the start of pattern output with an external event or when you want to hold the current output state temporarily without losing your position in the pattern.
Resetting Channels
The application provides two reset commands for returning channels to their default state, and one command for bulk-configuring all channels.
Reset Single Channel
The Reset command resets the currently selected channel back to standard I/O mode and disables all pattern generation controls:
check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAI_DIF_ENHANCE_OP_DISABLE));
check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan, NAI_DIF_MODE_STD_INPUT_OUTPUT));
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_ENABLE, NAI_DIF_ENHANCE_OP_DISABLE));
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_BURST, NAI_DIF_ENHANCE_OP_DISABLE));
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_PAUSE, NAI_DIF_ENHANCE_OP_DISABLE));
This sequence disables the enhanced trigger, returns the channel to standard input/output mode, and clears the enable, burst, and pause control bits. In your own application, follow this same sequence when you need to cleanly shut down pattern generation on a channel.
Reset All Channels
The RAll command performs the same reset sequence on every channel and additionally resets each channel’s timer:
for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, ch_loop, NAI_DIF_ENHANCE_OP_DISABLE));
check_status(naibrd_DIF_SetOpMode(cardIndex, module, ch_loop, NAI_DIF_MODE_STD_INPUT_OUTPUT));
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_ENABLE, NAI_DIF_ENHANCE_OP_DISABLE));
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_BURST, NAI_DIF_ENHANCE_OP_DISABLE));
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex, module,
NAI_DIF_PATTERN_RAM_CONTROL_PAUSE, NAI_DIF_ENHANCE_OP_DISABLE));
check_status(naibrd_DIF_Reset(cardIndex, module, ch_loop, NAI_DIF_RESET_TIMER_ONLY));
}
Set All Channels to Pattern Mode
The SEtall command configures every channel on the module for pattern generation output:
for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
check_status(naibrd_DIF_SetOutputState(cardIndex, module, ch_loop, NAI_DIF_STATE_LO));
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, ch_loop, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
check_status(naibrd_DIF_SetOpMode(cardIndex, module, ch_loop, NAI_DIF_MODE_OUTPUT_PATTERN_RAM));
}
This sets each channel’s output to low, configures it as an output, and switches it to pattern RAM mode. This is convenient when you want all channels driven by the shared pattern RAM simultaneously — since each bit in the pattern data controls one channel, all channels configured for pattern output will respond to their respective bits in the pattern.
Displaying Configuration and Status
Pattern Generation Configuration
The Display command reads back and displays the current pattern generation settings:
check_status(naibrd_DIF_GetPatternGenPeriod(cardIndex, module, &period));
check_status(naibrd_DIF_GetPatternGen_BurstNum(cardIndex, module, &burstnumber));
check_status(naibrd_DIF_GetPatternGenStartAddr(cardIndex, module, &startaddr));
check_status(naibrd_DIF_GetPatternGenEndAddr(cardIndex, module, &endaddr));
To read back the configuration in your own application, use the Get counterparts of the Set functions: naibrd_DIF_GetPatternGenPeriod(), naibrd_DIF_GetPatternGen_BurstNum(), naibrd_DIF_GetPatternGenStartAddr(), and naibrd_DIF_GetPatternGenEndAddr(). This is useful for verifying that your configuration was applied correctly.
Channel Status
The Stat command reads the channel’s status latches:
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_BIT_LATCHED, &status));
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_OVERCURRENT_LATCHED, &status));
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_LO_HI_TRANS_LATCHED, &status));
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_HI_LO_TRANS_LATCHED, &status));
The available status types are:
-
BIT (Built-In Test) — indicates a channel self-test failure.
-
Overcurrent — the channel has exceeded its current limit.
-
Lo-Hi Transition — a rising edge was detected since the last status read.
-
Hi-Lo Transition — a falling edge was detected since the last status read.
These are latched status bits — they remain set until explicitly cleared. Consult your module’s manual for details on status bit behavior and clearing.
|
Important
|
Common Status Errors
|
Troubleshooting Reference
The following table summarizes errors and symptoms you may encounter. Consult your module’s manual for hardware-specific diagnostics.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
No board found |
Board not powered, not physically connected, or driver not loaded. |
Verify power, physical connection, and that the appropriate driver is installed for your connection type. |
Connection timeout |
Ethernet-connected board is unreachable. |
Check network settings, IP configuration, and firewall rules. |
"Module selection not recognized as DIF module" |
The selected module does not have DIF channels. |
Select a slot containing a D8, DF1, DF2, DF3, or CMH module. |
"Unable to open Pattern file: TestRAMPattern.txt" |
The pattern file is not in the current working directory. |
Copy |
No output signal after enabling |
Channel not in output mode, pattern not loaded, or enable bit not set. |
Verify: (1) I/O format is set to output, (2) op mode is |
Output pattern does not match expected data |
Bit positions in the pattern data do not correspond to the expected channels, or the start/end addresses do not bracket all loaded data. |
Verify bit 0 = channel 1, bit 1 = channel 2, etc. Check that the end address covers all loaded entries. |
"Entry out of range" for start/end address |
The address is outside the valid pattern RAM range for this module. |
Use |
"Entry out of range" for period |
The period is below the module minimum or above the maximum. |
Query the timebase LSB with |
Overcurrent status set |
Channel load exceeds the module’s current drive capability. |
Reduce the load or check for wiring faults. Consult the module manual for current limits. |
Pattern runs once and stops (unexpected) |
Module is in burst mode with burst count = 1. |
Switch to continuous mode or increase the burst count. |
"Unsupported function for this module" |
Burst count or other feature not available on the selected module type. |
Check your module’s manual. Not all DIF modules support all pattern generation features. |
|
API function not supported on the selected module type. |
Verify you are using a supported DIF module (D8, DF1, DF2, DF3, or CMH). |
Full Source
Full Source — DIF_PatternGenerator.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
/* Common Sample Program include files */
#include "include/naiapp_boardaccess_menu.h"
#include "include/naiapp_boardaccess_query.h"
#include "include/naiapp_boardaccess_access.h"
#include "include/naiapp_boardaccess_display.h"
#include "include/naiapp_boardaccess_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_dif.h"
#include "advanced/nai_ether_adv.h"
static const int8_t *CONFIG_FILE = (int8_t *)"default_DIF_PatternGenerator.txt";
/* Function prototypes */
void Run_DIF_PatternGenerator(int32_t cardIndex, int32_t module, int32_t ModuleID);
void Cfg_DIF_PatternGen_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
void Display_DIF_PatternGen_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID);
static nai_status_t Configure_DIF_PatternGen_StartAddr(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_PatternGen_EndAddr(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_PatternGen_Period(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_PatternGen_Burstcount(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_PatternGen_Mode(int32_t paramCount, int32_t* p_params);
static nai_status_t Load_DIF_PatternGenArray(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_ControlEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_ControlPause(int32_t paramCount, int32_t* p_params);
static nai_status_t Display_DIF_PatternGen_Configuration(int32_t paramCount, int32_t* p_params);
static nai_status_t Display_DIF_Status(int32_t paramCount, int32_t* p_params);
static const int32_t DEF_DIF_CHANNEL = 1;
#define MAX_DIF_PATTERN_GENERATOR_ENTRIES 4092
/****** Command Table *******/
enum dif_patterngen_commands
{
DIF_PATTERNGEN_CMD_MODE,
DIF_PATTERNGEN_CMD_STARTADDR,
DIF_PATTERNGEN_CMD_ENDADDR,
DIF_PATTERNGEN_CMD_PERIOD,
DIF_PATTERNGEN_CMD_BURSTCOUNT,
DIF_PATTERNGEN_CMD_LOAD_DATA,
DIF_PATTERNGEN_CMD_ENABLE,
DIF_PATTERNGEN_CMD_PAUSE_DATA,
DIF_PATTERNGEN_CMD_RESETMODE,
DIF_PATTERNGEN_CMD_RESETALL,
DIF_PATTERNGEN_CMD_SETALL,
DIF_PATTERNGEN_CMD_DISP,
DIF_PATTERNGEN_CMD_STATUS,
DIF_PATTERNGEN_CMD_LAST
};
/****** Command Tables *******/
naiapp_cmdtbl_params_t DIF_PatternGen_MenuCmds[] = {
{"Mode", "DIF Select Pattern Mode", DIF_PATTERNGEN_CMD_MODE, Configure_DIF_PatternGen_Mode},
{"StartAddr", "DIF Set Start Address", DIF_PATTERNGEN_CMD_STARTADDR, Configure_DIF_PatternGen_StartAddr},
{"EndAddr", "DIF Set End Address", DIF_PATTERNGEN_CMD_ENDADDR, Configure_DIF_PatternGen_EndAddr},
{"Period", "DIF Pattern Generator Period", DIF_PATTERNGEN_CMD_PERIOD, Configure_DIF_PatternGen_Period},
{"Count", "DIF Pattern Generator Burst count", DIF_PATTERNGEN_CMD_BURSTCOUNT, Configure_DIF_PatternGen_Burstcount},
{"Load", "DIF Load Pattern Generator Data", DIF_PATTERNGEN_CMD_LOAD_DATA, Load_DIF_PatternGenArray},
{"CONtrol", "DIF Enable or Disable Pattern Generator Output", DIF_PATTERNGEN_CMD_ENABLE, Configure_DIF_ControlEnable},
{"Pause/Play", "DIF Pause or Resume Pattern Gen Output", DIF_PATTERNGEN_CMD_PAUSE_DATA, Configure_DIF_ControlPause},
{"Reset", "DIF Reset Chan Mode, Input", DIF_PATTERNGEN_CMD_RESETMODE, NULL},
{"RAll", "DIF Reset All Channels, Input", DIF_PATTERNGEN_CMD_RESETALL, NULL},
{"SEtall", "DIF Set All Channels to Pattern Gen", DIF_PATTERNGEN_CMD_SETALL, NULL},
{"Display", "DIF Display channel Pattern Generator Info", DIF_PATTERNGEN_CMD_DISP, Display_DIF_PatternGen_Configuration},
{"Stat", "DIF Display Status", DIF_PATTERNGEN_CMD_STATUS, Display_DIF_Status},
};
/**************************************************************************************************************/
/**
<summary>
The purpose of the DIF_PatternGenerator is to illustrate the methods to call in the naibrd library to perform configuration
setup for output in Pattern Generator operation mode. Pattern generator period setting is configurable.
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_PatternGenerator(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
while (stop != TRUE)
{
/* Query the user for the card index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Query the user for the module number */
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
if (stop != TRUE)
{
moduleID = naibrd_GetModuleID(cardIndex, module);
if ((moduleID != 0))
{
Run_DIF_PatternGenerator(cardIndex, module, moduleID);
}
}
}
printf("\nType Q to quit or Enter key to restart application:\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
printf("\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
/**************************************************************************************************************/
/**
<summary>
Run_DIF_PatternGenerator prompts the user for the card, module and channel to use for the application and calls
Cfg_DIF_PatternGen_Channel if the card, module, channel is valid for as a TLL module.
</summary>
*/
/**************************************************************************************************************/
void Run_DIF_PatternGenerator(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
int32_t MaxChannel;
MaxChannel = naibrd_DIF_GetChannelCount(ModuleID);
if (MaxChannel == 0)
{
printf(" *** Module selection not recognized as DIF module. ***\n\n");
}
else
{
Cfg_DIF_PatternGen_Channel(cardIndex, module, ModuleID, MaxChannel);
}
}
/**************************************************************************************************************/
/**
<summary>
Cfg_DIF_PatternGen_Channel handles calling the Display_DIF_PatternGen_ChannelCfg routine to display the DIF
channel configuration and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
void Cfg_DIF_PatternGen_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel)
{
bool_t bQuit = FALSE;
bool_t bContinue = TRUE;
bool_t bCmdFound = FALSE;
int32_t chan, defaultchan = 1;
int32_t cmd;
int32_t ch_loop;
int32_t status = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
naiapp_AppParameters_t dif_params;
p_naiapp_AppParameters_t dif_patgen_params = &dif_params;
dif_patgen_params->cardIndex = cardIndex;
dif_patgen_params->module = module;
dif_patgen_params->modId = ModuleID;
dif_patgen_params->maxChannels = MaxChannel;
while (bContinue)
{
printf(" \r\n\r\n");
printf("Channel selection \r\n");
printf("================= \r\n");
defaultchan = DEF_DIF_CHANNEL;
bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &chan);
dif_patgen_params->channel = chan;
/* Configure the selected channel for Pattern Generator Mode and output mode */
check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan, NAI_DIF_MODE_OUTPUT_PATTERN_RAM));
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
naiapp_utils_LoadParamMenuCommands(DIF_PATTERNGEN_CMD_LAST, DIF_PatternGen_MenuCmds);
while (bContinue)
{
Display_DIF_PatternGen_ChannelCfg(cardIndex, module, chan, ModuleID);
naiapp_display_ParamMenuCommands((int8_t *)"DIF Pattern Generator Operation Menu");
printf("\nType DIF 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 DIF_PATTERNGEN_CMD_LOAD_DATA:
case DIF_PATTERNGEN_CMD_PERIOD:
case DIF_PATTERNGEN_CMD_STARTADDR:
case DIF_PATTERNGEN_CMD_ENDADDR:
case DIF_PATTERNGEN_CMD_BURSTCOUNT:
case DIF_PATTERNGEN_CMD_MODE:
case DIF_PATTERNGEN_CMD_ENABLE:
case DIF_PATTERNGEN_CMD_PAUSE_DATA:
case DIF_PATTERNGEN_CMD_DISP:
case DIF_PATTERNGEN_CMD_STATUS:
DIF_PatternGen_MenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)dif_patgen_params);
break;
case DIF_PATTERNGEN_CMD_RESETMODE:
{
status |= check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, chan, NAI_DIF_ENHANCE_OP_DISABLE));
status |= check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan, NAI_DIF_MODE_STD_INPUT_OUTPUT));
status |= check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_ENABLE,NAI_DIF_ENHANCE_OP_DISABLE));
status |= check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_BURST, NAI_DIF_ENHANCE_OP_DISABLE));
status |= check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_PAUSE, NAI_DIF_ENHANCE_OP_DISABLE));
if (status == NAI_SUCCESS)
printf("Reset completed \n");
else
printf("Error %2X on set \n", status);
}
break;
case DIF_PATTERNGEN_CMD_RESETALL:
{
status = NAI_SUCCESS;
for (ch_loop=1; ch_loop<=MaxChannel; ch_loop++)
{
status |= check_status(naibrd_DIF_SetEnhanceTriggerEnable(cardIndex, module, ch_loop, NAI_DIF_ENHANCE_OP_DISABLE));
status |= check_status(naibrd_DIF_SetOpMode(cardIndex, module, ch_loop, NAI_DIF_MODE_STD_INPUT_OUTPUT));
status |= check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_ENABLE, NAI_DIF_ENHANCE_OP_DISABLE));
status |= check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_BURST, NAI_DIF_ENHANCE_OP_DISABLE));
status |= check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_PAUSE, NAI_DIF_ENHANCE_OP_DISABLE));
status |= check_status(naibrd_DIF_Reset(cardIndex, module, ch_loop, NAI_DIF_RESET_TIMER_ONLY));
}
if (status == NAI_SUCCESS)
printf("Reset All completed \n");
else
printf("Error %2X on set \n", status);
}
break;
case DIF_PATTERNGEN_CMD_SETALL:
{
status = NAI_SUCCESS;
for (ch_loop=1; ch_loop<=MaxChannel; ch_loop++)
{
status |= check_status(naibrd_DIF_SetOutputState(cardIndex, module, ch_loop, NAI_DIF_STATE_LO));
status |= check_status(naibrd_DIF_SetIOFormat(cardIndex, module, ch_loop, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
status |= check_status(naibrd_DIF_SetOpMode(cardIndex, module, ch_loop, NAI_DIF_MODE_OUTPUT_PATTERN_RAM));
}
if (status == NAI_SUCCESS)
printf("Set on all channels completed \n");
else
printf("Error %2X on set \n", status);
}
break;
default:
printf("Invalid command entered\n");
break;
}
}
else
printf("Invalid command entered\n");
}
}
else
bContinue = FALSE;
}
}
}
/**************************************************************************************************************/
/**
<summary>
Display_DIF_PatternGen_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for basic operation.
</summary>
*/
/**************************************************************************************************************/
void Display_DIF_PatternGen_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID)
{
uint32_t ioformat = 0;
nai_dif_state_t outputstate = 0;
nai_dif_state_t inputstate = 0;
nai_dif_enhanced_mode_t opmode = 0;
nai_dif_enable_t enablebit=0;
nai_dif_enable_t burstbit=0;
nai_dif_enable_t pausebit=0;
uint32_t ModuleVer;
uint32_t ModuleRev;
uint32_t ModInfo_Special;
naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
check_status(naibrd_DIF_GetIOFormat(cardIndex, module, chan, &ioformat));
check_status(naibrd_DIF_GetOutputState(cardIndex, module, chan, &outputstate));
check_status(naibrd_DIF_GetInputState(cardIndex, module, chan, &inputstate));
check_status(naibrd_DIF_GetOpMode(cardIndex, module, chan, &opmode));
check_status(naibrd_DIF_GetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_ENABLE, &enablebit));
check_status(naibrd_DIF_GetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_BURST, &burstbit));
check_status(naibrd_DIF_GetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_PAUSE, &pausebit));
printf("\n === Channel %d ===\n\n", chan);
{
printf(" I/O Output Input \n");
printf(" Format State State Enhanced Mode Selection \n");
printf(" -------- ------- ------- ------------------------- \n");
}
switch (ioformat)
{
case NAI_DIF_IOFORMAT_INPUT:
printf(" Input ");
break;
case NAI_DIF_GEN3_IOFORMAT_OUTPUT:
case NAI_DIF_GEN5_IOFORMAT_OUTPUT:
printf(" High-side");
break;
default:
printf(" Unknown ");
break;
}
switch (outputstate)
{
case NAI_DIF_STATE_LO:
printf(" LOW ");
break;
case NAI_DIF_STATE_HI:
printf(" HIGH ");
break;
default:
printf(" Unknown ");
break;
}
switch (inputstate)
{
case NAI_DIF_STATE_LO:
printf(" LOW Input ");
break;
case NAI_DIF_STATE_HI:
printf("HIGH Input ");
break;
default:
printf("Unknown ");
break;
}
switch (opmode)
{
case NAI_DIF_MODE_STD_INPUT_OUTPUT:
printf("STD_INPUT_OUTPUT \n");
break;
case NAI_DIF_MODE_MEASURE_HIGH_TIME:
printf("NAI_DIF_MODE_MEASURE_HIGH_TIME \n");
break;
case NAI_DIF_MODE_MEASURE_LOW_TIME:
printf("NAI_DIF_MODE_MEASURE_LOW_TIME \n ");
break;
case NAI_DIF_MODE_TIMESTAMP_RISING_EDGES:
printf("NAI_DIF_MODE_TIMESTAMP_RISING_EDGES \n");
break;
case NAI_DIF_MODE_TIMESTAMP_FALLING_EDGES:
printf("NAI_DIF_MODE_TIMESTAMP_FALLING_EDGES \n");
break;
case NAI_DIF_MODE_TIMESTAMP_ALL_EDGES:
printf("NAI_DIF_MODE_TIMESTAMP_ALL_EDGES \n");
break;
case NAI_DIF_MODE_COUNT_RISING_EDGES:
printf("NAI_DIF_MODE_COUNT_RISING_EDGES \n");
break;
case NAI_DIF_MODE_COUNT_FALLING_EDGES:
printf("NAI_DIF_MODE_COUNT_FALLING_EDGES \n");
break;
case NAI_DIF_MODE_COUNT_ALL_EDGES:
printf("NAI_DIF_MODE_COUNT_ALL_EDGES \n");
break;
case NAI_DIF_MODE_MEASURE_PERIOD_FROM_RISING_EDGE:
printf("NAI_DIF_MODE_MEASURE_PERIOD_FROM_RISING_EDGE \n");
break;
case NAI_DIF_MODE_MEASURE_FREQUENCY:
printf("NAI_DIF_MODE_MEASURE_FREQUENCY \n");
break;
case NAI_DIF_MODE_OUTPUT_PWM_FOREVER:
printf("NAI_DIF_MODE_OUTPUT_PWM_FOREVER \n");
break;
case NAI_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES:
printf("NAI_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES \n");
break;
case NAI_DIF_MODE_OUTPUT_PATTERN_RAM:
printf("NAI_DIF_MODE_OUTPUT_PATTERN_RAM \n");
break;
default:
printf("Unknown ");
break;
}
printf(" \n\n");
printf(" Pattern Gen Mode \n");
printf(" --------------------------\n");
switch (enablebit)
{
case NAI_DIF_STATE_LO:
printf(" Disabled");
break;
case NAI_DIF_STATE_HI:
printf(" Enabled");
break;
default:
printf(" UNK ");
break;
}
switch (burstbit)
{
case NAI_DIF_STATE_LO:
printf(" Continuous Mode");
break;
case NAI_DIF_STATE_HI:
printf(" Burst Mode");
break;
default:
printf(" UNK ");
break;
}
switch (pausebit)
{
case NAI_DIF_STATE_LO:
break;
case NAI_DIF_STATE_HI:
printf(" PAUSED");
break;
default:
printf(" UNK ");
break;
}
}
/**************************************************************************************************************/
/**
<summary>
Configure_DIF_PatternGen_StartAddr handles the user request to configure the time values for period on the selected
channel and calls the method in the naibrd library to set the period.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DIF_PatternGen_StartAddr(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;
bool_t bQuit = FALSE;
uint32_t startAddr = 0;
uint32_t min = 0;
uint32_t max = 0;
uint32_t ModuleID;
uint32_t ModuleVer;
uint32_t ModuleRev;
uint32_t ModInfo_Special;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\nEnter the desired Start Address: 0x");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
startAddr = strtol(((const char *)inputBuffer),NULL,16);
switch (ModuleID)
{
case NAI_MODULE_ID_DF2:
min =naibrd_DIF_GetValidPatternGenStart(ModuleID);
max =naibrd_DIF_GetValidPatternGenEnd(ModuleID);
default:
break;
}
if (startAddr > max || startAddr < min)
printf(" Entry out of range. Range %08X to %08X \n", min, max);
else
{
check_status(naibrd_DIF_SetPatternGenStartAddr(cardIndex,module,startAddr));
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DIF_PatternGen_EndAddr handles the user request to configure the time values for period on the selected
channel and calls the method in the naibrd library to set the period.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DIF_PatternGen_EndAddr(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;
bool_t bQuit = FALSE;
uint32_t endAddr = 0;
uint32_t min = 0;
uint32_t max = 0;
uint32_t ModuleID;
uint32_t ModuleVer;
uint32_t ModuleRev;
uint32_t ModInfo_Special;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\nEnter the desired End Address: 0x");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
endAddr = strtol(((const char *)inputBuffer),NULL,16);;
switch (ModuleID)
{
case NAI_MODULE_ID_DF2:
min =naibrd_DIF_GetValidPatternGenStart(ModuleID);
max =naibrd_DIF_GetValidPatternGenEnd(ModuleID);
default:
break;
}
if (endAddr > max || endAddr < min)
printf(" Entry out of range. Range 0x%08X to 0x%08X \n", min, max);
else
{
check_status(naibrd_DIF_SetPatternGenEndAddr(cardIndex,module,endAddr));
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DIF_PatternGen_Period handles the user request to configure the time values for period on the selected
channel and calls the method in the naibrd library to set the period.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_DIF_PatternGen_Period(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;
bool_t bQuit = FALSE;
float64_t time = 0.0;
float64_t lsb = 0;
float64_t min = 1;
float64_t max = -1;
uint32_t ModuleID;
uint32_t ModuleVer;
uint32_t ModuleRev;
uint32_t ModInfo_Special;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\nEnter the desired period in ms: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
time = atof((const char *)inputBuffer); /*entry in milliseconds*/
lsb = naibrd_DIF_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAI_MODULE_ID_DF2:
min =(float64_t)(0x2u * lsb);
max =(float64_t)(0xFFFFFFFF * lsb);
break;
default:
break;
}
if (time > max || time < min)
printf(" Entry out of range. Range %7.3f to %7.3f ms\n", min, max);
else
{
check_status(naibrd_DIF_SetPatternGenPeriod(cardIndex, module, time));
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Handles the user request to set the burst count value for the number of pulses to be issued upon trigger in
PWM burst mode operation on the selected channel, calling the method in the naibrd library to set the burst number.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DIF_PatternGen_Burstcount(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;
bool_t bQuit = FALSE;
uint32_t burstcount;
uint32_t ModuleID;
uint32_t ModuleVer;
uint32_t ModuleRev;
uint32_t ModInfo_Special;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\nEnter the desired burst count: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
burstcount = atoi((const char *)inputBuffer);
switch (ModuleID)
{
case NAI_MODULE_ID_DF2:
if (burstcount < 1)
{
burstcount = 1; /*minimum count is one*/
printf("Setting burstcount to minimum of 1.\n");
}
check_status(naibrd_DIF_SetPatternGen_BurstNum(cardIndex, module, burstcount));
break;
default:
printf("Unsupported function for this module.\n");
break;
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DIF_PatternGen_Mode handles the user request to select the PWM mode for the selected channel
and calls the method in the naibrd library to set the mode.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DIF_PatternGen_Mode(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;
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n == Pattern Gen Mode Selection == \n C Continuous Pattern Gen mode \n Burst Burst Pattern Gen mode \n\n Type DIF command : ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
if ((toupper(inputBuffer[0]) == 'C'))
{
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_BURST, NAI_DIF_ENHANCE_OP_DISABLE);
}
else if ((toupper(inputBuffer[0]) == 'B'))
{
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_BURST, NAI_DIF_ENHANCE_OP_ENABLE);
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Load_DIF_PatternGenArray loads the pattern from a file and illustrate the methods to call in the naibrd library to
set the pattern data. Channel independent, array covers all channels
</summary>
*/
/**************************************************************************************************************/
nai_status_t Load_DIF_PatternGenArray(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;
bool_t patternLoaded = FALSE;
uint32_t dataPattern[MAX_DIF_PATTERN_GENERATOR_ENTRIES];
int32_t i, j, len;
int32_t entryCnt = 0;
FILE* patternfile = NULL;
int8_t* filename = (int8_t*)"TestRAMPattern.txt";
int8_t buffer[256];
int8_t data[256];
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
for (i = 0; i < MAX_DIF_PATTERN_GENERATOR_ENTRIES; i++)
dataPattern[i] = 0;
patternfile = fopen((const char *)filename,"r");
if (patternfile != NULL)
{
while (fgets((char*)buffer,sizeof(buffer),patternfile))
{
if (entryCnt > MAX_DIF_PATTERN_GENERATOR_ENTRIES)
break;
else
{
/* Entries in the RAMPattern.txt are expected to be data only in hex format, each data value is on a new line */
len = (int32_t)strlen((const char*)buffer);
i = 0;
j = 0;
/* read the addr entry */
while ((buffer[i] != '\n') && (i < len))
{
if (isdigit(buffer[i]) || isalpha(buffer[i]))
data[j++] = buffer[i];
i++;
}
data[j] = '\0';
if (strlen((const char*)data) > 0)
{
dataPattern[entryCnt] = naiapp_utils_HexStrToDecUInt32(data);
entryCnt++;
}
}
}
if (entryCnt > 0)
{
/* Load the pattern into memory */
check_status(naibrd_DIF_SetPatternGenBuf(cardIndex, module, entryCnt, &dataPattern[0]));
patternLoaded = TRUE;
}
else
{
printf("ERROR: No pattern data has been loaded from Pattern file: %s\n", filename);
}
fclose(patternfile);
}
else
printf("ERROR: Unable to open Pattern file: %s\n", filename);
return (patternLoaded) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DIF_ControlEnable handles the user request to change the switch state for the selected
channel and calls the method in the naibrd library to set the state.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DIF_ControlEnable(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;
bool_t bQuit = FALSE;
bool_t bUpdateOutput = FALSE;
nai_dif_state_t enState = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n Type the desired Enable Bit Value, Enable or Disable \n ");
printf(" Enter Enable or Disable: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
switch (toupper(inputBuffer[0]))
{
case 'E':
enState = NAI_DIF_ENHANCE_OP_ENABLE;
bUpdateOutput = TRUE;
break;
case 'D':
enState= NAI_DIF_ENHANCE_OP_DISABLE;
bUpdateOutput = TRUE;
break;
default:
printf("ERROR: Invalid switch state selection\n");
break;
}
}
}
if (!bQuit)
{
if (bUpdateOutput)
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_ENABLE, enState));
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DIF_ControlPause handles the user request to change the switch state for the selected
channel and calls the method in the naibrd library to set the state.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DIF_ControlPause(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;
bool_t bQuit = FALSE;
bool_t bUpdateOutput = FALSE;
nai_dif_state_t enState = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n Type PAUSE or RESUME to Control Pattern Generator Output\n ");
printf(" Enter PAUSE or RESUME: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
switch (toupper(inputBuffer[0]))
{
case 'P':
enState = NAI_DIF_ENHANCE_OP_ENABLE;
bUpdateOutput = TRUE;
break;
case 'R':
enState= NAI_DIF_ENHANCE_OP_DISABLE;
bUpdateOutput = TRUE;
break;
default:
printf("ERROR: Invalid switch state selection\n");
break;
}
}
}
if (!bQuit)
{
if (bUpdateOutput)
check_status(naibrd_DIF_SetPatternGenCtrl(cardIndex,module, NAI_DIF_PATTERN_RAM_CONTROL_PAUSE, enState));
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Display_DIF_PatternGen_Configuration illustrate the methods to call in the naibrd library to retrieve the PWM
configuration settings.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Display_DIF_PatternGen_Configuration(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;
float64_t period;
uint32_t burstnumber;
uint32_t startaddr;
uint32_t endaddr;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n");
printf(" ----------PatternGen Configuration Settings-------------\n");
printf(" Period (ms) Burst Cnt StartAddr EndAddr \n");
printf(" ------------- ----------- ----------- ----------\n");
check_status(naibrd_DIF_GetPatternGenPeriod(cardIndex, module, &period));
printf(" %10.6f ", period);
check_status(naibrd_DIF_GetPatternGen_BurstNum(cardIndex, module, &burstnumber));
printf(" 0x%08X ", burstnumber);
check_status(naibrd_DIF_GetPatternGenStartAddr(cardIndex, module, &startaddr));
printf(" 0x%08X ", startaddr);
check_status(naibrd_DIF_GetPatternGenEndAddr(cardIndex, module, &endaddr));
printf(" 0x%08X ", endaddr);
printf("\n\n");
return NAI_ERROR_UNKNOWN;
}
/**************************************************************************************************************/
/**
<summary>
Display_DSW_Status illustrate the methods to call in the naibrd library to retrieve the status states.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Display_DIF_Status(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;
nai_status_bit_t status;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
/* Available status:
NAI_DIF_STATUS_BIT_LATCHED,
NAI_DIF_STATUS_OVERCURRENT_LATCHED,
NAI_DIF_STATUS_LO_HI_TRANS_LATCHED,
NAI_DIF_STATUS_HI_LO_TRANS_LATCHED,
*/
printf("\n");
printf(" ----------- Status -----------\n");
printf(" BIT OC Lo-Hi Hi-Lo \n");
printf(" ------- -------- ------ ------- \n");
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_BIT_LATCHED, &status));
printf(" %3i ", status);
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_OVERCURRENT_LATCHED, &status));
printf(" %3i ", status);
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_LO_HI_TRANS_LATCHED, &status));
printf(" %3i ", status);
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_HI_LO_TRANS_LATCHED, &status));
printf(" %3i ", status);
printf("\n\n");
return NAI_ERROR_UNKNOWN;
}