TTL PWM Sample Application (SSK 1.x)
Overview
The TTL PWM sample application demonstrates how to generate a pulse-width-modulated (PWM) waveform on a channel of an NAI TTL (Transistor-Transistor Logic) discrete I/O module using the NAI Software Support Kit (SSK 1.x). PWM output is one of the enhanced operating modes of a TTL channel: instead of holding a static level (as in TTL Output) or reading an input (as in TTL BasicOps), the channel drives a repeating pulse train defined by a period, a pulse width, and a polarity.
The sample supports two PWM modes:
- Continuous — the channel pulses forever once triggered, until you halt it.
- Burst — the channel emits a fixed number of pulses (the burst count) on each trigger, then stops.
After you select a channel, the sample opens a menu whose commands map to naibrd_TTL_*() API calls:
| Command | Description |
|---|---|
| Mode | Select the PWM mode (Continuous, Burst, or None/basic I/O) |
| Period | Set the pulse period, in milliseconds |
| Width | Set the pulse width, in milliseconds |
| Count | Set the burst count (pulses per trigger, Burst mode) |
| POlarity | Set the output polarity (positive- or negative-going pulse) |
| PM | Display the current PWM configuration (period, width, count, polarity) |
| Trigger | Start the PWM output |
| Halt | Stop the PWM output |
| Stat | Display channel status (BIT, overcurrent, transitions) |
| Demo | Configure every channel with incrementing period/width/count |
| Reset | Reset every channel to its initial (non-PWM) configuration |
| SETBurst / SETCont | Set every channel to Burst / Continuous mode |
Note
PWM is an enhanced-timing feature. The timing-range checks in this sample handle the enhanced-timing TTL modules (TL2, TL4, TL6, TL8); consult your module’s manual to confirm PWM support and its valid timing ranges.
Prerequisites
Before running this sample, make sure you have:
- An NAI board with an enhanced-timing TTL module installed (TL2, TL4, TL6, TL8).
- 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.
How to Run
Launch the TTL_PWM executable from your build output directory. On startup the application looks for a configuration file (default_TTL_PWM.txt). On the first run this file will not exist — the application presents 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. After selecting the module you are prompted for a channel, and the TTL PWM menu opens for that channel.
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.
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. - Query the user for a card index with
naiapp_query_CardIndex(). - Retrieve the module count with
naibrd_GetModuleCount()and query for a module slot withnaiapp_query_ModuleNumber(). - Retrieve the module ID with
naibrd_GetModuleID()and, if valid, hand control toRun_TTL_PWM().
Run_TTL_PWM() then confirms the slot holds a TTL module before entering the command loop:
MaxChannel = naibrd_TTL_GetChannelCount(ModuleID);
if (MaxChannel == 0)
printf(" *** Module selection not recognized as TTL module. ***\n\n");
else
Cfg_TTL_PWM_Channel(cardIndex, module, ModuleID, MaxChannel);int32_t naibrd_TTL_GetChannelCount(uint32_t modid)— returns the number of TTL channels for the given module ID, or 0 if the module is not a TTL module.
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 — indices are zero-based for cards and one-based for modules. Ensure the values you pass match your hardware setup.
- “Module selection not recognized as TTL module” — the selected slot does not contain a TTL module.
naibrd_TTL_GetChannelCount()returns 0 for non-TTL modules, and the sample rejects the selection.
Program Structure
Entry Point
On standard platforms the entry point is main(). On VxWorks the entry point is TTL_PWM() — the SSK 1.x build system selects the correct variant via a preprocessor guard:
#if defined (__VXWORKS__)
int32_t TTL_PWM(void)
#else
int32_t main(void)
#endifChannel Selection and Command Loop
Cfg_TTL_PWM_Channel() prompts for a single channel with naiapp_query_ChannelNumber() and stores the card, module, and selected channel in an naiapp_AppParameters_t struct. That struct is passed to each command handler, so every command acts on the selected channel. On each loop iteration the sample redisplays the channel’s configuration via Display_TTL_PWM_ChannelCfg(), prints the menu, and dispatches the selection through the TTL_PWM_MenuCmds[] table. The menu is a convenience of the sample — in your own application you would call the naibrd_TTL_*() functions directly.
Selecting the PWM Mode
Configure_TTL_PWM_Mode() puts the channel into one of the two PWM modes (or returns it to basic I/O). PWM mode requires the channel to be an output, so the handler sets the I/O format to output and then selects the operating mode:
/* Continuous PWM */
naibrd_TTL_SetIOFormat(cardIndex, module, chan, NAI_TTL_IOFORMAT_OUTPUT);
naibrd_TTL_SetOpMode(cardIndex, module, chan, NAI_TTL_MODE_OUTPUT_PWM_FOREVER);
/* Burst PWM */
naibrd_TTL_SetIOFormat(cardIndex, module, chan, NAI_TTL_IOFORMAT_OUTPUT);
naibrd_TTL_SetOpMode(cardIndex, module, chan, NAI_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES);
/* None -- return to basic input/output */
naibrd_TTL_SetOpMode(cardIndex, module, chan, NAI_TTL_MODE_STD_INPUT_OUTPUT);nai_status_t naibrd_TTL_SetIOFormat(int32_t cardIndex, int32_t module, int32_t channel, nai_ttl_ioformat_t format)— sets the channel’s I/O format;NAI_TTL_IOFORMAT_OUTPUTis required before PWM output.nai_status_t naibrd_TTL_SetOpMode(int32_t cardIndex, int32_t module, int32_t channel, nai_ttl_enhanced_mode_t mode)— selects the channel operating mode:NAI_TTL_MODE_OUTPUT_PWM_FOREVER— continuous PWM.NAI_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES— burst PWM (emits burst count pulses per trigger).NAI_TTL_MODE_STD_INPUT_OUTPUT— standard bidirectional I/O (no PWM).
The current mode is read back for display with naibrd_TTL_GetOpMode().
Setting the Waveform Parameters
With a PWM mode selected, four handlers define the shape of the pulse train. Each reads a value from the operator and calls a single naibrd_TTL_SetPWM_*() function.
Period and Pulse Width
Both period and pulse width are entered in milliseconds and passed as float64_t. Before applying a value, the sample reads the module’s timing resolution with naibrd_TTL_GetTimebaseLSB() and range-checks the entry:
lsb = naibrd_TTL_GetTimebaseLSB(ModuleID); /* smallest timing step, in ms */
/* ... compute min/max from lsb, reject out-of-range entries ... */
naibrd_TTL_SetPWM_Period(cardIndex, module, chan, time); /* period, ms */
naibrd_TTL_SetPWM_Pulsewidth(cardIndex, module, chan, time); /* pulse width, ms */float64_t naibrd_TTL_GetTimebaseLSB(uint32_t modid)— returns the module’s timebase least-significant-bit (the finest timing increment), used to derive the valid range.nai_status_t naibrd_TTL_SetPWM_Period(int32_t cardIndex, int32_t module, int32_t channel, float64_t period)— sets the pulse period in milliseconds.nai_status_t naibrd_TTL_SetPWM_Pulsewidth(int32_t cardIndex, int32_t module, int32_t channel, float64_t pulsewidth)— sets the pulse width in milliseconds.
Note
The pulse width must be shorter than the period. The duty cycle of the waveform is simply pulse width ÷ period. Values outside the module’s supported range (derived from the timebase LSB) are rejected before the API call is made.
Burst Count
For Burst mode, the burst count is the number of pulses emitted on each trigger. It is a uint32_t and must be at least 1:
naibrd_TTL_SetPWM_BurstNum(cardIndex, module, chan, burstcount);nai_status_t naibrd_TTL_SetPWM_BurstNum(int32_t cardIndex, int32_t module, int32_t channel, uint32_t burstNum)— sets the number of pulses per trigger for Burst mode. The sample clamps values below 1 up to 1. The burst count has no effect in Continuous mode.
Polarity
Polarity selects whether the active pulse is positive- or negative-going:
naibrd_TTL_SetPWM_Polarity(cardIndex, module, chan, NAI_TTL_PWMPOLARITY_POS); /* positive-going */
naibrd_TTL_SetPWM_Polarity(cardIndex, module, chan, NAI_TTL_PWMPOLARITY_NEG); /* negative-going */nai_status_t naibrd_TTL_SetPWM_Polarity(int32_t cardIndex, int32_t module, int32_t channel, nai_ttl_pwm_polarity_t polarity)— sets the output polarity.NAI_TTL_PWMPOLARITY_POSproduces a positive-going pulse;NAI_TTL_PWMPOLARITY_NEGproduces a negative-going pulse.
Starting and Stopping the Output
Setting the mode and parameters arms the channel; the waveform does not run until it is triggered. The sample starts and stops output by enabling or disabling the channel’s enhanced-operation trigger:
/* Trigger -- start PWM output */
naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAI_TTL_OUTPUT_ENHANCED_OP_ENABLE);
/* Halt -- stop PWM output */
naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, chan, NAI_TTL_ENHANCED_OP_DISABLE);nai_status_t naibrd_TTL_SetEnhanceTriggerEnable(int32_t cardIndex, int32_t module, int32_t channel, nai_ttl_enable_t enable)— enables (starts) or disables (stops) the channel’s enhanced operation. In PWM mode, enabling begins the pulse train and disabling halts it.
Note
The library also provides dedicated
naibrd_TTL_StartPWM(int32_t cardIndex, int32_t module, int32_t channel)andnaibrd_TTL_StopPWM(int32_t cardIndex, int32_t module, int32_t channel)functions, which this sample references in comments as an equivalent way to trigger and halt the output.
Reading Back Configuration and Status
PWM Configuration
The PM command reads back the full PWM configuration for the channel with the matching naibrd_TTL_GetPWM_*() getters:
naibrd_TTL_GetPWM_Period(cardIndex, module, chan, &period);
naibrd_TTL_GetPWM_Pulsewidth(cardIndex, module, chan, &pulsewidth);
naibrd_TTL_GetPWM_BurstNum(cardIndex, module, chan, &burstnumber);
naibrd_TTL_GetPWM_Polarity(cardIndex, module, chan, &polaritysetting);nai_status_t naibrd_TTL_GetPWM_Period(int32_t cardIndex, int32_t module, int32_t channel, float64_t* outperiod)— reads the period, in milliseconds.nai_status_t naibrd_TTL_GetPWM_Pulsewidth(int32_t cardIndex, int32_t module, int32_t channel, float64_t* outpulsewidth)— reads the pulse width, in milliseconds.nai_status_t naibrd_TTL_GetPWM_BurstNum(int32_t cardIndex, int32_t module, int32_t channel, uint32_t* outburstNum)— reads the burst count.nai_status_t naibrd_TTL_GetPWM_Polarity(int32_t cardIndex, int32_t module, int32_t channel, nai_ttl_pwm_polarity_t* outpolarity)— reads the polarity (0 = positive-going, 1 = negative-going).
Channel Status
The Stat command reads the channel’s latched status conditions with naibrd_TTL_GetStatus():
nai_status_bit_t status;
naibrd_TTL_GetStatus(cardIndex, module, chan, NAI_TTL_STATUS_BIT_LATCHED, &status);
naibrd_TTL_GetStatus(cardIndex, module, chan, NAI_TTL_STATUS_OVERCURRENT_LATCHED, &status);
naibrd_TTL_GetStatus(cardIndex, module, chan, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &status);
naibrd_TTL_GetStatus(cardIndex, module, chan, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &status);nai_status_t naibrd_TTL_GetStatus(int32_t cardIndex, int32_t module, int32_t channel, nai_ttl_status_type_t type, nai_status_bit_t* outstatusVal)— reads one status condition, selected bytype: BIT fault, overcurrent, and low-to-high / high-to-low logic transitions.
Bulk and Demo Helpers
Several commands operate on every channel at once, to make it easy to exercise a whole module. They are wrappers over the same per-channel API calls used above, looped across all channels:
- Demo — assigns each channel an incrementing period (channel n ms), a pulse width one-tenth of that, and a burst count equal to n, using
naibrd_TTL_SetPWM_Period(),naibrd_TTL_SetPWM_Pulsewidth(), andnaibrd_TTL_SetPWM_BurstNum(). - SETBurst / SETCont — set every channel to
NAI_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES(burst) orNAI_TTL_MODE_OUTPUT_PWM_FOREVER(continuous) vianaibrd_TTL_SetOpMode(). - Reset — returns every channel to an initial, non-PWM state: output low, I/O format input, a default pulse width, burst count 0, standard I/O mode, and zero debounce time, using
naibrd_TTL_SetOutputState(),naibrd_TTL_SetIOFormat(),naibrd_TTL_SetOpMode(), andnaibrd_TTL_SetDebounceTime()/naibrd_TTL_GetDebounceTime().
These are each prompted with a Yes/No confirmation before running.
Troubleshooting Reference
This table summarizes common errors and symptoms covered in the sections above. Consult your module’s manual for hardware-specific diagnostic procedures.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
| No board found or connection timeout | Board not powered, incorrect or missing configuration file, network issue | Verify hardware is powered and connected. If default_TTL_PWM.txt exists, check that it lists the correct interface and address; otherwise configure and save your connection in the board menu. |
| ”Module selection not recognized as TTL module” | Selected slot is not a TTL module, or wrong module number | naibrd_TTL_GetChannelCount() returns 0 for non-TTL modules. Verify the slot contains an enhanced-timing TTL module. |
| No output after setting parameters | Channel armed but never triggered | Use the Trigger command (naibrd_TTL_SetEnhanceTriggerEnable(... ENABLE)) to start the waveform after setting mode and parameters. |
| ”Entry out of range” when setting period/width | Value smaller than one timebase LSB or larger than the counter maximum | Choose a value within the printed range. The range is derived from naibrd_TTL_GetTimebaseLSB() for the module. |
| Burst mode emits pulses forever, or vice versa | Mode and command mismatched | Confirm the operating mode: NAI_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES for burst (respects burst count), NAI_TTL_MODE_OUTPUT_PWM_FOREVER for continuous. |
| ”Unsupported function for this module” on burst count | Module is not an enhanced-timing TTL module | Burst count is handled for TL2/TL4/TL6/TL8. Verify the module supports PWM burst. |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — TTL_PWM.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_ttl.h"
#include "advanced/nai_ether_adv.h"
static const int8_t *CONFIG_FILE = (int8_t *)"default_TTL_PWM.txt";
/* Function prototypes */
static void Run_TTL_PWM(int32_t cardIndex, int32_t module, int32_t ModuleID);
static void Cfg_TTL_PWM_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
static void Display_TTL_PWM_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID);
static nai_status_t Display_TTL_PWM_Configuration(int32_t paramCount, int32_t* p_params);
static nai_status_t Display_TTL_Status(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_TTL_PWM_Mode(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_TTL_PWM_Period(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_TTL_PWM_Pulsewidth(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_TTL_PWM_Burstcount(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_TTL_PWM_Polarity(int32_t paramCount, int32_t* p_params);
static const int32_t DEF_TTL_CHANNEL = 1;
/****** Command Table *******/
enum ttl_pwm_commands
{
TTL_PWM_CMD_MODE,
TTL_PWM_CMD_PERIOD,
TTL_PWM_CMD_PULSEWIDTH,
TTL_PWM_CMD_BURSTCOUNT,
TTL_PWM_CMD_POLARITY,
TTL_PWM_CMD_PWM_CFG,
TTL_PWM_CMD_PWM_START,
TTL_PWM_CMD_PWM_STOP,
TTL_PWM_CMD_PWM_DEMO,
TTL_PWM_CMD_PWM_INITIAL,
TTL_PWM_CMD_STATUS,
TTL_PWM_CMD_PWM_BURST,
TTL_PWM_CMD_PWM_CONT,
TTL_PWM_CMD_COUNT
};
/****** Command Tables *******/
naiapp_cmdtbl_params_t TTL_PWM_MenuCmds[] = {
{"Mode", " TTL Select PWM Mode", TTL_PWM_CMD_MODE, Configure_TTL_PWM_Mode},
{"Period", " TTL Set PWM Period", TTL_PWM_CMD_PERIOD, Configure_TTL_PWM_Period},
{"Width", " TTL Set PWM Pulsewidth", TTL_PWM_CMD_PULSEWIDTH, Configure_TTL_PWM_Pulsewidth},
{"Count", " TTL Set PWM burst count", TTL_PWM_CMD_BURSTCOUNT, Configure_TTL_PWM_Burstcount},
{"POlarity", " TTL Set PWM Polarity", TTL_PWM_CMD_POLARITY, Configure_TTL_PWM_Polarity},
{"PM", " TTL Display PWM configuration settings", TTL_PWM_CMD_PWM_CFG, Display_TTL_PWM_Configuration},
{"Trigger", " TTL Start PWM output", TTL_PWM_CMD_PWM_START, NULL},
{"Halt", " TTL Stop PWM output", TTL_PWM_CMD_PWM_STOP, NULL},
{"Demo", " TTL Demo PWM Settings", TTL_PWM_CMD_PWM_DEMO, NULL},
{"Reset", " TTL Reset All Channels to Initial Settings", TTL_PWM_CMD_PWM_INITIAL, NULL},
{"Stat", " TTL Display Status", TTL_PWM_CMD_STATUS, Display_TTL_Status},
{"SETBurst", " TTL Set all channels to PWM Burst", TTL_PWM_CMD_PWM_BURST, NULL},
{"SETCont", " TTL Set all channels to PWM Continuous", TTL_PWM_CMD_PWM_CONT, NULL},
};
/**************************************************************************************************************/
/**
<summary>
The purpose of the TTL_PWM 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>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t TTL_PWM(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_TTL_PWM(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_TTL_PWM prompts the user for the card, module and channel to use for the application and calls
Cfg_TTL_PWM_Channel if the card, module, channel is valid for as a discrete module.
</summary>
*/
/**************************************************************************************************************/
void Run_TTL_PWM(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
int32_t MaxChannel;
MaxChannel = naibrd_TTL_GetChannelCount(ModuleID);
if (MaxChannel == 0)
{
printf(" *** Module selection not recognized as TTL module. ***\n\n");
}
else
{
Cfg_TTL_PWM_Channel(cardIndex, module, ModuleID, MaxChannel);
}
}
/**************************************************************************************************************/
/**
<summary>
Display_TTL_PatternGen_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for basic operation.
</summary>
*/
/**************************************************************************************************************/
void Display_TTL_PWM_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID)
{
uint32_t ioformat = 0;
nai_ttl_state_t outputstate = 0;
nai_ttl_state_t inputstate = 0;
nai_ttl_enhanced_mode_t opmode = 0;
uint32_t ModuleVer;
uint32_t ModuleRev;
uint32_t ModInfo_Special;
naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
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_GetOpMode(cardIndex, module, chan, &opmode));
printf("\n === Channel %d ===\n\n", chan);
/*read PWM configuration values here, Period, Pulsewidth, Continuous/Burst Mode, */
{
printf(" I/O Output Input \n");
printf(" Format State State Enhanced Mode Selection \n");
printf("-------- ------- ------- ------------------------- \n");
}
/*display configuration settings here- */
switch (ioformat)
{
case NAI_TTL_IOFORMAT_INPUT:
printf(" Input ");
break;
case NAI_TTL_GEN3_IOFORMAT_OUTPUT:
case NAI_TTL_GEN5_IOFORMAT_OUTPUT:
printf(" High-side"); /*may want add check for proper value depending on whether gen3 or gen5; for now, assume it correctly matches module*/
break;
default:
printf(" Unknown ");
break;
}
switch (outputstate)
{
case NAI_TTL_STATE_LO:
printf(" LOW ");
break;
case NAI_TTL_STATE_HI:
printf(" HIGH ");
break;
default:
printf(" Unknown ");
break;
}
switch (inputstate)
{
case NAI_TTL_STATE_LO:
printf(" LOW Input ");
break;
case NAI_TTL_STATE_HI:
printf("HIGH Input ");
break;
default:
printf("Unknown ");
break;
}
switch (opmode)
{
case NAI_TTL_MODE_STD_INPUT_OUTPUT:
printf("STD_INPUT_OUTPUT ");
break;
case NAI_TTL_MODE_MEASURE_HIGH_TIME:
printf("NAI_TTL_MODE_MEASURE_HIGH_TIME ");
break;
case NAI_TTL_MODE_MEASURE_LOW_TIME:
printf("NAI_TTL_MODE_MEASURE_LOW_TIME ");
break;
case NAI_TTL_MODE_TIMESTAMP_RISING_EDGES:
printf("NAI_TTL_MODE_TIMESTAMP_RISING_EDGES ");
break;
case NAI_TTL_MODE_TIMESTAMP_FALLING_EDGES:
printf("NAI_TTL_MODE_TIMESTAMP_FALLING_EDGES ");
break;
case NAI_TTL_MODE_TIMESTAMP_ALL_EDGES:
printf("NAI_TTL_MODE_TIMESTAMP_ALL_EDGES ");
break;
case NAI_TTL_MODE_COUNT_RISING_EDGES:
printf("NAI_TTL_MODE_COUNT_RISING_EDGES ");
break;
case NAI_TTL_MODE_COUNT_FALLING_EDGES:
printf("NAI_TTL_MODE_COUNT_FALLING_EDGES ");
break;
case NAI_TTL_MODE_COUNT_ALL_EDGES:
printf("NAI_TTL_MODE_COUNT_ALL_EDGES ");
break;
case NAI_TTL_MODE_MEASURE_PERIOD_FROM_RISING_EDGE:
printf("NAI_TTL_MODE_MEASURE_PERIOD_FROM_RISING_EDGE ");
break;
case NAI_TTL_MODE_MEASURE_FREQUENCY:
printf("NAI_TTL_MODE_MEASURE_FREQUENCY ");
break;
case NAI_TTL_MODE_OUTPUT_PWM_FOREVER:
printf("NAI_TTL_MODE_OUTPUT_PWM_FOREVER ");
break;
case NAI_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES:
printf("NAI_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES ");
break;
case NAI_TTL_MODE_OUTPUT_PATTERN_RAM:
printf("NAI_TTL_MODE_OUTPUT_PATTERN_RAM ");
break;
default:
printf("Unknown ");
break;
}
}
/**************************************************************************************************************/
/**
<summary>
Cfg_TTL_PWM_Channel handles calling the Display_TTL_PWM_ChannelCfg routine to display the discrete channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
void Cfg_TTL_PWM_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel)
{
nai_status_t status = (nai_status_t)0;
bool_t bQuit = FALSE;
bool_t bContinue = TRUE;
bool_t bCmdFound = FALSE;
int32_t defaultchan = 1;
int32_t cmd;
int32_t ch_loop;
float64_t time;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
naiapp_AppParameters_t ttl_params;
p_naiapp_AppParameters_t ttl_pwm_params = &ttl_params;
ttl_pwm_params->cardIndex = cardIndex;
ttl_pwm_params->module = module;
while (bContinue)
{
printf(" \r\n\r\n");
printf("Channel selection \r\n");
printf("================= \r\n");
defaultchan = DEF_TTL_CHANNEL;
bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &ttl_pwm_params->channel);
naiapp_utils_LoadParamMenuCommands(TTL_PWM_CMD_COUNT, TTL_PWM_MenuCmds);
while (bContinue)
{
Display_TTL_PWM_ChannelCfg(cardIndex, module, ttl_pwm_params->channel, ModuleID);
naiapp_display_ParamMenuCommands((int8_t *)"TTL PWM Menu");
printf("\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_PWM_CMD_MODE:
case TTL_PWM_CMD_PERIOD:
case TTL_PWM_CMD_PULSEWIDTH:
case TTL_PWM_CMD_BURSTCOUNT:
case TTL_PWM_CMD_POLARITY:
case TTL_PWM_CMD_PWM_CFG:
case TTL_PWM_CMD_STATUS:
TTL_PWM_MenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)ttl_pwm_params);
break;
case TTL_PWM_CMD_PWM_START:
/* check_status(naibrd_TTL_StartPWM(cardIndex, module, chan)); */
check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, ttl_pwm_params->channel, NAI_TTL_OUTPUT_ENHANCED_OP_ENABLE));
break;
case TTL_PWM_CMD_PWM_STOP:
/* check_status(naibrd_TTL_StopPWM(cardIndex, module, chan)); */
check_status(naibrd_TTL_SetEnhanceTriggerEnable(cardIndex, module, ttl_pwm_params->channel, NAI_TTL_ENHANCED_OP_DISABLE));
break;
case TTL_PWM_CMD_PWM_DEMO:
{
status = NAI_SUCCESS;
printf("Set up all channels in incrementing period/pulsewidths and burstcounts? \n Enter Yes to confirm: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
if ((toupper(inputBuffer[0]) == 'Y'))
{
for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
time = ch_loop;
status |= check_status(naibrd_TTL_SetPWM_Period(cardIndex, module, ch_loop, time));
time /= 10.0;
status |= check_status(naibrd_TTL_SetPWM_Pulsewidth(cardIndex, module, ch_loop, time));
status |= check_status(naibrd_TTL_SetPWM_BurstNum(cardIndex, module, ch_loop, ch_loop));
}
if (status == NAI_SUCCESS)
printf("\n PWM channel configuration initialized for all channels. \n Set PWM Mode as needed. ");
else
printf("\n Configuration not completed successfully. \n");
}
}
}
}
break;
case TTL_PWM_CMD_PWM_INITIAL:
{
status = NAI_SUCCESS;
printf("Reset all channels to initial configuration? \n Enter Yes to confirm: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
if ((toupper(inputBuffer[0]) == 'Y'))
{
for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
status |= check_status(naibrd_TTL_SetOutputState(cardIndex, module, ch_loop, NAI_TTL_STATE_LO));
status |= check_status(naibrd_TTL_SetIOFormat(cardIndex, module, ch_loop, NAI_TTL_IOFORMAT_INPUT));
status |= check_status(naibrd_TTL_SetPWM_Pulsewidth(cardIndex, module, ch_loop, 16E-6));
status |= check_status(naibrd_TTL_SetPWM_BurstNum(cardIndex, module, ch_loop, 0));
status |= check_status(naibrd_TTL_SetOpMode(cardIndex, module, ch_loop, NAI_TTL_MODE_STD_INPUT_OUTPUT));
status |= check_status(naibrd_TTL_SetDebounceTime(cardIndex, module, ch_loop, 0.0));
status |= check_status(naibrd_TTL_GetDebounceTime(cardIndex, module, ch_loop, &time));
if (time > 1E-10)
status++;
}
if (status == NAI_SUCCESS)
printf("\n PWM channel configuration initialized for all channels. \n");
else
printf("\n Initialization not completed successfully. \n");
}
}
}
}
break;
case TTL_PWM_CMD_PWM_BURST:
{
printf("Reset all channels to PWM burst mode? \n Enter Yes to confirm: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
if ((toupper(inputBuffer[0]) == 'Y'))
{
for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
status |= check_status(naibrd_TTL_SetOpMode(cardIndex, module, ch_loop, NAI_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES));
}
if (status == NAI_SUCCESS)
printf("\n PWM channel configuration set for PWM Burst mode for all channels. \n");
else
printf("\n Initialization not completed successfully. \n");
}
}
}
}
break;
case TTL_PWM_CMD_PWM_CONT:
{
printf("Reset all channels to PWM continuous mode? \n Enter Yes to confirm: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
if ((toupper(inputBuffer[0]) == 'Y'))
{
for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
status |= check_status(naibrd_TTL_SetOpMode(cardIndex, module, ch_loop, NAI_TTL_MODE_OUTPUT_PWM_FOREVER));
}
if (status == NAI_SUCCESS)
printf("\n PWM channel configuration set for PWM Burst mode for all channels. \n");
else
printf("\n Initialization not completed successfully. \n");
}
}
}
}
break;
default:
printf("Invalid command entered\n");
break;
}
}
else
printf("Invalid command entered\n");
}
}
else
bContinue = FALSE;
}
}
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_PWM_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>
*/
/**************************************************************************************************************/
nai_status_t Configure_TTL_PWM_Mode(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
p_naiapp_AppParameters_t p_ttl_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ttl_params->cardIndex;
int32_t module = p_ttl_params->module;
int32_t chan = p_ttl_params->channel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n == PWM Mode Selection == \n C Continuous PWM mode \n Burst PWM Burst mode \n None Basic input mode \n\n Type DSW 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_SetIOFormat(cardIndex, module, chan, NAI_TTL_IOFORMAT_OUTPUT));
check_status(naibrd_TTL_SetOpMode(cardIndex, module, chan, NAI_TTL_MODE_OUTPUT_PWM_FOREVER));
}
else if ((toupper(inputBuffer[0]) == 'B'))
{
check_status(naibrd_TTL_SetIOFormat(cardIndex, module, chan, NAI_TTL_IOFORMAT_OUTPUT));
check_status(naibrd_TTL_SetOpMode(cardIndex, module, chan, NAI_TTL_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES));
}
else if ((toupper(inputBuffer[0]) == 'N'))
{
check_status(naibrd_TTL_SetOpMode(cardIndex, module, chan, NAI_TTL_MODE_STD_INPUT_OUTPUT));
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_PWM_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_TTL_PWM_Period(int32_t paramCount, int32_t* p_params)
{
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;
p_naiapp_AppParameters_t p_ttl_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ttl_params->cardIndex;
int32_t module = p_ttl_params->module;
int32_t chan = p_ttl_params->channel;
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_TTL_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAI_MODULE_ID_TL2:
case NAI_MODULE_ID_TL4:
case NAI_MODULE_ID_TL6:
case NAI_MODULE_ID_TL8:
min = (float64_t)(0x2u * lsb);
max = (float64_t)(0xFFFFFFFF * lsb);
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_TTL_SetPWM_Period(cardIndex, module, chan, time));
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_PWM_Pulsewidth handles the user request to configure the time values for pulsewidth on the selected
channel and calls the method in the naibrd library to set the width.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_TTL_PWM_Pulsewidth(int32_t paramCount, int32_t* p_params)
{
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;
p_naiapp_AppParameters_t p_ttl_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ttl_params->cardIndex;
int32_t module = p_ttl_params->module;
int32_t chan = p_ttl_params->channel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\nEnter the desired pulsewidth in milliseconds: ");
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);
lsb = naibrd_TTL_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAI_MODULE_ID_TL2:
case NAI_MODULE_ID_TL4:
case NAI_MODULE_ID_TL6:
case NAI_MODULE_ID_TL8:
min = (float64_t)(0x1u * lsb);
max = (float64_t)(0xFFFFFFFE * 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_TTL_SetPWM_Pulsewidth(cardIndex, module, chan, 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>
*/
/**************************************************************************************************************/
nai_status_t Configure_TTL_PWM_Burstcount(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
uint32_t burstcount;
uint32_t ModuleID;
uint32_t ModuleVer;
uint32_t ModuleRev;
uint32_t ModInfo_Special;
p_naiapp_AppParameters_t p_ttl_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ttl_params->cardIndex;
int32_t module = p_ttl_params->module;
int32_t chan = p_ttl_params->channel;
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_TL2:
case NAI_MODULE_ID_TL4:
case NAI_MODULE_ID_TL6:
case NAI_MODULE_ID_TL8:
if (burstcount < 1)
{
burstcount = 1; /*minimum count is one*/
printf("Setting burstcount to minimum of 1.\n");
}
check_status(naibrd_TTL_SetPWM_BurstNum(cardIndex, module, chan, burstcount));
break;
default:
printf("Unsupported function for this module.\n");
break;
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_TTL_PWM_Polarity handles the user request to select the PWM output polarity for the selected channel
and calls the method in the naibrd library for the setting.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Configure_TTL_PWM_Polarity(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
p_naiapp_AppParameters_t p_ttl_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ttl_params->cardIndex;
int32_t module = p_ttl_params->module;
int32_t chan = p_ttl_params->channel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n == PWM Output Polarity Selection == \n Pos TTL PWM positive going pulse output \n Neg TTL PWM negative going pulse output \n\n Type TTL command : ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
if ((toupper(inputBuffer[0]) == 'P'))
check_status(naibrd_TTL_SetPWM_Polarity(cardIndex, module, chan, (nai_ttl_pwm_polarity_t)NAI_TTL_PWMPOLARITY_POS));
else if ((toupper(inputBuffer[0]) == 'N'))
check_status(naibrd_TTL_SetPWM_Polarity(cardIndex, module, chan, (nai_ttl_pwm_polarity_t)NAI_TTL_PWMPOLARITY_NEG));
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Display_TTL_PWM_Configuration illustrate the methods to call in the naibrd library to retrieve the PWM
configuration settings.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Display_TTL_PWM_Configuration(int32_t paramCount, int32_t* p_params)
{
nai_ttl_pwm_polarity_t polaritysetting;
float64_t period;
float64_t pulsewidth;
uint32_t burstnumber;
p_naiapp_AppParameters_t p_ttl_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ttl_params->cardIndex;
int32_t module = p_ttl_params->module;
int32_t chan = p_ttl_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
/* Available configuration settings:
PWM period", (Value read back in milliseconds)
PWM pulsewidth", (Value read back in milliseconds)
PWM burst count (Number of pulses issued upon trigger in burst mode)
PWM polarity", 0 = positive going pulsewidth, 1 = negative going
*/
printf("\n");
printf(" -------------PWM Configuration Settings---------------------------- \n");
printf(" Period (ms) Pulsewidth (ms) Burst Cnt Polarity \n");
printf(" -------------- ---------------- ----------- ----------- \n");
check_status(naibrd_TTL_GetPWM_Period(cardIndex, module, chan, &period));
printf(" %10.6f ", period);
check_status(naibrd_TTL_GetPWM_Pulsewidth(cardIndex, module, chan, &pulsewidth));
printf(" %10.6f ", pulsewidth);
check_status(naibrd_TTL_GetPWM_BurstNum(cardIndex, module, chan, &burstnumber));
printf(" 0x%08X ", burstnumber);
check_status(naibrd_TTL_GetPWM_Polarity(cardIndex, module, chan, &polaritysetting));
if (polaritysetting == 0)
printf(" POS ");
else
printf(" NEG ");
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_TTL_Status(int32_t paramCount, int32_t* p_params)
{
nai_status_bit_t status;
p_naiapp_AppParameters_t p_ttl_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ttl_params->cardIndex;
int32_t module = p_ttl_params->module;
int32_t chan = p_ttl_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
/* Available status:
NAI_TTL_STATUS_BIT_LATCHED,
NAI_TTL_STATUS_OVERCURRENT_LATCHED,
NAI_TTL_STATUS_LO_HI_TRANS_LATCHED,
NAI_TTL_STATUS_HI_LO_TRANS_LATCHED,
*/
printf("\n");
printf(" ----------------- Status ----------------------------\n");
printf(" BIT OC Lo-Hi Hi-Lo \n");
printf(" ------- -------- ------ ------- \n");
check_status(naibrd_TTL_GetStatus(cardIndex, module, chan, NAI_TTL_STATUS_BIT_LATCHED, &status));
printf(" %3i ", status);
check_status(naibrd_TTL_GetStatus(cardIndex, module, chan, NAI_TTL_STATUS_OVERCURRENT_LATCHED, &status));
printf(" %3i ", status);
check_status(naibrd_TTL_GetStatus(cardIndex, module, chan, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &status));
printf(" %3i ", status);
check_status(naibrd_TTL_GetStatus(cardIndex, module, chan, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &status));
printf(" %3i ", status);
printf("\n\n");
return NAI_ERROR_UNKNOWN;
}