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

DIF PWM

DIF PWM Sample Application (SSK 1.x)

Overview

The DIF PWM sample application demonstrates how to configure and generate Pulse Width Modulation (PWM) output on differential (DIF) I/O channels using the NAI Software Support Kit (SSK 1.x). Differential I/O channels use balanced signal pairs to transmit digital signals with superior noise immunity compared to single-ended discrete (DT) lines. PWM on a differential channel gives you the same waveform-shaping capabilities — programmable frequency, duty cycle, and polarity — but over a differential physical interface suitable for longer cable runs and electrically noisy environments.

Three parameters define a PWM signal at the hardware level:

  • Period — the total time for one complete on/off cycle, specified in milliseconds. The reciprocal of the period is the PWM frequency. A 1 ms period produces a 1 kHz output; a 10 ms period produces 100 Hz. The period you choose depends on your application: motor controllers typically use 1-20 kHz to stay above audible frequencies, while servo signals use 50 Hz (20 ms). The DIF module’s period register determines the exact cycle time, with resolution set by the module’s timebase LSB.

  • Pulse width (duty cycle) — the time the output is held in its active state within each period, also in milliseconds. The duty cycle is the ratio of pulse width to period. A 0.3 ms pulse width with a 1 ms period gives 30% duty cycle — the output spends 30% of each cycle in the active state and 70% in the idle state. The average power or voltage delivered to the load scales linearly with duty cycle: 50% duty cycle delivers half the full-scale voltage on average. The pulse width must always be less than or equal to the period.

  • Polarity — determines the direction of the active pulse. With positive polarity (NAI_DIF_PWMPOLARITY_POS), the output idles low and pulses high during the active portion. With negative polarity (NAI_DIF_PWMPOLARITY_NEG), the output idles high and pulses low. On a differential pair, this translates to which line of the pair is driven high during the active pulse. Choose polarity based on whether your downstream receiver or load expects an active-high or active-low signal.

The DIF module supports two PWM operating modes:

  • Continuous mode (NAI_DIF_MODE_OUTPUT_PWM_FOREVER) — the channel outputs the PWM waveform indefinitely once triggered, running until explicitly stopped. Use this for steady-state loads such as constant-speed motor drives, LED brightness control, or any application requiring an ongoing periodic signal.

  • Burst mode (NAI_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES) — the channel outputs a specific number of PWM cycles (the burst count) and then stops automatically. Use this when you need a precise number of pulses — for example, stepping a motor a known number of increments, generating a timed calibration stimulus, or producing a fixed-length digital waveform for protocol signaling.

This sample supports the following DIF module types: D8, DF1, DF2, and DF3. It also works with the CMH combination module that includes differential I/O functionality. For basic DIF channel configuration (I/O format, thresholds, output state, slew rate), see the DIF BasicOps guide. Consult your module’s manual (e.g., DF1 Manual) for hardware-specific PWM timing limits, timebase resolution, and register details.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a DIF module installed (D8, DF1, DF2, DF3, or CMH).

  • 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 DIF_PWM executable from your build output directory. On startup the application looks for a configuration file (default_DIF_PWM.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, you select a channel and use the command menu to configure PWM parameters and trigger 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 DIF. For details on board connection configuration, see the First Time Setup Guide.

The main() function follows a standard SSK 1.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_DIF_PWM.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_GetModuleID() so downstream code can adapt to the specific DIF variant installed.

#if defined (__VXWORKS__)
int32_t DIF_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)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  Run_DIF_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);
      }
   }

   naiapp_access_CloseAllOpenCards();
   return 0;
}

After board connection, Run_DIF_PWM() validates that the selected module is a recognized DIF type by calling naibrd_DIF_GetChannelCount(). If the channel count is zero, the module is not a DIF module and the sample prints an error.

MaxChannel = naibrd_DIF_GetChannelCount(ModuleID);

if (MaxChannel == 0)
{
   printf(" *** Module selection not recognized as DIF module. ***\n\n");
}
else
{
   Cfg_DIF_PWM_Channel(cardIndex, module, ModuleID, MaxChannel);
}
Important

Common Connection Errors

  • No board found — verify the board is powered on and the connection interface (Ethernet, PCIe, etc.) is properly configured.

  • Connection timeout — check network settings, IP address, and that no firewall is blocking communication.

  • Invalid card/module index — card indices are 0-based; module indices are 1-based. Verify the module is physically installed in the expected slot.

  • Module not present — naibrd_DIF_GetChannelCount() returns 0 if the module ID does not match any known DIF type.

Program Structure

Automatic Channel Initialization

Unlike the DT PWM sample, the DIF PWM sample automatically configures the selected channel for PWM output as soon as a channel is selected. This means you do not need to manually set the mode before using the timing commands:

