Integrator Resources

The official home for NAI Support

Not sure where to start? Try Quick Start Guide or ask a question below!

Toggle Components with Visual Button
JavaScript Form Processing

TTL Pattern Gen

TTL Pattern Gen Sample Application (SSK 2.x)

Overview

The TTL Pattern Gen sample application demonstrates how to configure and output user-defined bit patterns on TTL (Transistor-Transistor Logic) channels using the NAI Software Support Kit (SSK 2.x). It shows how to load pattern data from a file into the module’s pattern RAM, configure the playback period and address range, and control pattern generation output including continuous mode, burst mode, pause, and resume.

Pattern generation is fundamentally different from simple high/low output control. Instead of setting a single static output state, the FPGA on the TTL module steps through a block of RAM containing a sequence of bit patterns at a programmable rate. Each RAM entry defines the simultaneous output state of all channels on the module. This enables you to produce complex, repeatable digital waveforms — test patterns, stimulus sequences, or protocol-level bit streams — without real-time host intervention.

Supported modules: TL1, TL2.

For the SSK 1.x version, see TTL PatternGenerator (SSK 1.x). For detailed register-level information, consult the TL1 Manual.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a supported TTL module installed (TL1 or TL2).

  • SSK 2.x installed on your development host.

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

  • A pattern data file (TestRAMPattern.txt) in the working directory, containing hex-encoded pattern values (one per line). See Loading Pattern Data for the expected format.

  • Appropriate output connections or a load on the TTL channel(s) under test.

How to Run

Launch the ttl_pattern_gen executable from your build output directory. On startup the application looks for a configuration file (default_TTL_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, select a channel, and the application presents a pattern generator operations menu where you configure the mode, addresses, period, load data, and enable or pause output.

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

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

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

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

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

  4. Retrieve the module ID with naibrd_GetModuleName() so downstream code can verify the module is a supported TTL type.

#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t TTL_PatternGenerator(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_TTL_CARD_INDEX, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt,
               DEF_TTL_MODULE, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module,
                  &moduleID));
               if ((moduleID != 0))
               {
                  Run_TTL_PatternGenerator(cardIndex, module, moduleID);
                  naiif_printf("\r\nType Q to quit or Enter to "
                     "continue:\r\n");
                  stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer),
                     NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               }
            }
         }
      }
   }

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

   return 0;
}

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

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

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

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

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

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

static int32_t Run_TTL_PatternGenerator(int32_t cardIndex,
   int32_t module, uint32_t modid)
{
   bool_t bQuit = NAI_FALSE;
   int32_t maxchannel;

   if (!bQuit)
   {
      maxchannel = naibrd_TTL_GetChannelCount(modid);
      if (maxchannel == 0)
      {
         naiif_printf(
            " *** Module selection not recognized as TTL module. "
            "***\r\n\r\n");
      }
      else
      {
         Cfg_TTL_PatternGen_Channel(cardIndex, module, modid,
            maxchannel);
      }
   }
   return cardIndex;
}
Important

Common connection errors you may encounter at this stage:

  • No board found — verify that the board is powered on and physically connected. Check that the configuration file lists the correct interface and address.

  • Connection timeout — confirm network settings (for Ethernet connections) or bus configuration (for PCI/PCIe). Firewalls and IP mismatches are frequent causes.

  • Invalid card or module index — the card index is zero-based; the module number is one-based. Ensure the values you pass match your hardware setup.

  • Module not recognized as TTL — naibrd_TTL_GetChannelCount() returned zero. The slot does not contain a TL1 or TL2 module.

Program Structure

Entry Point

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

The startup flow is the same in both cases:

  1. Attempt to load the saved configuration file via naiapp_RunBoardMenu(DEF_CONFIG_FILE).

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

  3. Validate the module with naibrd_TTL_GetChannelCount() and, if valid, enter Cfg_TTL_PatternGen_Channel() for the interactive session.

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

Application Parameters

The Cfg_TTL_PatternGen_Channel() function populates an naiapp_AppParameters_t struct that is passed to every command handler:

naiapp_AppParameters_t  ttlparams;
p_naiapp_AppParameters_t ttlParams = &ttlparams;
ttlParams->cardIndex = cardIndex;
ttlParams->module = module;
ttlParams->channel = chan;

Command Loop

After selecting a channel, the application enters a command loop, displaying the channel configuration and dispatching user commands:

Command Description

Mode

Select continuous or burst pattern generation mode

StartAddr

Set the start address in pattern RAM

EndAddr

Set the end address in pattern RAM

Period

Set the pattern generation period (ms)

Count

Set the burst count

Load

Load pattern data from file into RAM

CONtrol

Enable or disable pattern generator output

Pause/Play

Pause or resume pattern generation

Reset

Reset current channel to standard input mode and disable all pattern controls

RAll

Reset all channels to standard input mode and reset timers

SEtall

Set all channels to pattern generator output mode

Display

Display current pattern generator configuration (period, burst count, start/end addresses)

How Pattern Generation Works

Understanding the hardware pattern generation mechanism is essential for using this sample effectively.

TTL 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_TTL_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.

Pattern Generator Mode Selection

The sample supports two pattern generation modes: continuous and burst.

Continuous Mode

In continuous mode, the pattern generator cycles through the pattern RAM addresses repeatedly until explicitly stopped. To configure continuous mode, set the enhanced mode to pattern RAM output and disable the burst control:

