DT PWM
Edit this on GitLab
DT PWM Sample Application (SSK 1.x)
Overview
The DT PWM sample application demonstrates how to configure and generate Pulse Width Modulation (PWM) output on discrete (DT) channels using the NAI Software Support Kit (SSK 1.x). PWM is a technique for encoding information or controlling power delivery by switching a digital output between high and low states at a programmable rate. By adjusting how long the output stays high versus low within each cycle, you control the effective energy delivered to a load — this is the basis for motor speed control, LED dimming, servo positioning, and analog signal synthesis from digital hardware.
Three parameters define a PWM signal:
-
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 signal; a 10 ms period produces 100 Hz. Your choice of period depends on the load: motor drivers typically need 1-20 kHz to avoid audible switching noise, while servo control signals use 50 Hz (20 ms period).
-
Pulse width (duty cycle) — the time the output is held in its active state within each period, also specified in milliseconds. The ratio of pulse width to period is the duty cycle. A 0.5 ms pulse width in a 1 ms period gives a 50% duty cycle — the output spends equal time high and low. A 0.1 ms pulse width in the same period gives 10% duty cycle and delivers less average power. The pulse width must always be less than or equal to the period.
-
Polarity — determines whether the active pulse is a positive-going (high) or negative-going (low) excursion from the idle state. With positive polarity, the output idles low and pulses high for the pulse width duration. With negative polarity, the output idles high and pulses low. Polarity selection depends on whether your load is active-high or active-low.
The DT module supports two PWM operating modes:
-
Continuous mode — the channel outputs the PWM waveform indefinitely once triggered, running until explicitly stopped. Use this for steady-state applications such as motor speed control or LED brightness regulation.
-
Burst mode — the channel outputs a specific number of PWM cycles (the burst count) and then stops automatically. Use this for precise pulse generation such as stepper motor stepping, timed stimulus injection, or protocol signaling where you need an exact number of pulses. Burst mode is supported on DT4, D4P, and CM8 modules only — it is not available on KA or K6 modules.
The DT module also supports a master channel feature that lets you synchronize PWM output across multiple channels within a six-channel group. When you designate a channel as master, triggering that channel starts all channels in its group simultaneously, ensuring phase-aligned multi-channel PWM output.
This sample supports the following DT module types: DT1, DT4, D4P, K6, KA, and KB. It also works with combination modules that include discrete functionality: CM1, CM2, and CM8. For basic DT channel configuration (I/O format, thresholds, output state), see the DT BasicOps guide. Consult your module’s manual (e.g., DT1 Manual) for hardware-specific PWM timing limits and register details.
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with a DT module installed (DT1, DT4, D4P, K6, KA, KB, CM1, CM2, or CM8).
-
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 DT_PWM executable from your build output directory. On startup the application looks for a configuration file (default_DT_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 DT. For details on board connection configuration, see the First Time Setup Guide. |
The main() function follows a standard SSK 1.x startup flow:
-
Call
naiapp_RunBoardMenu()to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_DT_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. -
Query the user for a card index with
naiapp_query_CardIndex(). -
Query for a module slot with
naiapp_query_ModuleNumber(). -
Retrieve the module ID with
naibrd_GetModuleID()so downstream code can adapt to the specific DT variant installed.
#if defined (__VXWORKS__)
int32_t DT_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_DT_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_DT_PWM() validates that the selected module is a recognized DT type by calling naibrd_DT_GetChannelCount(). If the channel count is zero, the module is not a DT module and the sample prints an error.
MaxChannel = naibrd_DT_GetChannelCount(ModuleID);
if (MaxChannel == 0)
{
printf(" *** Module selection not recognized as DT module. ***\n\n");
}
else
{
Cfg_DT_PWM_Channel(cardIndex, module, ModuleID, MaxChannel);
}
|
Important
|
Common Connection Errors
|
Program Structure
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 dt_params;
p_naiapp_AppParameters_t dt_pwm_params = &dt_params;
dt_pwm_params->cardIndex = cardIndex;
dt_pwm_params->module = module;
dt_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 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) |
MAster |
Set master channel for synchronized group triggering |
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 (I/O, BIT, transitions, overcurrent) |
SETBurst |
Set all channels to burst mode |
SETCont |
Set all channels to continuous mode |
PWM Mode Selection
Before generating PWM output, you must set the channel’s operating mode. The DT module supports several enhanced modes; this sample focuses on the two PWM modes and provides options to return to input mode.
To set a channel to continuous PWM mode in your own application, call naibrd_DT_SetOpMode() with NAI_DT_MODE_OUTPUT_PWM_FOREVER and enable enhanced mode with naibrd_DT_SetBasicOpModeEnable():
/* Continuous PWM -- output runs until explicitly stopped */
check_status(naibrd_DT_SetOpMode(cardIndex, module, chan, NAI_DT_MODE_OUTPUT_PWM_FOREVER));
check_status(naibrd_DT_SetBasicOpModeEnable(cardIndex, module, chan, NAI_DT_IOMODE_ENHANCED));
To set burst mode, use NAI_DT_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES instead:
/* Burst PWM -- output runs for the configured burst count, then stops */
check_status(naibrd_DT_SetOpMode(cardIndex, module, chan, NAI_DT_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES));
check_status(naibrd_DT_SetBasicOpModeEnable(cardIndex, module, chan, NAI_DT_IOMODE_ENHANCED));
On modules with FPGA revision earlier than NAI_DT_Rev_10_2, the sample also offers an "Enhanced Input" mode (NAI_DT_MODE_ENHANCED_INPUT) and a "Basic Input" mode (NAI_DT_MODE_BASIC_INPUT) to return the channel to input operation. On newer FPGA revisions, the basic/enhanced distinction is not applicable — only Continuous and Burst PWM modes are offered.
naibrd_GetModuleRev(cardIndex, module, &modprocrev, &modfpgarev);
if (modfpgarev < NAI_DT_Rev_10_2)
{
/* Older FPGA: Enhanced Input and Basic Input modes available */
check_status(naibrd_DT_SetOpMode(cardIndex, module, chan, NAI_DT_MODE_ENHANCED_INPUT));
}
|
Important
|
Common Errors
|
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_DT_SetPWM_Period() with the desired value in milliseconds:
float64_t time = 1.0; /* 1 ms period = 1 kHz frequency */
check_status(naibrd_DT_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_DT_GetTimebaseLSB() to compute the range dynamically:
lsb = naibrd_DT_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAI_MODULE_ID_DT4:
case NAI_MODULE_ID_D4P:
case NAI_MODULE_ID_CM8:
min = (float64_t)(0x1u * lsb);
max = (float64_t)(0xFFFFFFFF * lsb);
break;
case NAI_MODULE_ID_KA:
case NAI_MODULE_ID_K6:
min = (float64_t)(0x2u * lsb);
max = (float64_t)(0xFFFF * lsb);
break;
}
DT4, D4P, and CM8 modules use a 32-bit period register, providing a wide timing range. KA and K6 modules use a 16-bit register with a coarser resolution, limiting both the maximum period and the minimum step size. Consult your module’s manual for the exact timebase LSB value and resulting timing limits.
Setting the Pulse Width
The pulse width determines how long the output stays in its active state during each period. The duty cycle is the ratio of pulse width to period — for example, a 0.3 ms pulse width with a 1 ms period gives a 30% duty cycle.
To set the pulse width, call naibrd_DT_SetPWM_Pulsewidth() with the value in milliseconds:
float64_t time = 0.5; /* 0.5 ms pulse width */
check_status(naibrd_DT_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 — DT4/D4P/CM8 modules support 32-bit values while KA/K6 modules use 16-bit values. The minimum pulse width on DT4/D4P/CM8 can be zero (output stays inactive for the entire period), while KA/K6 require a minimum of one LSB.
|
Important
|
Common Errors
|
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_DT_SetPWM_BurstNum():
uint32_t burstcount = 10; /* Output exactly 10 PWM cycles */
check_status(naibrd_DT_SetPWM_BurstNum(cardIndex, module, chan, burstcount));
The minimum burst count is 1. The sample enforces this:
if (burstcount < 1)
{
burstcount = 1;
printf("Setting burstcount to minimum of 1.\n");
}
Burst count configuration is supported on DT4, D4P, and CM8 modules only. On other module types (KA, K6), the sample prints "Unsupported function for this module." If you attempt to set a burst count on an unsupported module, the call will have no effect on the output behavior.
Burst mode is useful for applications that require a precise number of output pulses — for example, stepping a motor a known number of steps, generating a timed stimulus pulse train, or producing a fixed-length protocol preamble.
|
Important
|
Common Errors
|
Polarity
PWM polarity determines the direction of the active pulse relative to the idle state. With positive polarity, the output idles low and the pulse drives high. With negative polarity, the output idles high and the pulse drives low.
To set the polarity, call naibrd_DT_SetPWM_Polarity():
/* Positive polarity: idle low, pulse high */
check_status(naibrd_DT_SetPWM_Polarity(cardIndex, module, chan,
(nai_dt_pwm_polarity_t)NAI_DT_PWMPOLARITY_POS));
/* Negative polarity: idle high, pulse low */
check_status(naibrd_DT_SetPWM_Polarity(cardIndex, module, chan,
(nai_dt_pwm_polarity_t)NAI_DT_PWMPOLARITY_NEG));
Choose polarity based on your load’s requirements. If your load is active-high (it activates when the signal goes high), use positive polarity. If your load is active-low (it activates when the signal is pulled low), use negative polarity. The polarity setting does not affect the period or pulse width — it only inverts the waveform.
Master Channel
The master channel feature allows you to synchronize PWM output across multiple channels within a six-channel group. When you designate a channel as the master, triggering that channel simultaneously starts all channels in its group, ensuring phase-aligned output. This is useful for applications such as multi-phase motor control or coordinated LED patterns where several outputs must start at exactly the same time.
To set a master channel, call naibrd_DT_SetPWMMasterChannel():
uint32_t masterchannel = 1; /* Channel 1 is the master for its group */
check_status(naibrd_DT_SetPWMMasterChannel(cardIndex, module, masterchannel));
To reset the master channel assignment (so each channel triggers independently), call naibrd_DT_ResetPWMMasterChannel():
check_status(naibrd_DT_ResetPWMMasterChannel(cardIndex, module, chan));
To read back the current master channel assignment, call naibrd_DT_GetPWMMasterChannel():
int32_t masterchannel;
check_status(naibrd_DT_GetPWMMasterChannel(cardIndex, module, chan, &masterchannel));
|
Important
|
Common Errors
|
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_DT_StartPWM():
check_status(naibrd_DT_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_DT_StopPWM():
check_status(naibrd_DT_StopPWM(cardIndex, module, chan));
Stopping PWM output resets the channel’s mode back to input. If you want to restart PWM output, you will need to reconfigure the mode before calling naibrd_DT_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_dt_pwm_polarity_t polaritysetting;
int32_t masterchannel;
check_status(naibrd_DT_GetPWM_Period(cardIndex, module, chan, &period));
check_status(naibrd_DT_GetPWM_Pulsewidth(cardIndex, module, chan, &pulsewidth));
check_status(naibrd_DT_GetPWM_BurstNum(cardIndex, module, chan, &burstnumber));
check_status(naibrd_DT_GetPWM_Polarity(cardIndex, module, chan, &polaritysetting));
check_status(naibrd_DT_GetPWMMasterChannel(cardIndex, module, chan, &masterchannel));
The period and pulse width are returned in milliseconds. The polarity is returned as NAI_DT_PWMPOLARITY_POS (0) or NAI_DT_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 I/O configuration, output state, input state, and BIT/transition/overcurrent status registers. This information is useful for verifying that the channel is configured correctly and for diagnosing problems:
check_status(naibrd_DT_GetIOFormat(cardIndex, module, chan, &IOformat));
check_status(naibrd_DT_GetOutputState(cardIndex, module, chan, &state));
check_status(naibrd_DT_GetInputState(cardIndex, module, chan, &state));
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_BIT_LATCHED, &status));
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_BIT_REALTIME, &status));
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_LO_HI_TRANS_LATCHED, &status));
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_HI_LO_TRANS_LATCHED, &status));
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_OVERCURRENT_LATCHED, &status));
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_OVERCURRENT_REALTIME, &status));
When PWM output is active, you should see the transition status registers toggling as the output switches states. If the BIT status shows a fault, the channel’s output driver may have detected a mismatch between the commanded and actual output state. If the overcurrent status is set, the output has exceeded the current limit and the channel may have been automatically disabled — consult your module’s 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. This is not available on KA or K6 modules (burst mode is unsupported).
for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
time = ch_loop;
status |= check_status(naibrd_DT_SetPWM_Period(cardIndex, module, ch_loop, time));
time /= 10.0;
status |= check_status(naibrd_DT_SetPWM_Pulsewidth(cardIndex, module, ch_loop, time));
status |= check_status(naibrd_DT_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, default pulse width (0.00361 ms), burst count of 1, enhanced input mode, basic I/O mode, and zero debounce time.
for (ch_loop = 1; ch_loop <= MaxChannel; ch_loop++)
{
status |= check_status(naibrd_DT_SetOutputState(cardIndex, module, ch_loop, NAI_DT_STATE_LO));
status |= check_status(naibrd_DT_SetIOFormat(cardIndex, module, ch_loop, NAI_DT_IOFORMAT_INPUT));
status |= check_status(naibrd_DT_SetPWM_Pulsewidth(cardIndex, module, ch_loop, 0.00361));
status |= check_status(naibrd_DT_SetPWM_BurstNum(cardIndex, module, ch_loop, 1));
status |= check_status(naibrd_DT_SetOpMode(cardIndex, module, ch_loop, NAI_DT_MODE_ENHANCED_INPUT));
status |= check_status(naibrd_DT_SetBasicOpModeEnable(cardIndex, module, ch_loop, NAI_DT_IOMODE_BASIC));
status |= check_status(naibrd_DT_SetDebounceTime(cardIndex, module, ch_loop, 0.0));
}
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 DT |
Selected module slot does not contain a DT module, or the module ID is not in the recognized list. |
Verify the module is physically installed and select the correct slot index. |
|
The requested operation (burst mode, enhanced input) is not supported on this module type or FPGA revision. |
Check module compatibility. Burst mode requires DT4, D4P, or CM8. Older FPGA revisions may not support certain modes. |
Entry out of range (period / pulse width) |
The requested value exceeds the module’s register capacity or is below the minimum LSB. |
Use |
PWM output does not start |
Mode not set to a PWM mode, or |
Set the mode to Continuous or Burst, configure timing parameters, then call |
No output signal observed |
Channel I/O format may still be set to input, or output driver is disabled due to overcurrent. |
Verify the channel is in a PWM output mode (not input mode). Check overcurrent status and reset if needed. |
Burst mode unsupported |
Attempting burst count or burst mode on KA or K6 modules. |
Use continuous mode on KA/K6 modules, or switch to a DT4/D4P/CM8 module for burst capability. |
Overcurrent fault |
Output load exceeds the channel’s current limit, causing the hardware to disable the output driver. |
Reduce the load, check for short circuits, and issue an overcurrent reset per the module manual. |
Master channel has no effect |
Slave channels are not in PWM mode, or the master is set in the wrong channel group. |
Ensure all channels in the group are configured for PWM mode before setting the master. |
Full Source
Full Source — DT_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_dt.h"
#include "advanced/nai_ether_adv.h"
static const int8_t *CONFIG_FILE = (const int8_t *)"default_DT_PWM.txt";
/* Function prototypes */
static void Run_DT_PWM(int32_t cardIndex, int32_t module, int32_t ModuleID);
static void Cfg_DT_PWM_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
static void Display_DT_PWM_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID);
static nai_status_t Display_DT_PWM_Configuration(int32_t paramCount, int32_t* p_params);
static nai_status_t Display_DT_Status(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DT_PWM_Mode(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DT_PWM_Polarity(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DT_PWM_Period(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DT_PWM_Pulsewidth(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DT_PWM_Burstcount(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_DT_PWM_Master(int32_t paramCount, int32_t* p_params);
static const int32_t DEF_DT_CHANNEL = 1;
/****** Command Table *******/
enum dt_pwm_commands
{
DT_PWM_CMD_MODE,
DT_PWM_CMD_PERIOD,
DT_PWM_CMD_PULSEWIDTH,
DT_PWM_CMD_BURSTCOUNT,
DT_PWM_CMD_POLARITY,
DT_PWM_CMD_MASTER,
DT_PWM_CMD_PWM_CFG,
DT_PWM_CMD_PWM_START,
DT_PWM_CMD_PWM_STOP,
DT_PWM_CMD_PWM_DEMO,
DT_PWM_CMD_PWM_INITIAL,
DT_PWM_CMD_STATUS,
DT_PWM_CMD_PWM_BURST,
DT_PWM_CMD_PWM_CONT,
DT_PWM_CMD_COUNT
};
/****** Command Tables *******/
naiapp_cmdtbl_params_t DT_PWM_MenuCmds[] = {
{"Mode", " DT Select PWM Mode", DT_PWM_CMD_MODE, Configure_DT_PWM_Mode},
{"Period", " DT Set PWM Period", DT_PWM_CMD_PERIOD, Configure_DT_PWM_Period},
{"Width", " DT Set PWM Pulsewidth", DT_PWM_CMD_PULSEWIDTH, Configure_DT_PWM_Pulsewidth},
{"Count", " DT Set PWM Burst count", DT_PWM_CMD_BURSTCOUNT, Configure_DT_PWM_Burstcount},
{"POlarity", " DT Set PWM Polarity", DT_PWM_CMD_POLARITY, Configure_DT_PWM_Polarity},
{"MAster", " DT Set Master channel", DT_PWM_CMD_MASTER, Configure_DT_PWM_Master},
{"PM", " DT Display PWM configuration settings", DT_PWM_CMD_PWM_CFG, Display_DT_PWM_Configuration},
{"Trigger", " TTL Start PWM output", DT_PWM_CMD_PWM_START, NULL},
{"Halt", " TTL Stop PWM output", DT_PWM_CMD_PWM_STOP, NULL},
{"Demo", " DT Demo PWM Settings", DT_PWM_CMD_PWM_DEMO, NULL},
{"Reset", " DT Reset All Channels to Initial Settings",DT_PWM_CMD_PWM_INITIAL, NULL},
{"Stat", " DT Display Status", DT_PWM_CMD_STATUS, Display_DT_Status},
{"SETBurst", " DT Set all channels to PWM Burst", DT_PWM_CMD_PWM_BURST, NULL},
{"SETCont", " DT Set all channels to PWM Continuous", DT_PWM_CMD_PWM_CONT, NULL},
};
/**************************************************************************************************************/
/**
<summary>
The purpose of the DT_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 DT routines.
- ClearDeviceCfg
- QuerySystemCfg
- DisplayDeviceCfg
- GetBoardSNModCfg
- SaveDeviceCfg
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t DT_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_DT_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_DT_PWM prompts the user for the card, module and channel to use for the application and calls
Cfg_DT_PWM_Channel if the card, module, channel is valid for as a discrete module.
</summary>
*/
/**************************************************************************************************************/
static void Run_DT_PWM(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
int32_t MaxChannel;
MaxChannel = naibrd_DT_GetChannelCount(ModuleID);
if (MaxChannel == 0)
{
printf(" *** Module selection not recognized as DT module. ***\n\n");
}
else
{
Cfg_DT_PWM_Channel(cardIndex, module, ModuleID, MaxChannel);
}
}
/**************************************************************************************************************/
/**
<summary>
Cfg_DT_PWM_Channel handles calling the Display_DT_PWM_ChannelCfg routine to display the discrete channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
static void Cfg_DT_PWM_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel)
{
nai_status_t status = 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 dt_params;
p_naiapp_AppParameters_t dt_pwm_params = &dt_params;
dt_pwm_params->cardIndex = cardIndex;
dt_pwm_params->module = module;
dt_pwm_params->modId = ModuleID;
while (bContinue)
{
printf(" \r\n\r\n");
printf("Channel selection \r\n");
printf("================= \r\n");
defaultchan = DEF_DT_CHANNEL;
bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &chan);
dt_pwm_params->channel = chan;
naiapp_utils_LoadParamMenuCommands(DT_PWM_CMD_COUNT, DT_PWM_MenuCmds);
while (bContinue)
{
Display_DT_PWM_ChannelCfg(cardIndex, module, chan, ModuleID);
naiapp_display_ParamMenuCommands((int8_t *)"DT PWM Menu");
printf("\nType DT command or %c to return to module select menu: ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case DT_PWM_CMD_MODE:
case DT_PWM_CMD_PERIOD:
case DT_PWM_CMD_PULSEWIDTH:
case DT_PWM_CMD_BURSTCOUNT:
case DT_PWM_CMD_POLARITY:
case DT_PWM_CMD_MASTER:
case DT_PWM_CMD_PWM_CFG:
case DT_PWM_CMD_STATUS:
DT_PWM_MenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)dt_pwm_params);
break;
case DT_PWM_CMD_PWM_START:
check_status(naibrd_DT_StartPWM(cardIndex, module, chan));
break;
case DT_PWM_CMD_PWM_STOP:
check_status(naibrd_DT_StopPWM(cardIndex, module, chan));
printf("Mode reset to Input\n");
break;
case DT_PWM_CMD_PWM_DEMO:
{
if ((ModuleID == NAI_MODULE_ID_KA) || (ModuleID == NAI_MODULE_ID_K6))
{
printf("PWM burst mode not supported for this module\n");
break;
}
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_DT_SetPWM_Period(cardIndex, module, ch_loop, time));
time /= 10.0;
status |= check_status(naibrd_DT_SetPWM_Pulsewidth(cardIndex, module, ch_loop, time));
status |= check_status(naibrd_DT_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 DT_PWM_CMD_PWM_INITIAL:
{
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_DT_SetOutputState(cardIndex, module, ch_loop, NAI_DT_STATE_LO));
status |= check_status(naibrd_DT_SetIOFormat(cardIndex, module, ch_loop, NAI_DT_IOFORMAT_INPUT));
status |= check_status(naibrd_DT_SetPWM_Pulsewidth(cardIndex, module, ch_loop, 0.00361));
status |= check_status(naibrd_DT_SetPWM_BurstNum(cardIndex, module, ch_loop, 1));
status |= check_status(naibrd_DT_SetOpMode( cardIndex, module, ch_loop, NAI_DT_MODE_ENHANCED_INPUT));
status |= check_status(naibrd_DT_SetBasicOpModeEnable( cardIndex, module, ch_loop, NAI_DT_IOMODE_BASIC));
status |= check_status(naibrd_DT_SetDebounceTime(cardIndex, module, ch_loop, 0.0));
status |= check_status(naibrd_DT_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 DT_PWM_CMD_PWM_BURST:
{
if ((ModuleID == NAI_MODULE_ID_KA) || (ModuleID == NAI_MODULE_ID_K6))
{
printf("PWM burst mode not supported for this module\n");
break;
}
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_DT_SetOpMode( cardIndex, module, ch_loop, NAI_DT_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES));
status |= check_status(naibrd_DT_SetBasicOpModeEnable( cardIndex, module, ch_loop, NAI_DT_IOMODE_ENHANCED));
}
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 DT_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_DT_SetOpMode( cardIndex, module, ch_loop, NAI_DT_MODE_OUTPUT_PWM_FOREVER));
status |= check_status(naibrd_DT_SetBasicOpModeEnable( cardIndex, module, ch_loop, NAI_DT_IOMODE_ENHANCED));
}
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>
Display_DT_PWM_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for PWM operation.
</summary>
*/
/**************************************************************************************************************/
static void Display_DT_PWM_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan, uint32_t ModuleID)
{
uint32_t ioformat = 0;
nai_dt_state_t outputstate = 0;
nai_dt_state_t inputstate = 0;
nai_dt_state_t basicmode = 0;
nai_dt_enhanced_mode_t opmode = 0;
uint32_t modprocrev = 0u;
uint32_t modfpgarev = 0u;
uint32_t ModuleVer;
uint32_t ModuleRev;
uint32_t ModInfo_Special;
naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
check_status(naibrd_DT_GetIOFormat(cardIndex, module, chan, &ioformat));
check_status(naibrd_DT_GetOutputState(cardIndex, module, chan, &outputstate));
check_status(naibrd_DT_GetInputState(cardIndex, module, chan, &inputstate));
check_status(naibrd_DT_GetBasicOpModeEnable(cardIndex, module, chan, &basicmode));
check_status(naibrd_DT_GetOpMode(cardIndex, module, chan, &opmode));
printf("\n === Channel %d ===\n\n", chan);
/*read PWM configuration values here, Period, Pulsewidth, Continuous/Burst Mode, */
naibrd_GetModuleRev(cardIndex, module, &modprocrev, &modfpgarev);
if (modfpgarev < NAI_DT_Rev_10_2)
{
{
printf(" I/O Output Input Basic / \n");
printf(" Format State State Enhanced Enhanced Mode Selection\n");
printf("--------- ------ ----------- -------- --------------------------------\n");
}
} else
{
{
printf(" I/O Output Input \n");
printf(" Format State State Enhanced Mode Selection\n");
printf("--------- ------ ----------- --------------------------------\n");
}
}
/*display configuration settings here- */
switch (ioformat)
{
case NAI_DT_IOFORMAT_INPUT:
printf(" Input ");
break;
case NAI_DT_IOFORMAT_OUTPUT_LOW:
printf(" Low Side ");
break;
case NAI_DT_IOFORMAT_OUTPUT_HIGH:
printf(" High Side");
break;
case NAI_DT_IOFORMAT_OUTPUT_PUSHPULL:
printf(" Push/Pull");
break;
default:
printf(" Unknown ");
break;
}
switch (outputstate)
{
case NAI_DT_STATE_LO:
printf(" LOW Set ");
break;
case NAI_DT_STATE_HI:
printf(" HIGH Set ");
break;
default:
printf(" Unknown ");
break;
}
switch (inputstate)
{
case NAI_DT_STATE_LO:
printf(" LOW Input ");
break;
case NAI_DT_STATE_HI:
printf("HIGH Input ");
break;
default:
printf("Unknown ");
break;
}
naibrd_GetModuleRev(cardIndex, module, &modprocrev, &modfpgarev);
if (modfpgarev < NAI_DT_Rev_10_2)
{
switch (basicmode)
{
case NAI_DT_IOMODE_ENHANCED:
printf("Enhanced ");
break;
case NAI_DT_IOMODE_BASIC:
printf("Basic ");
break;
default:
printf("Unknown ");
break;
}
}
switch (opmode)
{
case NAI_DT_MODE_ENHANCED_INPUT:
printf("DT_MODE_ENHANCED_INPUT ");
break;
case NAI_DT_MODE_MEASURE_HIGH_TIME:
printf("DT_MODE_MEASURE_HIGH_TIME ");
break;
case NAI_DT_MODE_MEASURE_LOW_TIME:
printf("DT_MODE_MEASURE_LOW_TIME ");
break;
case NAI_DT_MODE_TIMESTAMP_RISING_EDGES:
printf("DT_MODE_TIMESTAMP_RISING_EDGES ");
break;
case NAI_DT_MODE_TIMESTAMP_FALLING_EDGES:
printf("DT_MODE_TIMESTAMP_FALLING_EDGES ");
break;
case NAI_DT_MODE_TIMESTAMP_ALL_EDGES:
printf("DT_MODE_TIMESTAMP_ALL_EDGES ");
break;
case NAI_DT_MODE_COUNT_RISING_EDGES:
printf("DT_MODE_COUNT_RISING_EDGES ");
break;
case NAI_DT_MODE_COUNT_FALLING_EDGES:
printf("DT_MODE_COUNT_FALLING_EDGES ");
break;
case NAI_DT_MODE_COUNT_ALL_EDGES:
printf("DT_MODE_COUNT_ALL_EDGES ");
break;
case NAI_DT_MODE_MEASURE_PERIOD_FROM_RISING_EDGE:
printf("DT_MODE_MEASURE_PERIOD_FROM_RISING_EDGE ");
break;
case NAI_DT_MODE_MEASURE_FREQUENCY:
printf("DT MODE Interval Counter ");
break;
case NAI_DT_MODE_OUTPUT_PWM_FOREVER:
printf("DT MODE PWM Continuous ");
break;
case NAI_DT_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES:
printf("DT MODE PWM Burst ");
break;
case NAI_DT_MODE_OUTPUT_PATTERN_RAM:
printf("DT MODE PATTERN_RAM ");
break;
case NAI_DT_MODE_BASIC_INPUT:
printf("DT MODE BASIC_INPUT");
break;
case NAI_DT_MODE_BASIC_OUTPUT_LOWSIDE:
printf("DT MODE BASIC_OUTPUT_LOWSIDE");
break;
case NAI_DT_MODE_BASIC_OUTPUT_HIGHSIDE:
printf("DT MODE BASIC_OUTPUT_HIGHSIDE");
break;
case NAI_DT_MODE_BASIC_OUTPUT_PUSHPULL:
printf("DT MODE BASIC_OUTPUT_PUSHPULL");
break;
default:
printf("Unknown ");
break;
}
}
/**************************************************************************************************************/
/**
<summary>
Display_DT_PWM_Configuration illustrate the methods to call in the naibrd library to retrieve the PWM
configuration settings.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Display_DT_PWM_Configuration(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_dt_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_dt_params->cardIndex;
int32_t module = p_dt_params->module;
int32_t chan = p_dt_params->channel;
nai_dt_pwm_polarity_t polaritysetting;
float64_t period;
float64_t pulsewidth;
uint32_t burstnumber;
int32_t masterchannel;
#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 MasterChannel\n");
printf(" -------------- ---------------- ----------- ----------- ---------------\n");
check_status(naibrd_DT_GetPWM_Period(cardIndex, module, chan, &period));
printf(" %10.6f ", period);
check_status(naibrd_DT_GetPWM_Pulsewidth(cardIndex, module, chan, &pulsewidth));
printf(" %10.6f ", pulsewidth);
check_status(naibrd_DT_GetPWM_BurstNum(cardIndex, module, chan, &burstnumber));
printf(" 0x%08X ", burstnumber);
check_status(naibrd_DT_GetPWM_Polarity(cardIndex, module, chan, &polaritysetting));
if (polaritysetting==0)
printf(" POS ");
else
printf(" NEG ");
check_status(naibrd_DT_GetPWMMasterChannel(cardIndex, module, chan, &masterchannel));
printf(" %d ", masterchannel);
printf("\n\n");
return NAI_ERROR_UNKNOWN;
}
/**************************************************************************************************************/
/**
<summary>
Display_DT_Status illustrate the methods to call in the naibrd library to retrieve the status settings.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Display_DT_Status(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_dt_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_dt_params->cardIndex;
int32_t module = p_dt_params->module;
int32_t chan = p_dt_params->channel;
nai_dt_ioformat_t IOformat;
nai_dt_state_t state;
nai_status_bit_t status = 0;
uint32_t ModuleID;
uint32_t ModuleVer;
uint32_t ModuleRev;
uint32_t ModInfo_Special;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
/* Available settings:
IO configuration,
Output setting,
Input state,
BIT status RT/Latched,
Low-High transition RT/Latched,
High-Low transition RT/Latched,
Overcurrent RT/Latched
*/
naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
printf("\n");
printf(" -----------------DT Status ---------------------------- \n");
printf(" BIT \n");
printf(" IOConfig OutputSetting InputState Latched / RT \n");
printf(" --------- --------------- ----------- --------------- \n");
check_status(naibrd_DT_GetIOFormat(cardIndex, module, chan, &IOformat));
switch (ModuleID)
{
case NAI_MODULE_ID_DT1:
case NAI_MODULE_ID_K6:
{
switch (IOformat)
{
case NAI_DT_IOFORMAT_INPUT:
printf(" INPUT ");
break;
case NAI_DT_IOFORMAT_OUTPUT_LOW:
printf(" Low Side");
break;
case NAI_DT_IOFORMAT_OUTPUT_HIGH:
printf("High Side");
break;
case NAI_DT_IOFORMAT_OUTPUT_PUSHPULL:
printf("Push/Pull");
break;
default:
printf(" ERROR ");
break;
}
break;
}
case NAI_MODULE_ID_KA:
switch (IOformat)
{
case NAI_DT_IOFORMAT_INPUT:
printf(" INPUT ");
break;
case NAI_DT_IOFORMAT_OUTPUT_LOW:
printf(" Low Side");
break;
default:
printf(" ERROR ");
break;
}
break;
default:
printf(" UNKNOWN ");
break;
}
printf(" ");
check_status(naibrd_DT_GetOutputState(cardIndex, module, chan, &state));
switch (state)
{
case NAI_DT_STATE_HI:
printf(" HI ");
break;
case NAI_DT_STATE_LO:
printf(" LO ");
break;
default:
printf(" UNK ");
break;
}
printf(" ");
check_status(naibrd_DT_GetInputState(cardIndex, module, chan, &state));
switch (state)
{
case NAI_DT_STATE_HI:
printf(" HI ");
break;
case NAI_DT_STATE_LO:
printf(" LO ");
break;
default:
printf(" UNK ");
break;
}
printf(" ");
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_BIT_LATCHED, &status)); /*BIT latched*/
printf(" %d ", status);
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_BIT_REALTIME, &status)); /*BIT RT*/
printf(" %d ", status);
printf("\n\n\n\n");
printf(" Lo-hi Transition Hi-lo Transition Overcurrent\n");
printf(" Latched / RT Latched / RT Latched / RT\n");
printf(" ---------------- ------------------ ----------------\n");
printf(" ");
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_LO_HI_TRANS_LATCHED, &status));
printf(" %d ", status);
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_LO_HI_TRANS_REALTIME, &status));
printf(" %d ", status);
printf(" ");
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_HI_LO_TRANS_LATCHED, &status));
printf(" %d ", status);
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_HI_LO_TRANS_REALTIME, &status));
printf(" %d ", status);
printf(" ");
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_OVERCURRENT_LATCHED, &status));
printf(" %d ", status);
check_status(naibrd_DT_GetStatus(cardIndex, module, chan, NAI_DT_STATUS_OVERCURRENT_REALTIME, &status));
printf(" %d ", status);
printf("\n\n");
return NAI_ERROR_UNKNOWN;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DT_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>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DT_PWM_Mode(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_dt_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_dt_params->cardIndex;
int32_t module = p_dt_params->module;
int32_t chan = p_dt_params->channel;
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
uint32_t modprocrev = 0u;
uint32_t modfpgarev = 0u;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
naibrd_GetModuleRev(cardIndex, module, &modprocrev, &modfpgarev);
if (modfpgarev < NAI_DT_Rev_10_2)
{
printf("\n == PWM Mode Selection == \n C Continuous PWM mode \n Burst PWM Burst mode \n Input Enhanced Input mode \n None Basic input mode \n\n Type DT command : ");
} else
{
printf("\n == PWM Mode Selection == \n C Continuous PWM mode \n Burst PWM Burst mode \n\n Type DT 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_DT_SetOpMode( cardIndex, module, chan, NAI_DT_MODE_OUTPUT_PWM_FOREVER));
check_status(naibrd_DT_SetBasicOpModeEnable( cardIndex, module, chan, NAI_DT_IOMODE_ENHANCED));
}
else if ((toupper(inputBuffer[0]) == 'B'))
{
check_status(naibrd_DT_SetOpMode( cardIndex, module, chan, NAI_DT_MODE_OUTPUT_PWM_CYCLE_NUM_TIMES));
check_status(naibrd_DT_SetBasicOpModeEnable( cardIndex, module, chan, NAI_DT_IOMODE_ENHANCED));
}
else if ((toupper(inputBuffer[0]) == 'I') && (modfpgarev < NAI_DT_Rev_10_2))
{
check_status(naibrd_DT_SetOpMode( cardIndex, module, chan, NAI_DT_MODE_ENHANCED_INPUT));
}
else if ((toupper(inputBuffer[0]) == 'N') && (modfpgarev < NAI_DT_Rev_10_2))
{
check_status(naibrd_DT_SetOpMode( cardIndex, module, chan, NAI_DT_MODE_BASIC_INPUT));
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DT_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>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DT_PWM_Polarity(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_dt_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_dt_params->cardIndex;
int32_t module = p_dt_params->module;
int32_t chan = p_dt_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 DT PWM positive going pulse output \n Neg DT PWM negative going pulse output \n\n Type DT 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_DT_SetPWM_Polarity( cardIndex, module, chan, (nai_dt_pwm_polarity_t) NAI_DT_PWMPOLARITY_POS ));
else if ((toupper(inputBuffer[0]) == 'N'))
check_status(naibrd_DT_SetPWM_Polarity( cardIndex, module, chan, (nai_dt_pwm_polarity_t) NAI_DT_PWMPOLARITY_NEG ));
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DT_PWM_Master handles the user request to select the PWM master channel within the 6 channel groups.
and calls the method in the naibrd library for the setting.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DT_PWM_Master(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_dt_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_dt_params->cardIndex;
int32_t module = p_dt_params->module;
int32_t chan = p_dt_params->channel;
bool_t bQuit = FALSE;
uint32_t masterchannel;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n == PWM Master Channel Selection == \n Channel applies within its group only \n (Enter 'r' to reset master) \n\n Enter channel to be set as master: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
if ((toupper(inputBuffer[0]) == 'R'))
check_status(naibrd_DT_ResetPWMMasterChannel( cardIndex, module, chan));
else
{
masterchannel = atoi((const char *)inputBuffer);
check_status(naibrd_DT_SetPWMMasterChannel( cardIndex, module, masterchannel));
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DT_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>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DT_PWM_Period(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_dt_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_dt_params->cardIndex;
int32_t module = p_dt_params->module;
int32_t chan = p_dt_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_DT_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAI_MODULE_ID_DT4:
case NAI_MODULE_ID_D4P:
case NAI_MODULE_ID_CM8:
min =(float64_t)(0x1u * lsb);
max =(float64_t)(0xFFFFFFFF * lsb);
case NAI_MODULE_ID_KA:
case NAI_MODULE_ID_K6:
min =(float64_t)(0x2u * lsb);
max =(float64_t)(0xFFFF * 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_DT_SetPWM_Period(cardIndex, module, chan, time));
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/**************************************************************************************************************/
/**
<summary>
Configure_DT_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>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DT_PWM_Pulsewidth(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_dt_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_dt_params->cardIndex;
int32_t module = p_dt_params->module;
int32_t chan = p_dt_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_DT_GetTimebaseLSB(ModuleID);
switch (ModuleID)
{
case NAI_MODULE_ID_DT4:
case NAI_MODULE_ID_D4P:
case NAI_MODULE_ID_CM8:
min = (float64_t)(0x0u * lsb);
max = (float64_t)(0xFFFFFFFE * lsb);
break;
case NAI_MODULE_ID_KA:
case NAI_MODULE_ID_K6:
min =(float64_t)(0x1u * lsb);
max =(float64_t)(0xFFFE * 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_DT_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>
*/
/**************************************************************************************************************/
static nai_status_t Configure_DT_PWM_Burstcount(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_dt_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_dt_params->cardIndex;
int32_t module = p_dt_params->module;
int32_t chan = p_dt_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_DT4:
case NAI_MODULE_ID_D4P:
case NAI_MODULE_ID_CM8:
if (burstcount < 1)
{
burstcount = 1; /*minimum count is one*/
printf("Setting burstcount to minimum of 1.\n");
}
check_status(naibrd_DT_SetPWM_BurstNum(cardIndex, module, chan, burstcount));
break;
default:
printf("Unsupported function for this module.\n");
break;
}
}
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}