/* Automatically configure selected channel for PWM output */
check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan, NAI_DIF_MODE_OUTPUT_PWM_FOREVER));
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));

This sets the channel to continuous PWM mode and configures the I/O format for output. In your own application, you will need to make these calls explicitly before configuring PWM timing parameters.

Application Parameters

The sample tracks connection and channel context in a naiapp_AppParameters_t struct that is passed to each command handler:

naiapp_AppParameters_t  dif_params;
p_naiapp_AppParameters_t dif_pwm_params = &dif_params;
dif_pwm_params->cardIndex = cardIndex;
dif_pwm_params->module = module;
dif_pwm_params->modId = ModuleID;

In your own application, you will track equivalent values — card index, module number, module ID, and channel number — however is appropriate for your architecture.

Command Menu

After selecting a channel, the sample presents a command menu. The menu system is a sample convenience — in your own code, call these API functions directly. The available commands are:

Command Description

Mode

Select PWM mode (Continuous, Burst, or Standard Input)

Period

Set PWM period in milliseconds

Width

Set PWM pulse width in milliseconds

Count

Set burst count (number of pulses in burst mode)

POlarity

Set PWM polarity (positive or negative)

PM

Display current PWM configuration settings

Trigger

Start PWM output on the selected channel

Halt

Stop PWM output on the selected channel

Demo

Configure all channels with incrementing period/width/burst values

Reset

Reset all channels to initial (input) configuration

Stat

Display channel status (BIT, overcurrent, transitions)

SETBurst

Set all channels to burst mode

SETCont

Set all channels to continuous mode

PWM Mode Selection

The DIF module supports multiple enhanced operating modes. This sample focuses on the two PWM modes and provides an option to return to standard input/output mode.

To set a channel to continuous PWM mode in your own application, call naibrd_DIF_SetOpMode() with NAI_DIF_MODE_OUTPUT_PWM_FOREVER and set the I/O format to output:

/* Continuous PWM -- output runs until explicitly stopped */
check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan, NAI_DIF_MODE_OUTPUT_PWM_FOREVER));
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));

To set burst mode, use NAI_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES instead:

/* Burst PWM -- output runs for the configured burst count, then stops */
check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan, NAI_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES));
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));

To return the channel to standard input/output mode (disabling PWM), set the mode to NAI_DIF_MODE_STD_INPUT_OUTPUT and the I/O format to input:

/* Return to standard I/O mode */
check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan, NAI_DIF_MODE_STD_INPUT_OUTPUT));
check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_IOFORMAT_INPUT));

Note that unlike DT channels, DIF channels do not have a separate basic/enhanced mode enable register. Setting the operating mode and I/O format is sufficient to configure the channel for PWM output.

Important

Common Errors

  • NAI_ERROR_NOT_SUPPORTED — the selected mode is not supported on this module type. Verify that your DIF module supports enhanced PWM modes.

  • Channel not outputting after mode set — setting the mode alone does not start the output. You must also call naibrd_DIF_StartPWM() to trigger the waveform.

  • I/O format not set — if the I/O format remains in input mode, the output driver will not be enabled even if the operating mode is set to PWM. Always set both the mode and the I/O format.

PWM Timing Configuration

Setting the Period

The PWM period determines how long each complete cycle takes. To set the period on a channel, call naibrd_DIF_SetPWM_Period() with the desired value in milliseconds:

float64_t time = 1.0; /* 1 ms period = 1 kHz frequency */
check_status(naibrd_DIF_SetPWM_Period(cardIndex, module, chan, time));

The valid range depends on the module type and its timebase LSB (least significant bit resolution). The sample retrieves the LSB with naibrd_DIF_GetTimebaseLSB() to compute the range dynamically:

lsb = naibrd_DIF_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAI_MODULE_ID_DF2:
   min = (float64_t)(0x2u * lsb);
   max = (float64_t)(0xFFFFFFFF * lsb);
   break;
}

The DF2 module uses a 32-bit period register, providing a wide timing range with fine resolution. Other DIF module types may have different register sizes and LSB values. Consult your module’s manual for the exact timebase LSB and resulting timing limits for your specific module.

Setting the Pulse Width

The pulse width determines how long the output stays in its active state during each period. To set the pulse width, call naibrd_DIF_SetPWM_Pulsewidth() with the value in milliseconds:

float64_t time = 0.5; /* 0.5 ms pulse width */
check_status(naibrd_DIF_SetPWM_Pulsewidth(cardIndex, module, chan, time));

The pulse width must be less than or equal to the period. The valid range follows the same module-dependent pattern as the period:

lsb = naibrd_DIF_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAI_MODULE_ID_DF2:
   min = (float64_t)(0x1u * lsb);
   max = (float64_t)(0xFFFFFFFE * lsb);
   break;
}