check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan,
   NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM));
naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_BURST, NAIBRD_TTL_DISABLE);

Burst Mode

In burst mode, the pattern generator cycles through the pattern for a specified number of iterations (the burst count) and then stops. Enable the burst control bit:

check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan,
   NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM));
naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_BURST, NAIBRD_TTL_ENABLE);

To select the mode in your own application, call naibrd_TTL_SetPatternGenCtrl() with NAIBRD_TTL_CTRL_PATTERN_BURST:

  • Pass NAIBRD_TTL_DISABLE for continuous mode — the hardware loops through the pattern indefinitely until you disable output.

  • Pass NAIBRD_TTL_ENABLE for 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 digital patterns. Burst mode is useful when you need a finite number of pattern cycles, for example to send a specific number of stimulus pulses.

Address and Period Configuration

Start and End Address

The pattern generator steps through a range of 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.

check_status(naibrd_TTL_SetPatternGenStartAddr(cardIndex, module,
   startAddr));
check_status(naibrd_TTL_SetPatternGenEndAddr(cardIndex, module,
   endAddr));

The addresses are specified in hexadecimal. The valid range is module-specific — consult your module’s manual for the exact valid address bounds for your hardware.

Period

The period controls how fast the pattern generator steps through the RAM. The value is specified in milliseconds. The valid range depends on the module’s timebase LSB (least significant bit), which is retrieved with naibrd_TTL_GetTimebaseLSB():

time = atof((const char *)inputBuffer); /* entry in milliseconds */
lsb = naibrd_TTL_GetTimebaseLSB(ModuleID);
min = (float64_t)(0x2u * lsb);
max = (float64_t)(0xFFFFFFFF * lsb);

if (time > max || time < min)
   naiif_printf(" Entry out of range.  Range %7.3f to %7.3f ms\r\n",
      min, max);
else
   check_status(naibrd_TTL_SetPatternGenPeriod(cardIndex, module, time));

The minimum period is 2 * LSB and the maximum is 0xFFFFFFFF * LSB. To set the period in your own application, call naibrd_TTL_SetPatternGenPeriod() with the desired period in milliseconds.

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.

Burst Count

The burst count specifies how many times the pattern repeats in burst mode. The minimum value is 1:

burstcount = atoi((const char *)inputBuffer);
if (burstcount < 1)
{
   burstcount = 1; /* minimum count is one */
   naiif_printf("Setting burstcount to minimum of 1.\r\n");
}
check_status(naibrd_TTL_SetPatternGen_BurstNum(cardIndex, module,
   burstcount));

The burst count only takes effect when the module is in burst mode (see Pattern Generator Mode Selection).

Loading Pattern Data

The Load_TTL_PatternGenArray() function reads pattern data from a text file (TestRAMPattern.txt) and writes it to the module’s pattern RAM.

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_TTL_PATTERN_GENERATOR_ENTRIES limit).

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 function reads the file line by line, parses each hex value, and writes the entire array to the pattern RAM in a single bulk API call:

uint32_t dataPattern[MAX_TTL_PATTERN_GENERATOR_ENTRIES];
int32_t entryCnt = 0;
int8_t* filename = (int8_t*)"TestRAMPattern.txt";

for (i = 0; i < MAX_TTL_PATTERN_GENERATOR_ENTRIES; i++)
   dataPattern[i] = 0;

patternfile = naiif_fopen((const char *)filename, "r");
if (patternfile != NULL)
{
   while (naiif_fgets_file((char*)buffer, sizeof(buffer), patternfile))
   {
      if (entryCnt > MAX_TTL_PATTERN_GENERATOR_ENTRIES)
         break;
      /* Parse hex data from each line */
      /* ... character parsing ... */
      dataPattern[entryCnt] = naiapp_utils_HexStrToDecUInt32(data);
      entryCnt++;
   }

   if (entryCnt > 0)
   {
      check_status(naibrd_TTL_SetPatternGenBuf(cardIndex, module,
         entryCnt, &dataPattern[0]));
   }
   naiif_fclose(patternfile);
}

The key API call is naibrd_TTL_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

  • "Unable to open Pattern file: TestRAMPattern.txt" — the file is not in the current working directory. Copy the file to the same directory as the executable, or launch the executable from the directory containing the file.

  • "No pattern data has been loaded from Pattern file" — the file exists but contains no parseable hex entries. Verify each line contains a valid hexadecimal value.

  • Output pattern does not match expected behavior — verify that the bit positions in your data correspond to the correct channels (bit 0 = channel 1). Also verify that the start and end addresses bracket all loaded data.

  • Pattern RAM is channel-independent — the pattern data array covers all channels on the module simultaneously. Each bit in a pattern word corresponds to one channel’s output state.

Controlling Pattern Output

Enable and Disable

To start pattern generation, enable the pattern generator control:

check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_ENABLE, NAIBRD_TTL_ENABLE));

To stop pattern generation:

check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_ENABLE, NAIBRD_TTL_DISABLE));

Before enabling output, make sure you have:

  1. Set the channel to output pattern RAM mode (naibrd_TTL_SetEnhancedMode() with NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM).

  2. Loaded pattern data into RAM (naibrd_TTL_SetPatternGenBuf()).

  3. Set the start and end addresses to bracket your data.

  4. Set the pattern period.

  5. Selected the mode (continuous or burst).

Pause and Resume

To temporarily suspend pattern output without disabling it:

/* Pause */
check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_PAUSE, NAIBRD_TTL_ENABLE));

/* Resume */
check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_PAUSE, NAIBRD_TTL_DISABLE));

Note that "enable" the pause bit means paused, and "disable" the pause bit means running. When paused, the outputs hold their current state. When resumed, playback continues from where it left off.

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_TTL_SetEnhancedMode(cardIndex, module, chan,
   NAIBRD_TTL_MODE_STD_INPUT_OUTPUT));
check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_ENABLE, NAIBRD_TTL_DISABLE));
check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_BURST, NAIBRD_TTL_DISABLE));
check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_PAUSE, NAIBRD_TTL_DISABLE));

This sequence 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 on every channel and additionally resets each channel’s timer using naibrd_TTL_Reset():

for (ch_loop = 1; ch_loop <= naibrd_TTL_GetChannelCount(ModuleID);
   ch_loop++)
{
   check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan,
      NAIBRD_TTL_MODE_STD_INPUT_OUTPUT));
   check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
      NAIBRD_TTL_CTRL_PATTERN_ENABLE, NAIBRD_TTL_DISABLE));
   check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
      NAIBRD_TTL_CTRL_PATTERN_BURST, NAIBRD_TTL_DISABLE));
   check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module,
      NAIBRD_TTL_CTRL_PATTERN_PAUSE, NAIBRD_TTL_DISABLE));
   check_status(naibrd_TTL_Reset(cardIndex, module, ch_loop,
      NAIBRD_TTL_RESET_TIMER_ONLY));
}

The naibrd_TTL_Reset() call with NAIBRD_TTL_RESET_TIMER_ONLY resets the channel’s internal timer/counter without affecting other channel registers. This ensures the pattern generator timing hardware is in a clean state.

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 <= naibrd_TTL_GetChannelCount(ModuleID);
   ch_loop++)
{
   check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, ch_loop,
      NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM));
}

This sets each channel’s enhanced mode to pattern RAM output. 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

Channel Configuration Display

Each time the command menu is shown, the application calls Display_TTL_PatternGen_ChannelCfg() to display the current channel state. This function reads the following values using Get API calls:

check_status(naibrd_TTL_GetIOFormat(cardIndex, module, chan, &ioformat));
check_status(naibrd_TTL_GetOutputState(cardIndex, module, chan,
   &outputstate));
check_status(naibrd_TTL_GetInputState(cardIndex, module, chan,
   &inputstate));
check_status(naibrd_TTL_GetEnhancedMode(cardIndex, module, chan,
   &opmode));
check_status(naibrd_TTL_GetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_ENABLE, &enablebit));
check_status(naibrd_TTL_GetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_BURST, &burstbit));
check_status(naibrd_TTL_GetPatternGenCtrl(cardIndex, module,
   NAIBRD_TTL_CTRL_PATTERN_PAUSE, &pausebit));

This displays the I/O format (input/output), output state (high/low), input state, current enhanced mode, and pattern generation control status (enabled/disabled, continuous/burst, paused/running). Use the corresponding Get API calls in your own application to verify configuration before enabling pattern output.

Pattern Generation Configuration

The Display command reads back and displays the current pattern generation settings using Display_TTL_PatternGen_Configuration():

check_status(naibrd_TTL_GetPatternGenPeriod(cardIndex, module, &period));
check_status(naibrd_TTL_GetPatternGen_BurstNum(cardIndex, module,
   &burstnumber));
check_status(naibrd_TTL_GetPatternGenStartAddr(cardIndex, module,
   &startaddr));
check_status(naibrd_TTL_GetPatternGenEndAddr(cardIndex, module,
   &endaddr));

To read back the configuration in your own application, use the Get counterparts of the Set functions: naibrd_TTL_GetPatternGenPeriod(), naibrd_TTL_GetPatternGen_BurstNum(), naibrd_TTL_GetPatternGenStartAddr(), and naibrd_TTL_GetPatternGenEndAddr(). This is useful for verifying that your configuration was applied correctly.

Troubleshooting Reference

Symptom Possible Cause and Resolution

No output observed

Pattern generator is not enabled. Call naibrd_TTL_SetPatternGenCtrl() with NAIBRD_TTL_CTRL_PATTERN_ENABLE set to NAIBRD_TTL_ENABLE. Also verify that the channel enhanced mode is set to NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM and that pattern data has been loaded.

Pattern file not found

Ensure TestRAMPattern.txt is in the application’s working directory.

Output is static (not cycling)

Period may be set to zero or an invalid value. Verify with naibrd_TTL_GetPatternGenPeriod().

Module not recognized

naibrd_TTL_GetChannelCount() returned zero. Verify the module type in the selected slot is TL1 or TL2.

"Entry out of range" for period

The period is below the module minimum or above the maximum. Query the timebase LSB with naibrd_TTL_GetTimebaseLSB(). Minimum = 2 * LSB, maximum = 0xFFFFFFFF * LSB.

Burst mode runs forever

Burst control bit is not enabled. Call naibrd_TTL_SetPatternGenCtrl() with NAIBRD_TTL_CTRL_PATTERN_BURST set to NAIBRD_TTL_ENABLE.

Pattern runs once and stops (unexpected)

Module is in burst mode with burst count = 1. Switch to continuous mode or increase the burst count.