The minimum pulse width is one LSB. Setting a pulse width of zero would produce no active pulse (the output stays idle for the entire period), which is effectively a disabled output.

Important

Common Errors

  • Entry out of range — the sample validates that period and pulse width values fall within the module’s supported range. If your value exceeds the register capacity or is below the minimum LSB, the API may silently clip the value or return an error.

  • Pulse width exceeds period — the hardware will not produce a valid waveform if the pulse width is greater than the period. Always set the period first, then set the pulse width to a value less than or equal to the period.

  • Unexpected frequency — the period register has a finite LSB resolution. The actual period written to hardware is quantized to the nearest LSB. For precise frequencies, compute the closest achievable period using naibrd_DIF_GetTimebaseLSB().

Burst Count

In burst mode, the channel outputs a specific number of PWM cycles and then stops automatically. To configure the burst count, call naibrd_DIF_SetPWM_BurstNum():

uint32_t burstcount = 10; /* Output exactly 10 PWM cycles */
check_status(naibrd_DIF_SetPWM_BurstNum(cardIndex, module, chan, burstcount));

The minimum burst count is 1. The sample enforces this for DF2 modules:

case NAI_MODULE_ID_DF2:
   if (burstcount < 1)
   {
      burstcount = 1;
      printf("Setting burstcount to minimum of 1.\n");
   }
   check_status(naibrd_DIF_SetPWM_BurstNum(cardIndex, module, chan, burstcount));
   break;
default:
   printf("Unsupported function for this module.\n");
   break;

The source explicitly handles burst count for DF2 modules. For other DIF module types, the sample prints "Unsupported function for this module." Check your module’s manual to determine whether burst count is supported on your specific module variant.

Burst mode is particularly useful with differential I/O because it lets you generate a precise number of pulses over a noise-immune differential pair — for example, sending a known number of step pulses to a remote motor controller across a long cable run where single-ended signals would be susceptible to interference.

Important

Common Errors

  • Unsupported function for this module — burst count configuration is explicitly handled for DF2 in the sample source. Other module types may not support programmable burst count.

  • Burst output does not start — you must set the mode to NAI_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES and then call naibrd_DIF_StartPWM() to trigger the burst.

  • Burst count of zero — the minimum count is 1. A zero value may produce undefined behavior.

Polarity

PWM polarity determines the direction of the active pulse relative to the idle state. With positive polarity, the differential output idles in the low state and the pulse drives high. With negative polarity, the output idles high and the pulse drives low.

To set the polarity, call naibrd_DIF_SetPWM_Polarity():

/* Positive polarity: idle low, pulse high */
check_status(naibrd_DIF_SetPWM_Polarity(cardIndex, module, chan,
   (nai_dif_pwm_polarity_t)NAI_DIF_PWMPOLARITY_POS));

/* Negative polarity: idle high, pulse low */
check_status(naibrd_DIF_SetPWM_Polarity(cardIndex, module, chan,
   (nai_dif_pwm_polarity_t)NAI_DIF_PWMPOLARITY_NEG));

On differential channels, polarity determines which line of the pair is driven active during the pulse. Choose polarity based on your receiver’s input polarity convention. If you are driving a device that expects active-high differential signaling, use positive polarity. If the device inverts the signal or expects active-low, use negative polarity. The polarity setting does not affect the period or pulse width — it only inverts the waveform.

Starting and Stopping PWM Output

After configuring the mode, period, pulse width, polarity, and (optionally) burst count, you start the PWM output by calling naibrd_DIF_StartPWM():

check_status(naibrd_DIF_StartPWM(cardIndex, module, chan));

In continuous mode, the output runs indefinitely until you stop it. In burst mode, the output runs for the configured number of cycles and then stops automatically. To stop a running PWM output at any time, call naibrd_DIF_StopPWM():

check_status(naibrd_DIF_StopPWM(cardIndex, module, chan));

Stopping PWM output resets the channel behavior. If you want to restart PWM output after stopping, you may need to reconfigure the mode before calling naibrd_DIF_StartPWM() again.

Displaying PWM Configuration

To read back the current PWM settings for a channel, use the Get variants of the configuration API calls:

float64_t period, pulsewidth;
uint32_t burstnumber;
nai_dif_pwm_polarity_t polaritysetting;

check_status(naibrd_DIF_GetPWM_Period(cardIndex, module, chan, &period));
check_status(naibrd_DIF_GetPWM_Pulsewidth(cardIndex, module, chan, &pulsewidth));
check_status(naibrd_DIF_GetPWM_BurstNum(cardIndex, module, chan, &burstnumber));
check_status(naibrd_DIF_GetPWM_Polarity(cardIndex, module, chan, &polaritysetting));

The period and pulse width are returned in milliseconds. The polarity is returned as NAI_DIF_PWMPOLARITY_POS (0) or NAI_DIF_PWMPOLARITY_NEG (1). Use these readback calls to verify your configuration before starting output, especially when validating that the pulse width does not exceed the period.

Channel Status Display

The sample provides a status display that reads the channel’s BIT, overcurrent, and transition status registers:

check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_BIT_LATCHED, &status));
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_OVERCURRENT_LATCHED, &status));
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_LO_HI_TRANS_LATCHED, &status));
check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_HI_LO_TRANS_LATCHED, &status));

When PWM output is active, you should see the transition status registers toggling as the output switches states. The BIT status verifies that the channel’s output matches the commanded state. If the overcurrent status is set, the output has exceeded the current limit and the channel may have been automatically disabled. On DIF modules, overcurrent detection is inferred from BIT circuitry — if the output state does not match the readback value, the module detects an overcurrent condition. Consult your module’s manual (e.g., DF1 Manual) for overcurrent recovery procedures.

Batch Operations

The sample provides several batch commands that configure all channels at once. These are useful for quickly setting up a multi-channel test scenario.

Demo Configuration

The Demo command configures all channels with incrementing period and pulse width values. Channel 1 gets a 1 ms period with 0.1 ms pulse width, channel 2 gets 2 ms with 0.2 ms, and so on. Burst counts are set to match the channel number. Each channel’s I/O format is also set to output:

for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
   time = ch_loop;
   status |= check_status(naibrd_DIF_SetIOFormat(cardIndex, module, ch_loop, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
   status |= check_status(naibrd_DIF_SetPWM_Period(cardIndex, module, ch_loop, time));
   time /= 10.0;
   status |= check_status(naibrd_DIF_SetPWM_Pulsewidth(cardIndex, module, ch_loop, time));
   status |= check_status(naibrd_DIF_SetPWM_BurstNum(cardIndex, module, ch_loop, ch_loop));
}

Reset to Initial Configuration

The Reset command returns all channels to their initial state: input mode, low output state, minimal pulse width (16 microseconds), zero burst count, standard input/output mode, and zero debounce time:

for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
   status |= check_status(naibrd_DIF_SetOutputState(cardIndex, module, ch_loop, NAI_DIF_STATE_LO));
   status |= check_status(naibrd_DIF_SetIOFormat(cardIndex, module, ch_loop, NAI_DIF_IOFORMAT_INPUT));
   status |= check_status(naibrd_DIF_SetPWM_Pulsewidth(cardIndex, module, ch_loop, 16E-6));
   status |= check_status(naibrd_DIF_SetPWM_BurstNum(cardIndex, module, ch_loop, 0));
   status |= check_status(naibrd_DIF_SetOpMode(cardIndex, module, ch_loop, NAI_DIF_MODE_STD_INPUT_OUTPUT));
   status |= check_status(naibrd_DIF_SetDebounceTime(cardIndex, module, ch_loop, 0.0));
}

Set All Burst / Set All Continuous

The SETBurst and SETCont commands set all channels to burst or continuous PWM mode respectively, which is convenient for quickly switching an entire module’s operating mode during testing.

Troubleshooting Reference

Note
This section summarizes errors covered in the preceding sections. Consult your module’s manual for hardware-specific diagnostics, timing limits, and overcurrent recovery procedures.
Error / Symptom Possible Causes Suggested Resolution

No board found

Board is powered off, connection interface not configured, wrong IP address.

Verify power, cabling, and network configuration. Check the board’s IP address matches your connection settings.

Module not recognized as DIF

Selected module slot does not contain a DIF module, or the module ID is not in the recognized list.

Verify the module is physically installed and select the correct slot index.

NAI_ERROR_NOT_SUPPORTED

The requested operation is not supported on this module type.

Check module compatibility. Not all DIF modules support all enhanced modes.

Entry out of range (period / pulse width)

The requested value exceeds the module’s register capacity or is below the minimum LSB.

Use naibrd_DIF_GetTimebaseLSB() to compute the valid range for your module type.

PWM output does not start

Mode not set to a PWM mode, I/O format not set to output, or naibrd_DIF_StartPWM() not called.

Set the mode, set I/O format to output, configure timing parameters, then call naibrd_DIF_StartPWM().

No output signal observed

Channel I/O format is still set to input, or output driver is disabled due to overcurrent.

Verify both the operating mode and I/O format are configured for output. Check overcurrent status.

Burst count unsupported

Attempting burst count on a module type not handled in the sample’s switch statement.

Check your module’s manual for burst mode support. The sample explicitly handles DF2.