Pattern output paused unexpectedly

The pause bit may be set. Call naibrd_TTL_SetPatternGenCtrl() with NAIBRD_TTL_CTRL_PATTERN_PAUSE set to NAIBRD_TTL_DISABLE to resume.

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.

Full Source

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

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

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

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

static const int8_t *DEF_CONFIG_FILE = (const int8_t *)"default_TTL_PatternGenerator.txt";
#define MAX_TTL_PATTERN_GENERATOR_ENTRIES    4092
/* Function prototypes */
static int32_t Run_TTL_PatternGenerator(int32_t cardIndex, int32_t module, uint32_t modid);
static void Cfg_TTL_PatternGen_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
static void Display_TTL_PatternGen_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan);
static void Verify_TTL_ParamCnt(int32_t paramCnt);
static nai_status_t Configure_TTL_PatternGen_StartAddr(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_TTL_PatternGen_EndAddr(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_TTL_PatternGen_Period(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_TTL_PatternGen_Burstcount(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_TTL_PatternGen_Mode(int32_t paramCnt, int32_t* p_params);
static nai_status_t Load_TTL_PatternGenArray(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_TTL_ControlEnable(int32_t paramCnt, int32_t* p_params);
static nai_status_t Configure_TTL_ControlPause(int32_t paramCnt, int32_t* p_params);
static nai_status_t Display_TTL_PatternGen_Configuration(int32_t paramCnt, int32_t* p_params);

static const int32_t DEF_TTL_CARD_INDEX = 0;
static const int32_t DEF_TTL_MODULE = 1;
static const int32_t DEF_TTL_CHANNEL = 1;

#define MAX_TTL_PATTERN_GENERATOR_ENTRIES    4092

/****** Command Table ******/
enum ttl_patterngen_commands
{
   TTL_PATTERNGEN_CMD_MODE,
   TTL_PATTERNGEN_CMD_STARTADDR,
   TTL_PATTERNGEN_CMD_ENDADDR,
   TTL_PATTERNGEN_CMD_PERIOD,
   TTL_PATTERNGEN_CMD_BURSTCOUNT,
   TTL_PATTERNGEN_CMD_LOAD_DATA,
   TTL_PATTERNGEN_CMD_ENABLE,
   TTL_PATTERNGEN_CMD_PAUSE_DATA,
   TTL_PATTERNGEN_CMD_RESETMODE,
   TTL_PATTERNGEN_CMD_RESETALL,
   TTL_PATTERNGEN_CMD_SETALL,
   TTL_PATTERNGEN_CMD_DISP,
   TTL_PATTERNGEN_CMD_COUNT
};

/****** Command Tables ******/
static naiapp_cmdtbl_params_t TTL_PatternGen_MenuCmds[] = {

   {"Mode",          "TTL Select Mode",                                TTL_PATTERNGEN_CMD_MODE,              Configure_TTL_PatternGen_Mode},
   {"StartAddr",     "TTL Set Start Address",                          TTL_PATTERNGEN_CMD_STARTADDR,         Configure_TTL_PatternGen_StartAddr},
   {"EndAddr",       "TTL Set End Address",                            TTL_PATTERNGEN_CMD_ENDADDR,           Configure_TTL_PatternGen_EndAddr},
   {"Period",        "TTL Pattern Generator Period",                   TTL_PATTERNGEN_CMD_PERIOD,            Configure_TTL_PatternGen_Period},
   {"Count",         "TTL Pattern Generator Burst count",              TTL_PATTERNGEN_CMD_BURSTCOUNT,        Configure_TTL_PatternGen_Burstcount},
   {"Load",          "TTL Load Pattern Generator Data",                TTL_PATTERNGEN_CMD_LOAD_DATA,         Load_TTL_PatternGenArray},
   {"CONtrol",       "TTL Enable or Disable Pattern Generator Output", TTL_PATTERNGEN_CMD_ENABLE,            Configure_TTL_ControlEnable},
   {"Pause/Play",    "TTL Pause or Resume Pattern Gen Output",         TTL_PATTERNGEN_CMD_PAUSE_DATA,        Configure_TTL_ControlPause},
   {"Reset",         "TTL Reset Chan Mode, Input",                     TTL_PATTERNGEN_CMD_RESETMODE,         NULL},
   {"RAll",          "TTL Reset All Channels, Input",                  TTL_PATTERNGEN_CMD_RESETALL,          NULL},
   {"SEtall",        "TTL Set All Channels to Pattern Gen",            TTL_PATTERNGEN_CMD_SETALL,            NULL},
   {"Display",       "TTL Display channel Pattern Generator Info",     TTL_PATTERNGEN_CMD_DISP,              Display_TTL_PatternGen_Configuration},
};
/**************************************************************************************************************/
/**
<summary>
The purpose of the TTL_PatternGen is to illustrate the methods to call in the naibrd library to perform configuration
 setup for output in PWM operation mode.  Pulse period, pulse width, pulse polarity settings are 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 TTL routines.
 - ClearDeviceCfg
 - QuerySystemCfg
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - SaveDeviceCfg
</summary>
*/
/**************************************************************************************************************/
#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t TTL_PatternGenerator(void)
#else
int32_t main(void)
#endif
{
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   bool_t stop = NAI_FALSE;
   uint32_t moduleID;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == (bool_t)NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         /* Select Card Index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), DEF_TTL_CARD_INDEX, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Select Module */
            stop = naiapp_query_ModuleNumber(moduleCnt, DEF_TTL_MODULE, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               if ((moduleID != 0))
               {
                  Run_TTL_PatternGenerator(cardIndex, module, moduleID);
                  naiif_printf("\r\nType Q to quit or Enter to continue:\r\n");
                  stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
               }
            }
         }
      }
   }

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

   return 0;

}
/**************************************************************************************************************/
/**
 * <summary>
 * Verify_TTL_ParamCnt verifies parameter count and displays error message if invalid.
 * </summary>
 */
 /**************************************************************************************************************/
static void Verify_TTL_ParamCnt(int32_t paramCnt)
{
   if (paramCnt != APP_PARAM_COUNT)
   {
      naiif_printf(" *** Parameter count specified is incorrect!!! ***\r\n");
   }
}
/**************************************************************************************************************/
/**
<summary>
Run_TTL_PatternGen prompts the user for the card, module and channel to use for the application and calls
Cfg_TTL_PatternGen_Channel if the card, module, channel is valid for as a ttl module.
</summary>
*/
/**************************************************************************************************************/
static int32_t Run_TTL_PatternGenerator(int32_t cardIndex, int32_t module, uint32_t modid)
{
   bool_t bQuit = NAI_FALSE;
   int32_t maxchannel;

   if (!bQuit)
   {
      maxchannel = naibrd_TTL_GetChannelCount(modid);
      if (maxchannel == 0)
      {
         naiif_printf(" *** Module selection not recognized as TTL module. ***\r\n\r\n");
      }
      else
      {
         Cfg_TTL_PatternGen_Channel(cardIndex, module, modid, maxchannel);
      }
   }
   return cardIndex;
}

/**************************************************************************************************************/
/**
<summary>
Cfg_TTL_PatternGen_Channel handles calling the Display_TTL_PWM_ChannelCfg routine to display the ttl channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
static void Cfg_TTL_PatternGen_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 ch_loop;
   int32_t cmd;
   nai_status_t status = NAI_SUCCESS;
   naiapp_AppParameters_t  ttlparams;
   p_naiapp_AppParameters_t ttlParams = &ttlparams;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

      naiapp_utils_LoadParamMenuCommands(TTL_PATTERNGEN_CMD_COUNT, TTL_PatternGen_MenuCmds);
      while (bContinue)
      {
         Display_TTL_PatternGen_ChannelCfg(cardIndex, module, chan);
         naiapp_display_ParamMenuCommands((int8_t *)"TTL PatternGen Operation Menu");
         naiif_printf("\r\nType TTL command or %c to quit : ", NAI_QUIT_CHAR);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
               if (bCmdFound)
               {
                  switch (cmd)
                  {
                     case TTL_PATTERNGEN_CMD_MODE:
                     case TTL_PATTERNGEN_CMD_STARTADDR:
                     case TTL_PATTERNGEN_CMD_ENDADDR:
                     case TTL_PATTERNGEN_CMD_PERIOD:
                     case TTL_PATTERNGEN_CMD_BURSTCOUNT:
                     case TTL_PATTERNGEN_CMD_LOAD_DATA:
                     case TTL_PATTERNGEN_CMD_ENABLE:
                     case TTL_PATTERNGEN_CMD_PAUSE_DATA:
                     case TTL_PATTERNGEN_CMD_DISP:
                        TTL_PatternGen_MenuCmds[cmd].func(APP_PARAM_COUNT,(int32_t*)ttlParams);
                        break;
                     case TTL_PATTERNGEN_CMD_RESETMODE:
                     {
                        status |= check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_STD_INPUT_OUTPUT));
                        status |= check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_ENABLE, NAIBRD_TTL_DISABLE));
                        status |= check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_BURST, NAIBRD_TTL_DISABLE));
                        status |= check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_PAUSE, NAIBRD_TTL_DISABLE));
                        if (status == NAI_SUCCESS)
                           naiif_printf("Reset completed \r\n");
                        else
                           naiif_printf("Error %2X on set \r\n", status);
                     }
                        break;
                     case TTL_PATTERNGEN_CMD_RESETALL:
                     {
                        for (ch_loop = 1; ch_loop <= naibrd_TTL_GetChannelCount(ModuleID); ch_loop++)
                        {
                           status |= check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_STD_INPUT_OUTPUT));
                           status |= check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_ENABLE, NAIBRD_TTL_DISABLE));
                           status |= check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_BURST, NAIBRD_TTL_DISABLE));
                           status |= check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_PAUSE, NAIBRD_TTL_DISABLE));
                           status |= check_status(naibrd_TTL_Reset(cardIndex, module, ch_loop, NAIBRD_TTL_RESET_TIMER_ONLY));
                        }
                        if (status == NAI_SUCCESS)
                           naiif_printf("Reset All completed \r\n");
                        else
                           naiif_printf("Error %2X on set \r\n", status);
                     }
                     break;
                     case TTL_PATTERNGEN_CMD_SETALL:
                     {
                        for (ch_loop = 1; ch_loop <= naibrd_TTL_GetChannelCount(ModuleID); ch_loop++)
                        {
                           status |= check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, ch_loop, NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM));
                        }
                        if (status == NAI_SUCCESS)
                           naiif_printf("Set on all channels completed \r\n");
                        else
                           naiif_printf("Error %2X on set\r\n", status);
                     }
                     break;

                  default:
                     naiif_printf("Invalid command entered\r\n");
                     break;
                  }
               }
               else
                  naiif_printf("Invalid command entered\r\n");
            }
         }
         else
            bContinue = NAI_FALSE;
      }
   }
}

/**************************************************************************************************************/
/**
<summary>
Display_TTL_PWM_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for PWM operation.
</summary>
*/
/**************************************************************************************************************/
static void Display_TTL_PatternGen_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan)
{
   naibrd_ttl_ioformat_t ioformat = 0;
   naibrd_ttl_state_t outputstate = 0;
   naibrd_ttl_state_t inputstate = 0;
   naibrd_ttl_enhanced_mode_t opmode = 0;
   naibrd_ttl_enable_type_t enablebit = 0;
   naibrd_ttl_enable_type_t burstbit = 0;
   naibrd_ttl_enable_type_t pausebit = 0;
   check_status(naibrd_TTL_GetIOFormat(cardIndex, module, chan, &ioformat));
   check_status(naibrd_TTL_GetOutputState(cardIndex, module, chan, &outputstate));
   check_status(naibrd_TTL_GetInputState(cardIndex, module, chan, &inputstate));
   check_status(naibrd_TTL_GetEnhancedMode(cardIndex, module, chan, &opmode));
   check_status(naibrd_TTL_GetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_ENABLE, &enablebit));
   check_status(naibrd_TTL_GetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_BURST, &burstbit));
   check_status(naibrd_TTL_GetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_PAUSE, &pausebit));

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

   /*read PWM configuration values here, Period, Pulsewidth, Continuous/Burst Mode, */
   {
      naiif_printf("  I/O       Output    Input                                                                 \r\n");
      naiif_printf(" Format     State     State        Enhanced Mode Selection            Pattern Gen Mode      \r\n");
      naiif_printf("---------  ------   ----------- -----------------------------    ---------------------------\r\n");
   }

   /*display configuration settings here- */
   switch (ioformat)
   {
      case NAIBRD_TTL_IOFORMAT_INPUT:
         naiif_printf("  Input   ");
         break;
      case NAIBRD_TTL_IOFORMAT_OUTPUT:
         naiif_printf(" Output "); /*may want add check for proper value depending on whether gen3 or gen5; for now, assume it correctly matches module*/
         break;
      default:
         naiif_printf(" Unknown  ");
      break;
   }
   switch (outputstate)
   {
   case NAIBRD_TTL_STATE_LO:
      naiif_printf("  LOW Set ");
      break;
   case NAIBRD_TTL_STATE_HI:
      naiif_printf(" HIGH Set ");
      break;
   default:
      naiif_printf(" Unknown  ");
      break;
   }

   switch (inputstate)
   {
   case NAIBRD_TTL_STATE_LO:
      naiif_printf(" LOW Input  ");
      break;
   case NAIBRD_TTL_STATE_HI:
      naiif_printf("HIGH Input  ");
      break;
   default:
      naiif_printf("Unknown     ");
      break;
   }

   switch (opmode)
   {
   case NAIBRD_TTL_MODE_STD_INPUT_OUTPUT:
      naiif_printf("TTL_MODE_ENHANCED_INPUT   ");
      break;
   case NAIBRD_TTL_MODE_MEASURE_HIGH_TIME:
      naiif_printf("TTL_MODE_MEASURE_HIGH_TIME   ");
      break;
   case NAIBRD_TTL_MODE_MEASURE_LOW_TIME:
      naiif_printf("TTL_MODE_MEASURE_LOW_TIME   ");
      break;
   case NAIBRD_TTL_MODE_TIMESTAMP_RISING_EDGES:
      naiif_printf("TTL_MODE_TIMESTAMP_RISING_EDGES   ");
      break;
   case NAIBRD_TTL_MODE_TIMESTAMP_FALLING_EDGES:
      naiif_printf("TTL_MODE_TIMESTAMP_FALLING_EDGES   ");
      break;
   case NAIBRD_TTL_MODE_TIMESTAMP_ALL_EDGES:
      naiif_printf("TTL_MODE_TIMESTAMP_ALL_EDGES   ");
      break;
   case NAIBRD_TTL_MODE_COUNT_RISING_EDGES:
      naiif_printf("TTL_MODE_COUNT_RISING_EDGES   ");
      break;
   case NAIBRD_TTL_MODE_COUNT_FALLING_EDGES:
      naiif_printf("TTL_MODE_COUNT_FALLING_EDGES   ");
      break;
   case NAIBRD_TTL_MODE_COUNT_ALL_EDGES:
      naiif_printf("TTL_MODE_COUNT_ALL_EDGES   ");
      break;
   case NAIBRD_TTL_MODE_MEASURE_PERIOD_RISING_EDGE:
      naiif_printf("TTL_MODE_MEASURE_PERIOD_FROM_RISING_EDGE   ");
      break;
   case NAIBRD_TTL_MODE_MEASURE_FREQUENCY:
      naiif_printf("TTL MODE Interval Counter   ");
      break;
   case NAIBRD_TTL_MODE_OUTPUT_PWM_FOREVER:
      naiif_printf("TTL MODE PWM Continuous  ");
      break;
   case NAIBRD_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES:
      naiif_printf("TTL MODE PWM Burst   ");
      break;
   case NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM:
      naiif_printf("TTL MODE PATTERN_RAM   ");
      break;
   default:
      naiif_printf("Unknown    ");
      break;
   }


   switch (enablebit)
   {
      case NAIBRD_TTL_DISABLE:
         naiif_printf("  Disabled");
         break;
      case NAIBRD_TTL_ENABLE:
         naiif_printf("   Enabled");
         break;
         /* undefined value read back */
      default:
         naiif_printf("   UNK  ");
         break;
   }
   switch (burstbit)
   {
      case NAIBRD_TTL_DISABLE:
         naiif_printf(" Continuous Mode");
         break;
      case NAIBRD_TTL_ENABLE:
         naiif_printf(" Burst Mode");
         break;
         /* undefined value read back */
      default:
         naiif_printf(" UNK  ");
         break;
   }
   switch (pausebit)
   {
      case NAIBRD_TTL_DISABLE:
         break;
      case NAIBRD_TTL_ENABLE:
         naiif_printf(" PAUSED");
         break;
         /* undefined value read back */
      default:
         naiif_printf(" UNK  ");
         break;
   }
}

/**************************************************************************************************************/
/**
<summary>
Configure_TTL_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_TTL_PatternGen_StartAddr(int32_t paramCnt, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   uint32_t startAddr = 0;
   nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
   p_naiapp_AppParameters_t ttlparams = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = ttlparams->cardIndex;
   int32_t module = ttlparams->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   Verify_TTL_ParamCnt(paramCnt);

   naiif_printf("\r\nEnter the desired Start Address: 0x");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         startAddr = strtol(((const char *)inputBuffer), NULL, 16);
         status = check_status(naibrd_TTL_SetPatternGenStartAddr(cardIndex, module, startAddr));
      }
   }
   return status;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_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_TTL_PatternGen_EndAddr(int32_t paramCnt, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   uint32_t endAddr = 0;
   nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
   p_naiapp_AppParameters_t ttlparams = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = ttlparams->cardIndex;
   int32_t module = ttlparams->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   Verify_TTL_ParamCnt(paramCnt);

   naiif_printf("\r\nEnter the desired End Address: 0x");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         endAddr = strtol(((const char *)inputBuffer), NULL, 16);;
         status = check_status(naibrd_TTL_SetPatternGenEndAddr(cardIndex, module, endAddr));
      }
   }
   return status;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_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>
*/
/**************************************************************************************************************/
static nai_status_t Configure_TTL_PatternGen_Period(int32_t paramCnt, int32_t* p_params)
{
   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;
   nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
   p_naiapp_AppParameters_t ttlparams = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = ttlparams->cardIndex;
   int32_t module = ttlparams->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   Verify_TTL_ParamCnt(paramCnt);

   naiif_printf("\r\nEnter the desired period in ms: ");
   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); /*entry in milliseconds*/
         lsb = naibrd_TTL_GetTimebaseLSB(ModuleID);
         min = (float64_t)(0x2u * lsb);
         max = (float64_t)(0xFFFFFFFF * lsb);

         if (time > max || time < min)
            naiif_printf(" Entry out of range.  Range %7.3f to %7.3f ms\r\n", min, max);
         else
         {
            status = check_status(naibrd_TTL_SetPatternGenPeriod(cardIndex, module, time));
         }
      }
   }
   return status;
}
/**************************************************************************************************************/
/**
<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_TTL_PatternGen_Burstcount(int32_t paramCnt, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   uint32_t burstcount;
   nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
   p_naiapp_AppParameters_t ttlparams = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = ttlparams->cardIndex;
   int32_t module = ttlparams->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   Verify_TTL_ParamCnt(paramCnt);

   naiif_printf("\r\nEnter the desired burst count: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         burstcount = atoi((const char *)inputBuffer);
         if (burstcount < 1)
         {
            burstcount = 1; /*minimum count is one*/
            naiif_printf("Setting burstcount to minimum of 1.\r\n");
         }
         status = check_status(naibrd_TTL_SetPatternGen_BurstNum(cardIndex, module, burstcount));
      }
   }
   return status;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_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_TTL_PatternGen_Mode(int32_t paramCnt, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
   p_naiapp_AppParameters_t ttlparams = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = ttlparams->cardIndex;
   int32_t module = ttlparams->module;
   int32_t chan = ttlparams->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   Verify_TTL_ParamCnt(paramCnt);

   naiif_printf("\r\n == Pattern Gen Mode Selection == \r\n C  Continuous Pattern Gen mode \r\n Burst  Burst Pattern Gen mode  \r\n\r\n Type TTL 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_TTL_SetEnhancedMode(cardIndex, module, chan , NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM));
            status = check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_BURST, NAIBRD_TTL_DISABLE));
         }
         else if ((toupper(inputBuffer[0]) == 'B'))
         {
            check_status(naibrd_TTL_SetEnhancedMode(cardIndex, module, chan, NAIBRD_TTL_MODE_OUTPUT_PATTERN_RAM));
           status = check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_BURST, NAIBRD_TTL_ENABLE));
         }

      }
   }
   return status;
}
/**************************************************************************************************************/
/**
<summary>
Load_TTL_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>
*/
/**************************************************************************************************************/
static nai_status_t Load_TTL_PatternGenArray(int32_t paramCnt, int32_t* p_params)
{
   uint32_t dataPattern[MAX_TTL_PATTERN_GENERATOR_ENTRIES];
   int32_t i, j, len;
   int32_t entryCnt = 0;
   FILE* patternfile = NULL;
   int8_t* filename = (int8_t*)"TestRAMPattern.txt";
   int8_t data[256];
   int8_t buffer[256];
   nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
   p_naiapp_AppParameters_t ttlparams = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = ttlparams->cardIndex;
   int32_t module = ttlparams->module;
   Verify_TTL_ParamCnt(paramCnt);
   for (i = 0; i < MAX_TTL_PATTERN_GENERATOR_ENTRIES; i++)
      dataPattern[i] = 0;

   patternfile = naiif_fopen((const char *)filename, "r");
   if (patternfile != NULL)
   {
      while (naiif_fgets_file((char*)buffer, sizeof(buffer), patternfile))
      {
         if (entryCnt > MAX_TTL_PATTERN_GENERATOR_ENTRIES)
            break;
         else
         {
            /* Entries in the RAMPattern.txt are expected to be addr,data */
            len = (int32_t)strlen((const char*)buffer);
            i = 0;
            j = 0;
            /* read the data entry */
            while (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 */
         status = check_status(naibrd_TTL_SetPatternGenBuf(cardIndex, module, entryCnt, &dataPattern[0]));
      }
      else
      {
         naiif_printf("ERROR: No pattern data has been loaded from Pattern file: %s\r\n", filename);
      }
      naiif_fclose(patternfile);
   }
   else
      naiif_printf("ERROR: Unable to open Pattern file: %s\r\n", filename);

   return status;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_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_TTL_ControlEnable(int32_t paramCnt, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   bool_t bUpdateOutput = NAI_FALSE;
   naibrd_ttl_enable_type_t enState = 0;
   nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
   p_naiapp_AppParameters_t ttlparams = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = ttlparams->cardIndex;
   int32_t module = ttlparams->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   Verify_TTL_ParamCnt(paramCnt);

   /* Set the switch state (open or closed).
   */
   naiif_printf("\r\n Type the desired Enable Bit Value, Enable or Disable \r\n ");
   naiif_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 = NAIBRD_TTL_ENABLE;
            bUpdateOutput = NAI_TRUE;
            break;
         case 'D':
            enState = NAIBRD_TTL_DISABLE;
            bUpdateOutput = NAI_TRUE;
            break;
         default:
            naiif_printf("ERROR: Invalid switch state selection\r\n");
            break;
         }
      }
   }
   if (!bQuit)
   {
      if (bUpdateOutput)
         status = check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_ENABLE, enState));
   }
   return status;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_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_TTL_ControlPause(int32_t paramCnt, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   bool_t bUpdateOutput = NAI_FALSE;
   naibrd_ttl_enable_type_t enState = 0;
   nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
   p_naiapp_AppParameters_t ttlparams = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = ttlparams->cardIndex;
   int32_t module = ttlparams->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   Verify_TTL_ParamCnt(paramCnt);

   /* Set the switch state (open or closed).
   */
   naiif_printf("\r\n Type PAUSE or RESUME to Control Pattern Generator Output\r\n ");
   naiif_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 = NAIBRD_TTL_ENABLE;
               bUpdateOutput = NAI_TRUE;
               break;
            case 'R':
               enState = NAIBRD_TTL_DISABLE;
               bUpdateOutput = NAI_TRUE;
               break;
            default:
               naiif_printf("ERROR: Invalid switch state selection\r\n");
               break;
         }
      }
   }
   if (!bQuit)
   {
      if (bUpdateOutput)
         status = check_status(naibrd_TTL_SetPatternGenCtrl(cardIndex, module, NAIBRD_TTL_CTRL_PATTERN_PAUSE, enState));
   }
   return status;
}
/**************************************************************************************************************/
/**
<summary>
Display_TTL_PatternGen_Configuration illustrate the methods to call in the naibrd library to retrieve the PWM
configuration settings.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Display_TTL_PatternGen_Configuration(int32_t paramCnt, int32_t* p_params)
{
   float64_t period;
   int32_t burstnumber;
   uint32_t startaddr;
   uint32_t endaddr;
   nai_status_t status = NAI_ERROR_NOT_SUPPORTED;
   p_naiapp_AppParameters_t ttlparams = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = ttlparams->cardIndex;
   int32_t module = ttlparams->module;
   Verify_TTL_ParamCnt(paramCnt);

   naiif_printf("\r\n");
   naiif_printf("  ----------PatternGen Configuration Settings-------------\r\n");
   naiif_printf("  Period (ms)      Burst Cnt      StartAddr     EndAddr  \r\n");
   naiif_printf("  -------------   -----------    -----------   ----------\r\n");

   check_status(naibrd_TTL_GetPatternGenPeriod(cardIndex, module, &period));
   naiif_printf(" %10.6f   ", period);

   check_status(naibrd_TTL_GetPatternGen_BurstNum(cardIndex, module, &burstnumber));
   naiif_printf("    0x%08X   ", burstnumber);

   check_status(naibrd_TTL_GetPatternGenStartAddr(cardIndex, module, &startaddr));
   naiif_printf("  0x%08X   ", startaddr);

   status = check_status(naibrd_TTL_GetPatternGenEndAddr(cardIndex, module, &endaddr));
   naiif_printf("  0x%08X   ", endaddr);

   naiif_printf("\r\n\r\n");
   return status;
}

Help Bot

X