Overcurrent fault

Output load exceeds the channel’s current limit, or a short circuit is present on the differential pair.

Reduce the load, check for wiring faults, and issue an overcurrent reset per the module manual.

Signal integrity issues

Cable too long, missing termination, or excessive noise coupling.

Verify differential pair wiring, enable 120-ohm termination if supported by your module, and keep cable runs within specifications.

Full Source

Full Source — DIF_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_dif.h"
#include "advanced/nai_ether_adv.h"

static const int8_t *CONFIG_FILE = (int8_t *)"default_DIF_PWM.txt";

/* Function prototypes */
static void Run_DIF_PWM(int32_t cardIndex, int32_t module, int32_t ModuleID);
static void Cfg_DIF_PWM_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
static void Display_DIF_PWM_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID);
static nai_status_t Display_DIF_PWM_Configuration(int32_t paramCount, int32_t* p_params);
static nai_status_t Display_DIF_Status(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_PWM_Mode(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_PWM_Period(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_PWM_Pulsewidth(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_PWM_Burstcount(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DIF_PWM_Polarity(int32_t paramCount, int32_t* p_params);

static const int32_t DEF_DIF_CHANNEL       = 1;
/****** Command Table *******/
enum dif_pwm_commands
{
   DIF_PWM_CMD_MODE,
   DIF_PWM_CMD_PERIOD,
   DIF_PWM_CMD_PULSEWIDTH,
   DIF_PWM_CMD_BURSTCOUNT,
   DIF_PWM_CMD_POLARITY,
   DIF_PWM_CMD_PWM_CFG,
   DIF_PWM_CMD_PWM_START,
   DIF_PWM_CMD_PWM_STOP,
   DIF_PWM_CMD_PWM_DEMO,
   DIF_PWM_CMD_PWM_INITIAL,
   DIF_PWM_CMD_STATUS,
   DIF_PWM_CMD_PWM_BURST,
   DIF_PWM_CMD_PWM_CONT,
   DIF_PWM_CMD_COUNT
};

/****** Command Tables *******/
naiapp_cmdtbl_params_t DIF_PWM_MenuCmds[] = {
   {"Mode",       "    DIF Select PWM Mode",                         DIF_PWM_CMD_MODE,          Configure_DIF_PWM_Mode},
   {"Period",     "    DIF Set PWM Period",                          DIF_PWM_CMD_PERIOD,        Configure_DIF_PWM_Period},
   {"Width",      "    DIF Set PWM Pulsewidth",                      DIF_PWM_CMD_PULSEWIDTH,    Configure_DIF_PWM_Pulsewidth},
   {"Count",      "    DIF Set PWM burst count",                     DIF_PWM_CMD_BURSTCOUNT,    Configure_DIF_PWM_Burstcount},
   {"POlarity",   "    DIF Set PWM Polarity",                        DIF_PWM_CMD_POLARITY,      Configure_DIF_PWM_Polarity},
   {"PM",         "    DIF Display PWM configuration settings",      DIF_PWM_CMD_PWM_CFG,       Display_DIF_PWM_Configuration},
   {"Trigger",    "    DIF Start PWM output",                        DIF_PWM_CMD_PWM_START,     NULL},
   {"Halt",       "    DIF Stop PWM output",                         DIF_PWM_CMD_PWM_STOP,      NULL},
   {"Demo",       "    DIF Demo PWM Settings",                       DIF_PWM_CMD_PWM_DEMO,      NULL},
   {"Reset",      "    DIF Reset All Channels to Initial Settings",  DIF_PWM_CMD_PWM_INITIAL,   NULL},
   {"Stat",       "    DIF Display Status",                          DIF_PWM_CMD_STATUS,        Display_DIF_Status},
   {"SETBurst",   "    DIF Set all channels to PWM Burst",           DIF_PWM_CMD_PWM_BURST,     NULL},
   {"SETCont",    "    DIF Set all channels to PWM Continuous",      DIF_PWM_CMD_PWM_CONT,      NULL},
};

/**************************************************************************************************************/
/**
<summary>
The purpose of the DIF_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 DIF routines.
 - ClearDeviceCfg
 - QuerySystemCfg
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - SaveDeviceCfg
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t DIF_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_DIF_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_DIF_PWM prompts the user for the card, module and channel to use for the application and calls
Cfg_DIF_PWM_Channel if the card, module, channel is valid for as a discrete module.
</summary>
*/
/**************************************************************************************************************/
void Run_DIF_PWM(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
   int32_t MaxChannel;

   MaxChannel = naibrd_DIF_GetChannelCount(ModuleID);

   if (MaxChannel == 0)
   {
      printf(" *** Module selection not recognized as DIF module. ***\n\n");
   }
   else
   {
      Cfg_DIF_PWM_Channel(cardIndex, module, ModuleID, MaxChannel);
   }
}

/**************************************************************************************************************/
/**
<summary>
Display_DIF_PatternGen_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for basic operation.
</summary>
*/
/**************************************************************************************************************/
void Display_DIF_PWM_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID)
{
   uint32_t ioformat = 0;
   nai_dif_state_t outputstate = 0;
   nai_dif_state_t inputstate = 0;
   nai_dif_enhanced_mode_t opmode = 0;

   uint32_t ModuleVer;
   uint32_t ModuleRev;
   uint32_t ModInfo_Special;
   naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
   check_status(naibrd_DIF_GetIOFormat(cardIndex, module, chan, &ioformat));
   check_status(naibrd_DIF_GetOutputState(cardIndex, module, chan, &outputstate));
   check_status(naibrd_DIF_GetInputState(cardIndex, module, chan, &inputstate));
   check_status(naibrd_DIF_GetOpMode(cardIndex, module, chan, &opmode));

   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_DIF_IOFORMAT_INPUT:
      printf("  Input   ");
      break;
   case NAI_DIF_GEN3_IOFORMAT_OUTPUT:
   case NAI_DIF_GEN5_IOFORMAT_OUTPUT:
      printf(" High-side");
      break;
   default:
      printf(" Unknown  ");
      break;
   }
   switch (outputstate)
   {
   case NAI_DIF_STATE_LO:
      printf("  LOW     ");
      break;
   case NAI_DIF_STATE_HI:
      printf("  HIGH    ");
      break;
   default:
      printf(" Unknown  ");
      break;
   }

   switch (inputstate)
   {
   case NAI_DIF_STATE_LO:
      printf(" LOW Input  ");
      break;
   case NAI_DIF_STATE_HI:
      printf("HIGH Input  ");
      break;
   default:
      printf("Unknown     ");
      break;
   }
   switch (opmode)
   {
   case NAI_DIF_MODE_STD_INPUT_OUTPUT:
      printf("STD_INPUT_OUTPUT   ");
      break;
   case NAI_DIF_MODE_MEASURE_HIGH_TIME:
      printf("NAI_DIF_MODE_MEASURE_HIGH_TIME   ");
      break;
   case NAI_DIF_MODE_MEASURE_LOW_TIME:
      printf("NAI_DIF_MODE_MEASURE_LOW_TIME   ");
      break;
   case NAI_DIF_MODE_TIMESTAMP_RISING_EDGES:
      printf("NAI_DIF_MODE_TIMESTAMP_RISING_EDGES   ");
      break;
   case NAI_DIF_MODE_TIMESTAMP_FALLING_EDGES:
      printf("NAI_DIF_MODE_TIMESTAMP_FALLING_EDGES   ");
      break;
   case NAI_DIF_MODE_TIMESTAMP_ALL_EDGES:
      printf("NAI_DIF_MODE_TIMESTAMP_ALL_EDGES   ");
      break;
   case NAI_DIF_MODE_COUNT_RISING_EDGES:
      printf("NAI_DIF_MODE_COUNT_RISING_EDGES   ");
      break;
   case NAI_DIF_MODE_COUNT_FALLING_EDGES:
      printf("NAI_DIF_MODE_COUNT_FALLING_EDGES   ");
      break;
   case NAI_DIF_MODE_COUNT_ALL_EDGES:
      printf("NAI_DIF_MODE_COUNT_ALL_EDGES   ");
      break;
   case NAI_DIF_MODE_MEASURE_PERIOD_FROM_RISING_EDGE:
      printf("NAI_DIF_MODE_MEASURE_PERIOD_FROM_RISING_EDGE   ");
      break;
   case NAI_DIF_MODE_MEASURE_FREQUENCY:
      printf("NAI_DIF_MODE_MEASURE_FREQUENCY   ");
      break;
   case NAI_DIF_MODE_OUTPUT_PWM_FOREVER:
      printf("NAI_DIF_MODE_OUTPUT_PWM_FOREVER   ");
      break;
   case NAI_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES:
      printf("NAI_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES   ");
      break;
   case NAI_DIF_MODE_OUTPUT_PATTERN_RAM:
      printf("NAI_DIF_MODE_OUTPUT_PATTERN_RAM   ");
      break;
   default:
      printf("Unknown    ");
      break;
   }

}
/**************************************************************************************************************/
/**
<summary>
Cfg_DIF_PWM_Channel handles calling the Display_DIF_PWM_ChannelCfg routine to display the discrete channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
void Cfg_DIF_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 chan, defaultchan = 1;
   int32_t cmd;
   int32_t ch_loop;
   float64_t time;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   naiapp_AppParameters_t  dif_params;
   p_naiapp_AppParameters_t dif_pwm_params = &dif_params;
   dif_pwm_params->cardIndex = cardIndex;
   dif_pwm_params->module = module;
   dif_pwm_params->modId = ModuleID;
   while (bContinue)
   {
      printf("    \r\n\r\n");
      printf("Channel selection \r\n");
      printf("================= \r\n");
      defaultchan = DEF_DIF_CHANNEL;
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &chan);
      dif_pwm_params->channel = chan;

      /* Configure the selected channel for Pattern Generator Mode and output mode */
      check_status(naibrd_DIF_SetOpMode(cardIndex, module, chan, NAI_DIF_MODE_OUTPUT_PWM_FOREVER));
      check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));

      naiapp_utils_LoadParamMenuCommands(DIF_PWM_CMD_COUNT, DIF_PWM_MenuCmds);
      while (bContinue)
      {
         Display_DIF_PWM_ChannelCfg(cardIndex, module, chan, ModuleID);
         naiapp_display_ParamMenuCommands((int8_t *)"DIF PWM Menu");
         printf("\nType DIF command or %c to quit : ", NAI_QUIT_CHAR);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
               if (bCmdFound)
               {
                  switch (cmd)
                  {
                  case DIF_PWM_CMD_MODE:
                  case DIF_PWM_CMD_PERIOD:
                  case DIF_PWM_CMD_PULSEWIDTH:
                  case DIF_PWM_CMD_BURSTCOUNT:
                  case DIF_PWM_CMD_POLARITY:
                  case DIF_PWM_CMD_PWM_CFG:
                  case DIF_PWM_CMD_STATUS:
                     DIF_PWM_MenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)dif_pwm_params);
                     break;
                  case DIF_PWM_CMD_PWM_START:
                     check_status(naibrd_DIF_StartPWM(cardIndex, module, chan));
                     break;
                  case DIF_PWM_CMD_PWM_STOP:
                     check_status(naibrd_DIF_StopPWM(cardIndex, module, chan));
                     printf("Mode reset to Input\n");
                     break;
                  case DIF_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_DIF_SetIOFormat(cardIndex, module, ch_loop, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
                                    status |= check_status(naibrd_DIF_SetPWM_Period(cardIndex, module, ch_loop, time));
                                    time /= 10.0;
                                    status |= check_status(naibrd_DIF_SetPWM_Pulsewidth(cardIndex, module, ch_loop, time));
                                    status |= check_status(naibrd_DIF_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 DIF_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_DIF_SetOutputState(cardIndex, module, ch_loop, NAI_DIF_STATE_LO));
                                    status |= check_status(naibrd_DIF_SetIOFormat(cardIndex, module, ch_loop, NAI_DIF_IOFORMAT_INPUT));
                                    status |= check_status(naibrd_DIF_SetPWM_Pulsewidth(cardIndex, module, ch_loop, 16E-6));
                                    status |= check_status(naibrd_DIF_SetPWM_BurstNum(cardIndex, module, ch_loop, 0));
                                    status |= check_status(naibrd_DIF_SetOpMode( cardIndex, module, ch_loop, NAI_DIF_MODE_STD_INPUT_OUTPUT));
                                    status |= check_status(naibrd_DIF_SetDebounceTime(cardIndex, module, ch_loop, 0.0));
                                    status |= check_status(naibrd_DIF_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 DIF_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_DIF_SetOpMode( cardIndex, module, ch_loop, NAI_DIF_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 DIF_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_DIF_SetOpMode( cardIndex, module, ch_loop, NAI_DIF_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_DIF_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_DIF_PWM_Mode(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   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_DIF_SetOpMode( cardIndex, module, chan, NAI_DIF_MODE_OUTPUT_PWM_FOREVER));
            check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
         }
         else if ((toupper(inputBuffer[0]) == 'B'))
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAI_DIF_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES));
            check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_GEN5_IOFORMAT_OUTPUT));
         }
         else if ((toupper(inputBuffer[0]) == 'N'))
         {
            check_status(naibrd_DIF_SetOpMode( cardIndex, module, chan, NAI_DIF_MODE_STD_INPUT_OUTPUT));
            check_status(naibrd_DIF_SetIOFormat(cardIndex, module, chan, NAI_DIF_IOFORMAT_INPUT));
         }
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_DIF_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_DIF_PWM_Period(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   bool_t bQuit = FALSE;
   float64_t time = 0.0;
   float64_t lsb = 0;
   float64_t min = 1;
   float64_t max = -1;
   uint32_t ModuleID;
   uint32_t ModuleVer;
   uint32_t ModuleRev;
   uint32_t ModInfo_Special;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   printf("\nEnter the desired period in ms: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
         time = atof((const char *)inputBuffer); /*entry in milliseconds*/
         lsb = naibrd_DIF_GetTimebaseLSB(ModuleID);
         switch (ModuleID)
         {
         case NAI_MODULE_ID_DF2:
            min =(float64_t)(0x2u * lsb);
            max =(float64_t)(0xFFFFFFFF * lsb);
         default:
            break;
         }
         if (time > max || time < min)
            printf(" Entry out of range.  Range %7.3f to %7.3f ms\n", min, max);
         else
         {
            check_status(naibrd_DIF_SetPWM_Period(cardIndex, module, chan, time));
         }
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DIF_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_DIF_PWM_Pulsewidth(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   bool_t bQuit = FALSE;
   float64_t time = 0.0;
   float64_t lsb = 0;
   float64_t min = 1;
   float64_t max = -1;
   uint32_t ModuleID;
   uint32_t ModuleVer;
   uint32_t ModuleRev;
   uint32_t ModInfo_Special;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   printf("\nEnter the desired 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_DIF_GetTimebaseLSB(ModuleID);
         switch (ModuleID)
         {
         case NAI_MODULE_ID_DF2:
            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_DIF_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_DIF_PWM_Burstcount(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   bool_t bQuit = FALSE;
   uint32_t burstcount;
   uint32_t ModuleID;
   uint32_t ModuleVer;
   uint32_t ModuleRev;
   uint32_t ModInfo_Special;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   printf("\nEnter the desired burst count: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
         burstcount = atoi((const char *)inputBuffer);
         switch (ModuleID)
         {
         case NAI_MODULE_ID_DF2:
            if (burstcount < 1)
            {
               burstcount = 1; /*minimum count is one*/
               printf("Setting burstcount to minimum of 1.\n");
            }
            check_status(naibrd_DIF_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_DIF_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_DIF_PWM_Polarity(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   printf("\n == PWM Output Polarity Selection == \n Pos  DIF PWM positive going pulse output \n Neg  DIF PWM negative going pulse output \n\n Type DIF command : ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         if ((toupper(inputBuffer[0]) == 'P'))
            check_status(naibrd_DIF_SetPWM_Polarity( cardIndex, module, chan, (nai_dif_pwm_polarity_t) NAI_DIF_PWMPOLARITY_POS ));
         else if ((toupper(inputBuffer[0]) == 'N'))
            check_status(naibrd_DIF_SetPWM_Polarity( cardIndex, module, chan, (nai_dif_pwm_polarity_t) NAI_DIF_PWMPOLARITY_NEG ));
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Display_DIF_PWM_Configuration illustrate the methods to call in the naibrd library to retrieve the PWM
configuration settings.
</summary>
*/
/**************************************************************************************************************/
nai_status_t Display_DIF_PWM_Configuration(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   nai_dif_pwm_polarity_t polaritysetting;
   float64_t period;
   float64_t pulsewidth;
   uint32_t burstnumber;

#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_DIF_GetPWM_Period(cardIndex, module, chan, &period));
   printf("    %10.6f   ", period);

   check_status(naibrd_DIF_GetPWM_Pulsewidth(cardIndex, module, chan, &pulsewidth));
   printf("     %10.6f   ", pulsewidth);

   check_status(naibrd_DIF_GetPWM_BurstNum(cardIndex, module, chan, &burstnumber));
   printf("     0x%08X   ", burstnumber);

   check_status(naibrd_DIF_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_DIF_Status(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_dif_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_dif_params->cardIndex;
   int32_t module = p_dif_params->module;
   int32_t chan = p_dif_params->channel;
   nai_status_bit_t status;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   /* Available status:
         NAI_DIF_STATUS_BIT_LATCHED,
         NAI_DIF_STATUS_OVERCURRENT_LATCHED,
         NAI_DIF_STATUS_LO_HI_TRANS_LATCHED,
         NAI_DIF_STATUS_HI_LO_TRANS_LATCHED,
   */
   printf("\n");
   printf("  ----------------- Status ----------------------------\n");
   printf("   BIT      OC    Lo-Hi   Hi-Lo  \n");
   printf(" ------- -------- ------ ------- \n");

   check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_BIT_LATCHED, &status));
   printf("  %3i   ", status);

   check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_OVERCURRENT_LATCHED, &status));
   printf("  %3i   ", status);

   check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_LO_HI_TRANS_LATCHED, &status));
   printf("  %3i   ", status);

   check_status(naibrd_DIF_GetStatus(cardIndex, module, chan, NAI_DIF_STATUS_HI_LO_TRANS_LATCHED, &status));
   printf("  %3i   ", status);

   printf("\n\n");

   return NAI_ERROR_UNKNOWN;
}

Help Bot

X