PWM BasicOps
Edit this on GitLab
PWM BasicOps Sample Application (SSK 1.x)
Overview
The PWM BasicOps sample application demonstrates how to configure and control PWM (Pulse Width Modulation) motor drive channels using the NAI Software Support Kit (SSK 1.x). PWM modules generate variable-width electrical pulses to control motor current, motor voltage, and drive behavior. This sample covers the full range of PWM drive operations: commanding current and voltage output, enabling and resetting drives, reading DAC and ADC channels, monitoring real-time measurements and status, configuring module-level drive mode and command source, tuning per-channel control loop gains and current limits, setting up communication and safety watchdogs, managing battlefield and thermal override protections, and configuring serial interface parameters.
This sample supports the PW1 and PW2 module types (identified in the SSK as NAI_MODULE_ID_PW1 and NAI_MODULE_ID_PW2). The two module variants have different measurement capabilities — PW1 provides single-phase current and voltage measurements with temperature monitoring, while PW2 provides three-phase current and voltage measurements with power supply current and voltage readback. The sample detects the installed module type at runtime and adapts its display accordingly.
It serves as a practical API reference — each menu command maps directly to one or more naibrd_PWM_*() API calls that you can lift into your own code.
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with a PWM module installed (PW1 or PW2).
-
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 PWM_BasicOps executable from your build output directory. On startup the application looks for a configuration file (default_PWM_BasicOps.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, a main command menu lets you exercise each PWM operation through organized submenus.
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 PWM. 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_PWM_BasicOps.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 PWM variant installed.
#ifdef __VXWORKS__
int32_t PWM_BasicOps_Sample(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
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))
{
PWM_BasicOps_run(cardIndex, module, moduleID);
}
}
}
printf("\nType Q to quit or Enter key to restart application:\n");
stop = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
}
}
printf("\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Entry Point
On standard platforms the entry point is main(). On VxWorks the entry point is PWM_BasicOps_Sample() — the SSK 1.x build system selects the correct variant via a preprocessor guard:
#ifdef __VXWORKS__
int32_t PWM_BasicOps_Sample(void)
#else
int32_t main(void)
#endif
The startup flow is the same in both cases:
-
Attempt to load the saved configuration file via
naiapp_RunBoardMenu(CONFIG_FILE). If the file does not yet exist, the interactive board menu is presented instead. -
Enter a loop that queries for card index and module slot.
-
Call
PWM_BasicOps_run()to enter the interactive command loop for the selected module. -
On exit, close all open board connections with
naiapp_access_CloseAllOpenCards().
Application Parameters
The PWM_BasicOps_run() function populates an naiapp_AppParameters_t struct that is passed to every command handler. Your application will need to track these same values to identify which board, module, and channel you are targeting:
pwm_basicOps_params->cardIndex = cardIndex;
pwm_basicOps_params->module = module;
pwm_basicOps_params->channel = DEFAULT_CHANNEL;
pwm_basicOps_params->maxChannels = naibrd_PWM_GetChannelCount(modId);
pwm_basicOps_params->modId = modId;
pwm_basicOps_params->displayHex = FALSE;
-
cardIndex— identifies which board in a multi-board system. -
module— the slot number where the PWM module is installed. -
channel— the currently selected channel (defaults to 1). -
maxChannels— total channel count for the detected module, retrieved by callingnaibrd_PWM_GetChannelCount()with the module ID. -
modId— the module identifier returned bynaibrd_GetModuleID(). API functions use this to apply module-specific behavior (for example, PW1 vs. PW2 measurement differences). -
displayHex— toggles between hexadecimal and decimal display of register values.
Command Loop and Menu System
PWM_BasicOps_run() drives the interactive command loop. On each iteration it displays the main menu and dispatches the user’s selection to the matching handler function. The main menu provides access to ten functional submenus:
| Command | Description |
|---|---|
PCtl |
PWM channel control — set current/voltage commands, enable/reset drives |
DCtl |
DAC control — view DAC output values |
ACtl |
ADC control — view ADC inputs, configure source and enable state |
Meas |
PWM measurements — read real-time current, voltage, and temperature |
Stat |
Status — view module status and board ready state |
MCfg |
Module configuration — set drive mode and command source |
CCfg |
Channel configuration — set current limit, input scale, and control loop gains |
WD |
Watchdog — configure VME/PCIe/Ethernet watchdog timeout and enable |
GCtl |
General control — battlefield override, thermal override, soft reset |
SCtl |
Serial control — serial interface configuration, watchdog, test bits, CRC/frame counters |
The menu-driven structure is a convenience of the sample application. In your own application, you would call the same underlying naibrd_PWM_*() API functions directly — for example, calling naibrd_PWM_SetCurrent() instead of navigating to the "PCtl" menu command and selecting "C".
Each submenu handler follows a read-modify-verify pattern: it displays the current state of the relevant registers, presents a submenu of configurable parameters, accepts the user’s input, writes the new value via the API, and then redisplays the updated state. This loop continues until the user types 'Q' to return to the main menu.
PWM Channel Control
This section covers the core drive operations: commanding output current and voltage, enabling the drive, and resetting it. These are the fundamental operations for controlling a PWM motor drive — you set the desired output level, enable the drive to begin switching, and reset it if a fault occurs.
Set Current Command
To command a specific output current on a PWM channel in your own application, call naibrd_PWM_SetCurrent(). The API expects the current value in milliamps, so if your application works in amps you must multiply by 1000 before calling the API.
float32_t current; /* Current in amps from user input */
/* Note: the current API uses units of milliamps */
naibrd_PWM_SetCurrent(cardIndex, module, channel, current * 1000.0f);
-
cardIndex— identifies the board. -
module— the slot containing the PWM module. -
channel— the drive channel to command. -
current * 1000.0f— the desired output current in milliamps. The sample prompts for amps and converts internally.
To read the current command value back, call naibrd_PWM_GetCurrent(). The returned value is also in milliamps. To read the raw register value, use naibrd_PWM_GetChannelRaw() with NAI_PWM_CHAN_RAW_CURRENT_CMD.
Set Voltage Command
To command a specific output voltage on a PWM channel, call naibrd_PWM_SetVoltage(). The voltage is specified directly in volts.
float32_t voltage; /* Voltage in volts from user input */
naibrd_PWM_SetVoltage(cardIndex, module, channel, voltage);
-
voltage— the desired output voltage in volts.
To read the voltage command back, call naibrd_PWM_GetVoltage(). To read the raw register value, use naibrd_PWM_GetChannelRaw() with NAI_PWM_CHAN_RAW_VOLTAGE_CMD.
|
Note
|
Whether the module responds to the current command or the voltage command depends on the drive mode setting. See Set Drive Mode for details on switching between current-drive and voltage-drive modes. |
Enable Drive
To enable or disable the PWM drive output on a channel, call naibrd_PWM_SetDriveEnable(). When the drive is enabled, the module begins PWM switching on the output. When disabled, the output is inactive.
/* Enable the drive on the specified channel */
naibrd_PWM_SetDriveEnable(cardIndex, module, channel, TRUE);
/* Disable the drive */
naibrd_PWM_SetDriveEnable(cardIndex, module, channel, FALSE);
-
TRUE— enables PWM output on the channel. -
FALSE— disables PWM output on the channel.
To query the current enable state, call naibrd_PWM_GetDriveEnable().
Reset Drive
To reset a PWM drive channel (for example, after a fault condition), call naibrd_PWM_ResetDrive(). This clears any latched fault state and returns the channel to its initial condition.
naibrd_PWM_ResetDrive(cardIndex, module, channel);
After a reset, you will need to reconfigure the channel and re-enable the drive before output resumes.
|
Important
|
Common Errors
|
DAC Control
The DAC control submenu displays the output values of the module’s digital-to-analog converter channels. This is a read-only view — the DAC outputs are set internally by the module’s control loop based on your current and voltage commands.
To read a DAC output value in your own application, call naibrd_PWM_GetDACOutput():
float32_t dacOutput = 0;
uint32_t hexValue = 0;
naibrd_PWM_GetDACOutput(cardIndex, module, dac, &dacOutput);
naibrd_PWM_GetDAChannelRaw(cardIndex, module, dac, NAI_PWM_CHAN_RAW_DA_OUTPUT, &hexValue);
-
dac— the DAC channel number (1-based). -
dacOutput— receives the floating-point output value. -
hexValue— receives the raw register value for diagnostic purposes.
The sample iterates over all DAC channels (up to MAX_PWM_DAC_CHANNELS) and prints each output alongside its raw hex value. In your own application, you can use these readbacks to verify that the control loop is producing the expected drive signals.
|
Important
|
Common Errors
|
ADC Control
The ADC control submenu displays the analog-to-digital converter input channels and allows you to configure the ADC source and enable state. The ADC channels provide feedback measurements that the control loop uses internally, and that your application can read for monitoring purposes.
Read ADC Input
To read an ADC channel’s voltage in your own application, call naibrd_PWM_GetADCInput():
float32_t voltage = 0;
naibrd_PWM_GetADCInput(cardIndex, module, adc, &voltage);
-
adc— the ADC channel number (1-based). -
voltage— receives the measured voltage.
Set ADC Source (PW2 Only)
To select the input source for an ADC channel, call naibrd_PWM_SetADCSource(). This function is available on the PW2 module. The source determines where the ADC receives its input data:
/* Route ADC input from the serial interface */
naibrd_PWM_SetADCSource(cardIndex, module, channel, NAI_PWM_ADC_SOURCE_SERIAL);
/* Route ADC input from Ethernet */
naibrd_PWM_SetADCSource(cardIndex, module, channel, NAI_PWM_ADC_SOURCE_ETHERNET);
/* Route ADC input from PWM channel 1 */
naibrd_PWM_SetADCSource(cardIndex, module, channel, NAI_PWM_ADC_SOURCE_PWM_CH1);
/* Route ADC input from PWM channel 2 */
naibrd_PWM_SetADCSource(cardIndex, module, channel, NAI_PWM_ADC_SOURCE_PWM_CH2);
-
NAI_PWM_ADC_SOURCE_SERIAL— ADC input comes from the serial interface. -
NAI_PWM_ADC_SOURCE_ETHERNET— ADC input comes from the Ethernet interface. -
NAI_PWM_ADC_SOURCE_PWM_CH1— ADC input is routed from PWM channel 1. -
NAI_PWM_ADC_SOURCE_PWM_CH2— ADC input is routed from PWM channel 2.
To query the current source setting, call naibrd_PWM_GetADCSource().
Enable/Disable ADC (PW2 Only)
To enable or disable an ADC channel, call naibrd_PWM_SetADCEnable():
/* Enable ADC input on the specified channel */
naibrd_PWM_SetADCEnable(cardIndex, module, channel, TRUE);
To query the current enable state, call naibrd_PWM_GetADCEnable().
|
Note
|
On the PW1 module, the ADC submenu displays read-only measurement data. The source selection and enable/disable commands are available only on the PW2 module. |
|
Important
|
Common Errors
|
PWM Measurements
The measurements submenu displays real-time current, voltage, temperature, and power supply readings from the module. The measurement set differs significantly between PW1 and PW2 modules.
PW1 Measurements
On PW1 modules, the sample reads single-phase measurements per channel plus power supply data:
float32_t current_mA = 0.0f;
float32_t voltage = 0.0f;
int32_t temperature = 0;
/* Per-channel measurements */
naibrd_PWM_GetMeasuredCurrent(cardIndex, module, channel, ¤t_mA);
naibrd_PWM_GetMeasuredVoltage(cardIndex, module, channel, &voltage);
naibrd_PWM_GetMeasuredTemperature(cardIndex, module, channel, &temperature);
/* Power supply measurements (module-level) */
naibrd_PWM_GetMeasuredPSVoltage(cardIndex, module, &voltage);
naibrd_PWM_GetMeasuredPSTemperature(cardIndex, module, &temperature);
-
current_mA— measured output current in milliamps. Divide by 1000 to convert to amps. -
voltage— measured output voltage in volts. -
temperature— measured temperature in degrees Celsius. -
Power supply voltage and temperature are module-level readings (not per-channel).
PW2 Measurements
On PW2 modules, the sample reads three-phase current and voltage measurements per channel, plus per-channel power supply current and voltage:
float32_t current1_mA, current2_mA, current3_mA;
float32_t voltage1, voltage2, voltage3;
/* Three-phase current (per channel, per phase 1-3) */
naibrd_PWM_GetDriveMeasureCurrent(cardIndex, module, channel, 1, ¤t1_mA);
naibrd_PWM_GetDriveMeasureCurrent(cardIndex, module, channel, 2, ¤t2_mA);
naibrd_PWM_GetDriveMeasureCurrent(cardIndex, module, channel, 3, ¤t3_mA);
/* Three-phase voltage (per channel, per phase 1-3) */
naibrd_PWM_GetDriveMeasureVoltage(cardIndex, module, channel, 1, &voltage1);
naibrd_PWM_GetDriveMeasureVoltage(cardIndex, module, channel, 2, &voltage2);
naibrd_PWM_GetDriveMeasureVoltage(cardIndex, module, channel, 3, &voltage3);
/* Per-channel power supply measurements */
naibrd_PWM_GetPSCurrentMeasure(cardIndex, module, channel, ¤t1_mA);
naibrd_PWM_GetPSVoltageMeasure(cardIndex, module, channel, &voltage1);
The third parameter to the phase-specific functions (1, 2, or 3) selects the phase. This is useful for three-phase motor drive applications where you need to monitor each winding independently.
|
Note
|
If you call PW1-specific measurement functions on a PW2 module (or vice versa), the sample prints "Feature is not supported by this module." Your application should check modId to determine which measurement API calls to use.
|
|
Important
|
Common Errors
|
Status
The status submenu displays the module’s status register and board ready state. To check module status and board readiness in your own application:
uint32_t hexValue = 0;
/* Read the status register */
naibrd_PWM_GetStatus(cardIndex, module, &hexValue);
/* Check board ready state */
if (naibrd_PWM_IsBoardReady(cardIndex, module) == NAI_SUCCESS)
{
/* Board is ready for operation */
}
/* Read the raw board ready register */
naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_BOARD_READY, &hexValue);
-
naibrd_PWM_GetStatus()— retrieves the module status register as a raw hex value. Consult your module’s manual for the bit definitions. -
naibrd_PWM_IsBoardReady()— returnsNAI_SUCCESSwhen the module has completed initialization and is ready to accept commands. Returns an error status if the module is not yet ready. -
naibrd_PWM_GetRaw()withNAI_PWM_RAW_BOARD_READY— reads the raw board ready register value for diagnostic purposes.
Always verify that the board is ready before issuing drive commands. If the board is not ready, commands may be ignored or produce unexpected results.
|
Important
|
Common Errors
|
Module Configuration
The module configuration submenu controls two module-level settings: the drive mode (current vs. voltage) and the command source (serial vs. other). These settings affect all channels on the module.
Set Drive Mode
To select whether the module operates in current-drive mode or voltage-drive mode, call naibrd_PWM_SetDriveMode():
/* Set module to current-drive mode */
naibrd_PWM_SetDriveMode(cardIndex, module, NAI_PWM_CURRENT_DRIVE);
/* Set module to voltage-drive mode */
naibrd_PWM_SetDriveMode(cardIndex, module, NAI_PWM_VOLTAGE_DRIVE);
-
NAI_PWM_CURRENT_DRIVE— the module regulates output current. Usenaibrd_PWM_SetCurrent()to command the output. -
NAI_PWM_VOLTAGE_DRIVE— the module regulates output voltage. Usenaibrd_PWM_SetVoltage()to command the output.
The drive mode determines which command register the module’s control loop uses as its setpoint. In current-drive mode, the current command register is active and the voltage command is ignored. In voltage-drive mode, the opposite is true. Make sure you set the drive mode before issuing current or voltage commands.
To read the current drive mode, call naibrd_PWM_GetDriveMode().
Set Command Source
To select where the module receives its current/voltage commands, call naibrd_PWM_SetSource():
/* Commands come from the serial interface */
naibrd_PWM_SetSource(cardIndex, module, NAI_PWM_SOURCE_SERIAL);
/* Commands come from VME, PCIe, or Ethernet */
naibrd_PWM_SetSource(cardIndex, module, NAI_PWM_SOURCE_OTHER);
-
NAI_PWM_SOURCE_SERIAL— the module accepts current/voltage commands from its dedicated serial interface. -
NAI_PWM_SOURCE_OTHER— the module accepts commands from the host bus (VME, PCIe, or Ethernet). This is the typical setting when controlling the module from your application via the SSK API.
To read the current source setting, call naibrd_PWM_GetSource().
|
Important
|
Common Errors
|
Channel Configuration
The channel configuration submenu controls per-channel parameters that tune the drive’s behavior: current limit, input scale, and the three control loop gains (global, integral, and proportional).
Set Current Limit
To set the maximum allowable output current on a channel, call naibrd_PWM_SetCurrentLimit(). The API expects the value in milliamps:
float32_t currentLimit; /* Limit in amps from user input */
/* Note: the current API uses units of milliamps */
naibrd_PWM_SetCurrentLimit(cardIndex, module, channel, currentLimit * 1000.0f);
The current limit acts as a safety clamp — if the control loop attempts to drive current beyond this limit, the module caps the output at the limit value. Set this to protect your load and wiring from excessive current.
To read the current limit back, call naibrd_PWM_GetCurrentLimit(). The returned value is in milliamps.
Set Input Scale (Kc)
To set the input scale factor for a channel, call naibrd_PWM_SetInputScale():
int32_t cfgValue;
naibrd_PWM_SetInputScale(cardIndex, module, channel, cfgValue);
The input scale factor (Kc) scales the command input before it enters the control loop. Consult your module’s manual for the valid range and effect of this parameter on drive behavior.
To read the current input scale, call naibrd_PWM_GetInputScale().
Set Global Gain (Kg)
To set the global gain for a channel’s control loop, call naibrd_PWM_SetGlobalGain():
int32_t cfgValue;
naibrd_PWM_SetGlobalGain(cardIndex, module, channel, cfgValue);
The global gain (Kg) is an overall scaling factor applied to the control loop output. It multiplies the combined output of the proportional and integral terms. Increasing Kg increases the overall loop responsiveness; decreasing it reduces output amplitude.
To read the current global gain, call naibrd_PWM_GetGlobalGain().
Set Integral Gain (Ki)
To set the integral gain for a channel’s control loop, call naibrd_PWM_SetIntegralGain():
int32_t cfgValue;
naibrd_PWM_SetIntegralGain(cardIndex, module, channel, cfgValue);
The integral gain (Ki) controls the integrator in the control loop. The integrator accumulates the error between the commanded and measured output over time, driving steady-state error toward zero. Higher Ki values reduce steady-state error faster but can cause overshoot and oscillation if set too aggressively.
To read the current integral gain, call naibrd_PWM_GetIntegralGain().
Set Proportional Gain (Kp)
To set the proportional gain for a channel’s control loop, call naibrd_PWM_SetProportionalGain():
int32_t cfgValue;
naibrd_PWM_SetProportionalGain(cardIndex, module, channel, cfgValue);
The proportional gain (Kp) controls the immediate response to the error between the commanded and measured output. Higher Kp values produce faster response but can cause ringing and instability. Lower values produce smoother but slower response.
To read the current proportional gain, call naibrd_PWM_GetProportionalGain().
|
Note
|
Tuning Kg, Ki, and Kp correctly is essential for stable drive operation. Start with conservative values (low gains) and increase gradually while monitoring the measurements submenu for oscillation. Consult your module’s manual for recommended starting values and tuning procedures. |
|
Important
|
Common Errors
|
Watchdog Configuration
The watchdog submenu configures the VME/PCIe/Ethernet communication watchdog timer. The watchdog monitors communication between your host application and the PWM module. If the watchdog expires (no communication within the timeout period), the module can take protective action such as disabling drive outputs.
Set Watchdog Timeout
To set the watchdog timeout in your own application, call naibrd_PWM_SetWatchdogTimeout():
float32_t cfgValue; /* Timeout in milliseconds */
naibrd_PWM_SetWatchdogTimeout(cardIndex, module, cfgValue);
-
cfgValue— the watchdog timeout in milliseconds. If no communication is received within this period, the watchdog triggers.
To read the current timeout, call naibrd_PWM_GetWatchdogTimeout(). To read the raw register value, use naibrd_PWM_GetRaw() with NAI_PWM_RAW_WATCHDOG_TIMEOUT.
Enable/Disable Watchdog
To enable or disable the watchdog timer, call naibrd_PWM_SetWatchdogEnable():
/* Enable the watchdog */
naibrd_PWM_SetWatchdogEnable(cardIndex, module, TRUE);
/* Disable the watchdog */
naibrd_PWM_SetWatchdogEnable(cardIndex, module, FALSE);
When the watchdog is enabled, your application must periodically communicate with the module to prevent the watchdog from expiring. Any API call to the module resets the watchdog timer. During development and bench testing, you may want to leave the watchdog disabled to avoid unexpected drive shutdowns.
To read the current enable state, call naibrd_PWM_GetWatchdogEnable().
|
Important
|
Common Errors
|
General Controls
The general controls submenu provides access to safety overrides and soft reset functionality.
Battlefield Override Enable
To enable or disable the battlefield override in your own application, call naibrd_PWM_SetBattlefieldOverrideEnable():
/* Enable battlefield override */
naibrd_PWM_SetBattlefieldOverrideEnable(cardIndex, module, TRUE);
/* Disable battlefield override */
naibrd_PWM_SetBattlefieldOverrideEnable(cardIndex, module, FALSE);
When battlefield override is enabled, the module continues to operate even when certain fault conditions are present that would normally shut down the drive. This is intended for mission-critical applications where continued operation under degraded conditions is preferable to a complete shutdown.
To read the current state, call naibrd_PWM_GetBattlefieldOverrideEnable().
Power Supply Over-Temperature Override Enable
To enable or disable the power supply over-temperature override, call naibrd_PWM_SetPSOverTempOverrideEnable():
/* Enable PS over-temperature override */
naibrd_PWM_SetPSOverTempOverrideEnable(cardIndex, module, TRUE);
/* Disable PS over-temperature override */
naibrd_PWM_SetPSOverTempOverrideEnable(cardIndex, module, FALSE);
When this override is enabled, the module continues to operate even if a power supply over-temperature condition is detected. Under normal circumstances, an over-temperature event shuts down the drive to protect the hardware. Enable this override only when continued operation is critical and the thermal risk is understood.
To read the current state, call naibrd_PWM_GetPSOverTempOverrideEnable().
Soft Reset
To perform a software reset of the PWM module, call naibrd_PWM_SoftReset():
naibrd_PWM_SoftReset(cardIndex, module);
A soft reset returns the module to its power-on state. All configuration settings (drive mode, gains, current limits, watchdog, etc.) are reset to their default values, and all drives are disabled. After a reset, you must reconfigure the module and re-enable drives before operation can resume.
The sample prompts for confirmation (Y/N) before executing the reset to prevent accidental resets.
|
Important
|
Common Errors
|
Serial Control
The serial control submenu configures the module’s dedicated serial communication interface. This interface provides a secondary command path for current/voltage commands and ADC data, independent of the VME/PCIe/Ethernet host bus.
Set Rx Clock Edge
To select which clock edge the serial receiver samples data on, call naibrd_PWM_SetSerialRxClockEdge():
/* Sample on the rising edge */
naibrd_PWM_SetSerialRxClockEdge(cardIndex, module, NAI_PWM_CLOCK_EDGE_RISING);
/* Sample on the falling edge */
naibrd_PWM_SetSerialRxClockEdge(cardIndex, module, NAI_PWM_CLOCK_EDGE_FALLING);
The clock edge setting must match the transmitting device’s configuration. If the edges are mismatched, the serial interface will receive corrupted data.
To read the current setting, call naibrd_PWM_GetSerialRxClockEdge().
Set Serial Watchdog Timeout
To set the serial interface watchdog timeout, call naibrd_PWM_SetSerialWatchdogTimeout():
float32_t cfgValue; /* Timeout in milliseconds */
naibrd_PWM_SetSerialWatchdogTimeout(cardIndex, module, cfgValue);
This watchdog is separate from the VME/PCIe/Ethernet watchdog configured in the Watchdog submenu. It monitors the serial interface specifically.
To read the current timeout, call naibrd_PWM_GetSerialWatchdogTimeout().
Enable/Disable Serial Watchdog
To enable or disable the serial watchdog, call naibrd_PWM_SetSerialWatchdogEnable():
naibrd_PWM_SetSerialWatchdogEnable(cardIndex, module, TRUE);
To read the current enable state, call naibrd_PWM_GetSerialWatchdogEnable().
Set Serial Test Bits
To write a test pattern to the serial interface, call naibrd_PWM_SetSerialTestBits():
uint32_t hexValue; /* Test pattern in hex */
naibrd_PWM_SetSerialTestBits(cardIndex, module, hexValue);
Serial test bits allow you to inject known data patterns for loopback testing and communication verification. To read the current test bits value, call naibrd_PWM_GetSerialTestBits().
Enable/Disable Serial Transmit
To enable or disable the serial transmitter, call naibrd_PWM_SetSerialTransmitEnable():
naibrd_PWM_SetSerialTransmitEnable(cardIndex, module, TRUE);
The transmitter must be enabled for the module to send data over the serial interface. To read the current state, call naibrd_PWM_GetSerialTransmitEnable().
CRC Error Count and Data Frame Count
The serial interface tracks CRC errors and data frame counts for diagnostic purposes:
int32_t count;
/* Read CRC error count */
naibrd_PWM_GetCRCErrorCount(cardIndex, module, &count);
/* Read data frame count */
naibrd_PWM_GetDataFrameCount(cardIndex, module, &count);
/* Read data frame status register */
uint32_t hexValue;
naibrd_PWM_GetDataFrameStatus(cardIndex, module, &hexValue);
You can disable these counters individually:
/* Disable CRC error counting */
naibrd_PWM_SetCRCErrorCountDisable(cardIndex, module, TRUE);
/* Disable data frame counting */
naibrd_PWM_SetDataFrameCountDisable(cardIndex, module, TRUE);
Note the inverted logic: passing TRUE disables the counter, and passing FALSE enables it. The sample displays counters as "Enabled" when the disable flag is FALSE, and "Disabled" when the disable flag is TRUE.
To query the current disable state, call naibrd_PWM_GetCRCErrorCountDisable() and naibrd_PWM_GetDataFrameCountDisable().
|
Important
|
Common Errors
|
Troubleshooting Reference
|
Note
|
This section summarizes errors covered in the preceding sections and serves as a quick-reference. Consult your module’s manual for hardware-specific diagnostics and detailed status register bit maps. |
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
No board found |
Board not powered on; incorrect interface or address in configuration file. |
Verify power, check configuration file settings, confirm physical connection. |
Connection timeout |
Network misconfiguration; firewall blocking traffic; incorrect bus configuration. |
Check IP settings, verify firewall rules, confirm PCI/PCIe bus configuration. |
Invalid card or module index |
Incorrect zero-based card index or one-based module index. |
Verify indices match your hardware setup. |
Module not present at selected slot |
The selected slot does not contain a PWM module. |
Use board menu to verify slot population. |
Board shows "NOT READY" |
Module still initializing; power supply issue. |
Wait and re-poll; check power supply connections. |
Drive does not respond to commands |
Drive not enabled; drive mode does not match command type; command source set to Serial while commanding over Ethernet/PCIe. |
Enable drive; match drive mode to command type; set source to |
Unexpected current units |
API uses milliamps; passing amps without conversion. |
Multiply amps by 1000 before calling |
Drive oscillates or overshoots |
Control loop gains (Kg, Ki, Kp) set too high. |
Reduce gains and increase gradually while monitoring measurements. |
Drive responds slowly |
Control loop gains too low; integral gain Ki is zero. |
Increase gains; ensure Ki is non-zero. |
Feature not supported by this module |
Calling PW1-specific functions on PW2 or vice versa. |
Check |
Drive unexpectedly disables |
Communication watchdog expired. |
Increase timeout, communicate more frequently, or disable watchdog during development. |
CRC error count increasing |
Serial clock edge mismatch; signal integrity issue. |
Verify Rx clock edge setting; check serial cabling. |
Configuration lost |
Soft reset was performed. |
Re-apply all configuration after calling |
Full Source
Full Source — PWM_BasicOps.c (SSK 1.x)
#include <stdint.h>
#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_pwm.h"
#include "advanced/nai_ether_adv.h"
#include "boards/naibrd_gen5.h"
//#include "nai_sys_cfg.h"
//#include "nai_utils.h"
static const int8_t *SAMPLE_PGM_NAME = (const int8_t *)"PWM_BasicOps";
static const int8_t *CONFIG_FILE = (const int8_t *)"default_PWM_BasicOps.txt";
/* Global buffer and count for user input */
int8_t g_op[80];
int32_t g_responseCnt;
#define DEFAULT_CHANNEL 1
typedef enum nai_pwm_devices
{
DEVICE_NONE,
DEVICE_64PW2,
DEVICE_68PW1
}nai_pwm_devices_t;
/* Global variable for pwm device selected */
static nai_pwm_devices_t g_selectedDevice;
/*******************************/
/* Private Function Prototypes */
/*******************************/
static bool_t PWM_BasicOps_run(int32_t cardIndex, int32_t module, uint32_t modId);
/* PWM Channel Control Function Prototypes */
static nai_status_t handlePWMChannelControls(int32_t paramCount, int32_t* p_params);
static nai_status_t getPWMChannelControls(int32_t paramCount, int32_t* p_params);
static bool_t setPWMChannelControls(int32_t paramCount, int32_t* p_params);
static nai_status_t setCurrentCommand(int32_t paramCount, int32_t* p_params);
static nai_status_t setVoltageCommand(int32_t paramCount, int32_t* p_params);
static nai_status_t setDriveEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t resetDrive(int32_t paramCount, int32_t* p_params);
/* DAC Control Function Prototypes */
static nai_status_t handleDACControls(int32_t paramCount, int32_t* p_params);
static nai_status_t getDACControls(int32_t paramCount, int32_t* p_params);
/* ADC Control Function Prototypes */
static nai_status_t handleADCControls(int32_t paramCount, int32_t* p_params);
static nai_status_t getADCControls(int32_t paramCount, int32_t* p_params);
static bool_t setADCControls(int32_t paramCount, int32_t* p_params);
static nai_status_t setADCEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t setADCSource(int32_t paramCount, int32_t* p_params);
/* PWM Measurements Function Prototypes */
static nai_status_t handlePWMMeasurements(int32_t paramCount, int32_t* p_params);
static nai_status_t getPWMMeasurements(int32_t paramCount, int32_t* p_params);
/* PWM Status Function Prototypes */
static nai_status_t handlePWMStatus(int32_t paramCount, int32_t* p_params);
static nai_status_t getPWMStatus(int32_t paramCount, int32_t* p_params);
/* PWM Module Configuration Function Prototypes */
static nai_status_t handlePWMModuleCfg(int32_t paramCount, int32_t* p_params);
static nai_status_t getPWMModuleCfg(int32_t paramCount, int32_t* p_params);
static bool_t setPWMModuleCfg(int32_t paramCount, int32_t* p_params);
static nai_status_t setDriveMode(int32_t paramCount, int32_t* p_params);
static nai_status_t setSourceSelect(int32_t paramCount, int32_t* p_params);
/* Channel Configuration Function Prototypes */
static nai_status_t handlePWMChannelCfg(int32_t paramCount, int32_t* p_params);
static nai_status_t getPWMChannelCfg(int32_t paramCount, int32_t* p_params);
static bool_t setPWMChannelCfg(int32_t paramCount, int32_t* p_params);
static nai_status_t setCurrentLimit(int32_t paramCount, int32_t* p_params);
static nai_status_t setInputScale(int32_t paramCount, int32_t* p_params);
static nai_status_t setGlobalGain(int32_t paramCount, int32_t* p_params);
static nai_status_t setIntegralGain(int32_t paramCount, int32_t* p_params);
static nai_status_t setProportionalGain(int32_t paramCount, int32_t* p_params);
/* PWM VME/PCIe/Ethernet Watchdog Function Prototypes */
static nai_status_t handlePWMWatchdogCfg(int32_t paramCount, int32_t* p_params);
static nai_status_t getPWMWatchdogCfg(int32_t paramCount, int32_t* p_params);
static bool_t setPWMWatchdogCfg(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMWatchdogTimeout(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMWatchdogEnable(int32_t paramCount, int32_t* p_params);
/* PWM General Control Function Prototypes */
static nai_status_t handlePWMGeneralControls(int32_t paramCount, int32_t* p_params);
static nai_status_t getPWMGeneralControls(int32_t paramCount, int32_t* p_params);
static bool_t setPWMGeneralControls(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMSoftReset(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMBattlefieldOverrideEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMPSOvertempOverrideEnable(int32_t paramCount, int32_t* p_params);
/* Serial Control Function Prototypes */
static nai_status_t handlePWMSerialControls(int32_t paramCount, int32_t* p_params);
static nai_status_t getPWMSerialControls(int32_t paramCount, int32_t* p_params);
static bool_t setPWMSerialControls(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMSerialRxClockEdge(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMSerialWatchdogTimeout(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMSerialWatchdogEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMSerialTestBits(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMSerialTransmitEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMCRCErrorCountDisable(int32_t paramCount, int32_t* p_params);
static nai_status_t setPWMDataFrameCountDisable(int32_t paramCount, int32_t* p_params);
/* Private Query Prototypes */
static int32_t queryPWMChannel(int8_t* p_queryText, int32_t maxChannel, int32_t defaultValue);
static bool_t queryFloat32Value(int8_t* p_queryText, float32_t* p_outFloat32);
static bool_t queryInt32Value(int8_t* p_queryText, int32_t* p_outInt32);
static bool_t queryYesNoValue(int8_t* p_queryText, bool_t* p_outresponseYes);
static bool_t queryHex32Value(int8_t* p_queryText, uint32_t* p_outHex32);
/*****************************/
/****** Command Tables *******/
/*****************************/
enum pwm_main_commands
{
PWM_CMD_PWM_CONTROL,
PWM_CMD_DAC_CONTROL,
PWM_CMD_ADC_CONTROL,
PWM_CMD_MEASUREMENT,
PWM_CMD_STATUS,
PWM_CMD_MODULE_CFG,
PWM_CMD_CHANNEL_CFG,
PWM_CMD_WATCHDOG,
PWM_CMD_GENERAL_CONTROL,
PWM_CMD_SERIAL,
PWM_CMD_MAIN_COUNT
};
/* Main Menu */
naiapp_cmdtbl_params_t PWM_MenuCmds[] = {
{"PCtl", " PWM Control", PWM_CMD_PWM_CONTROL, handlePWMChannelControls},
{"DCtl", " DAC Control", PWM_CMD_DAC_CONTROL, handleDACControls},
{"ACtl", " ADC Control", PWM_CMD_ADC_CONTROL, handleADCControls},
{"Meas", " PWM Measurements", PWM_CMD_MEASUREMENT, handlePWMMeasurements},
{"Stat", " Status", PWM_CMD_STATUS, handlePWMStatus},
{"MCfg", " Module Cfg", PWM_CMD_MODULE_CFG, handlePWMModuleCfg},
{"CCfg", " Channel Cfg", PWM_CMD_CHANNEL_CFG, handlePWMChannelCfg},
{"WD", " Watchdog", PWM_CMD_WATCHDOG, handlePWMWatchdogCfg},
{"GCtl", " General Control", PWM_CMD_GENERAL_CONTROL, handlePWMGeneralControls},
{"SCtl", " Serial Control", PWM_CMD_SERIAL, handlePWMSerialControls},
};
/* PWM Channel Control Menus */
enum pwm_channel_control_commands
{
PWM_CMD_CHAN_CURRENT,
PWM_CMD_CHAN_VOLTAGE,
PWM_CMD_CHAN_DRIVE_ENABLE,
PWM_CMD_CHAN_DRIVE_RESET,
PWM_CMD_CHAN_CONTROL_COUNT
};
naiapp_cmdtbl_params_t PWM_ChannelControlMenuCmds[] = {
{"C", " Current Command", PWM_CMD_CHAN_CURRENT, setCurrentCommand},
{"V", " Voltage Command", PWM_CMD_CHAN_VOLTAGE, setVoltageCommand},
{"D", " Drive Enable", PWM_CMD_CHAN_DRIVE_ENABLE, setDriveEnable},
{"R", " Reset Drive", PWM_CMD_CHAN_DRIVE_RESET, resetDrive},
};
/* PWM ADC Control Menus */
enum pwm_adc_control_commands
{
PWM_CMD_ADC_SOURCE,
PWM_CMD_ADC_ENABLE,
PWM_CMD_ADC_CONTROL_COUNT
};
naiapp_cmdtbl_params_t PWM_ADCControlMenuCmds[] = {
{"S", " ADC Source", PWM_CMD_ADC_SOURCE, setADCSource},
{"E", " ADC Enable", PWM_CMD_ADC_ENABLE, setADCEnable},
};
/* Module Configuration Menus */
enum pwm_module_cfg_commands
{
PWM_CMD_MODULE_CFG_DRIVE,
PWM_CMD_MODULE_CFG_SOURCE,
PWM_CMD_MODULE_CFG_COUNT
};
naiapp_cmdtbl_params_t PWM_ModuleCfgMenuCmds[] = {
{"D", " Drive Mode", PWM_CMD_MODULE_CFG_DRIVE, setDriveMode},
{"S", " Source", PWM_CMD_MODULE_CFG_SOURCE, setSourceSelect},
};
/* Channel Configuration Menus */
enum pwm_channel_cfg_commands
{
PWM_CMD_CHAN_CFG_CURRENT_LIMIT,
PWM_CMD_CHAN_CFG_INPUT_SCALE,
PWM_CMD_CHAN_CFG_GLOBAL_GAIN,
PWM_CMD_CHAN_CFG_INTEGRAL_GAIN,
PWM_CMD_CHAN_CFG_PROPORTIONAL_GAIN,
PWM_CMD_CHAN_CFG_COUNT
};
naiapp_cmdtbl_params_t PWM_ChannelCfgMenuCmds[] = {
{"C", " Current Limit", PWM_CMD_CHAN_CFG_CURRENT_LIMIT, setCurrentLimit},
{"S", " Input Scale", PWM_CMD_CHAN_CFG_INPUT_SCALE, setInputScale},
{"G", " Global Gain", PWM_CMD_CHAN_CFG_GLOBAL_GAIN, setGlobalGain},
{"I", " Integral Gain", PWM_CMD_CHAN_CFG_INTEGRAL_GAIN, setIntegralGain},
{"P", " Proportional Gain", PWM_CMD_CHAN_CFG_PROPORTIONAL_GAIN, setProportionalGain},
};
/* PWM Watchdog Menus */
enum pwm_watchdog_commands
{
PWM_CMD_WATCHDOG_TIMEOUT,
PWM_CMD_WATCHDOG_ENABLE,
PWM_CMD_WATCHDOG_COUNT
};
naiapp_cmdtbl_params_t PWM_WatchdogMenuCmds[] = {
{"T", " Watchdog Timeout", PWM_CMD_WATCHDOG_TIMEOUT, setPWMWatchdogTimeout},
{"E", " Watchdog Enable", PWM_CMD_WATCHDOG_ENABLE, setPWMWatchdogEnable},
};
/* PWM General Control Menus */
enum pwm_general_control_commands
{
PWM_CMD_BATTLEFIELD_OVERRIDE_ENABLE,
PWM_CMD_PS_OVERTEMP_OVERRIDE_ENABLE,
PWM_CMD_SOFT_RESET,
PWM_CMD_GENERAL_CONTROL_COUNT
};
naiapp_cmdtbl_params_t PWM_GeneralControlMenuCmds[] = {
{"B", " Battlefield Override Enable", PWM_CMD_BATTLEFIELD_OVERRIDE_ENABLE, setPWMBattlefieldOverrideEnable},
{"P", " PS Over-Temp Override Enable", PWM_CMD_PS_OVERTEMP_OVERRIDE_ENABLE, setPWMPSOvertempOverrideEnable},
{"R", " Soft Reset", PWM_CMD_SOFT_RESET, setPWMSoftReset},
};
/* PWM Serial Control Menus */
enum pwm_serial_control_commands
{
PWM_CMD_SERIAL_RX_CLOCK_EDGE,
PWM_CMD_SERIAL_WATCHDOG_TIMEOUT,
PWM_CMD_SERIAL_WATCHDOG_ENABLE,
PWM_CMD_SERIAL_TESTBITS,
PWM_CMD_SERIAL_TRANSMIT_ENABLE,
PWM_CMD_SERIAL_DISABLE_CRC_ERROR_COUNT,
PWM_CMD_SERIAL_DISABLE_DATA_FRAME_COUNT,
PWM_CMD_SERIAL_CONTROL_COUNT
};
naiapp_cmdtbl_params_t PWM_SerialControlMenuCmds[] = {
{"Clk", " Rx Clock Edge", PWM_CMD_SERIAL_RX_CLOCK_EDGE, setPWMSerialRxClockEdge},
{"WT", " Watchdog Timeout", PWM_CMD_SERIAL_WATCHDOG_TIMEOUT, setPWMSerialWatchdogTimeout},
{"WE", " Watchdog Enable", PWM_CMD_SERIAL_WATCHDOG_ENABLE, setPWMSerialWatchdogEnable},
{"TB", " Test Bits", PWM_CMD_SERIAL_TESTBITS, setPWMSerialTestBits},
{"TE", " Transmit Enable", PWM_CMD_SERIAL_TRANSMIT_ENABLE, setPWMSerialTransmitEnable},
{"CRC", " CRC Error Count Disable", PWM_CMD_SERIAL_DISABLE_CRC_ERROR_COUNT, setPWMCRCErrorCountDisable},
{"DF", " Data Frame Count Disable", PWM_CMD_SERIAL_DISABLE_DATA_FRAME_COUNT, setPWMDataFrameCountDisable},
};
/**************************************************************************************************************/
/**
<summary>
The purpose of the PWM_BasicOps is to illustrate the methods to call in the naibrd library to perform basic
operations to the PWM Devices (64PW2 and 68PW1).
</summary>
*/
/**************************************************************************************************************/
#ifdef __VXWORKS__
int32_t PWM_BasicOps_Sample(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
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))
{
PWM_BasicOps_run(cardIndex, module, moduleID);
}
}
}
printf("\nType Q to quit or Enter key to restart application:\n");
stop = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
}
}
printf("\nType the Enter key to exit the program: ");
naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
naiapp_access_CloseAllOpenCards();
return 0;
}
/* Private Function Prototypes */
static bool_t PWM_BasicOps_run(int32_t cardIndex, int32_t module, uint32_t modId)
{
bool_t bQuit = FALSE;
bool_t bCmdFound = FALSE;
int32_t cmd;
naiapp_AppParameters_t pwm_basicops_params;
p_naiapp_AppParameters_t pwm_basicOps_params = &pwm_basicops_params;
pwm_basicOps_params->cardIndex = cardIndex;
pwm_basicOps_params->module = module;
pwm_basicOps_params->channel = DEFAULT_CHANNEL;
pwm_basicOps_params->maxChannels = naibrd_PWM_GetChannelCount(modId);
pwm_basicOps_params->modId = modId;
pwm_basicOps_params->displayHex = FALSE;
do
{
naiapp_utils_LoadParamMenuCommands(PWM_CMD_MAIN_COUNT, PWM_MenuCmds);
naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_PGM_NAME);
printf("\n\nPlease enter a command or 'q' to quit:");
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(g_responseCnt, g_op, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case PWM_CMD_PWM_CONTROL:
case PWM_CMD_DAC_CONTROL:
case PWM_CMD_ADC_CONTROL:
case PWM_CMD_MEASUREMENT:
case PWM_CMD_STATUS:
case PWM_CMD_CHANNEL_CFG:
case PWM_CMD_WATCHDOG:
case PWM_CMD_GENERAL_CONTROL:
case PWM_CMD_SERIAL:
PWM_MenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)pwm_basicOps_params);
break;
default:
break;
}
}
else
{
printf("Invalid command entered\n");
}
}
}
} while (!bQuit);
return bQuit;
}
/*********************************/
/* PWM Channel Control Functions */
/*********************************/
static nai_status_t handlePWMChannelControls(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getPWMChannelControls(paramCount, p_params);
bQuit = setPWMChannelControls(paramCount, p_params);
if (bQuit)
{
bContinue = FALSE;
}
}
return NAI_SUCCESS;
}
static nai_status_t getPWMChannelControls(int32_t paramCount, int32_t* p_params)
{
float32_t current_mA = 0.0;
float32_t voltage = 0.0;
bool_t driveEnabled = FALSE;
uint32_t hexValue = 0;
int32_t channel;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nPWM Controls:\n");
printf("==============\n");
printf("Chan Current Command (A) Voltage Command (V) Drive Enable \n");
printf("--------------------------------------------------------------------------\n");
for (channel = 1; channel <= pwm_basicOps_params->maxChannels; channel++)
{
printf(" %d ", channel);
/* Retrieve Current Command */
check_status(naibrd_PWM_GetCurrent(cardIndex, module, channel, ¤t_mA));
check_status(naibrd_PWM_GetChannelRaw(cardIndex, module, channel, NAI_PWM_CHAN_RAW_CURRENT_CMD, &hexValue));
printf(" %8.3f (0x%08X) ", current_mA/1000.0f, hexValue);
/* Retrieve Voltage Command */
check_status(naibrd_PWM_GetVoltage(cardIndex, module, channel, &voltage));
check_status(naibrd_PWM_GetChannelRaw(cardIndex, module, channel, NAI_PWM_CHAN_RAW_VOLTAGE_CMD, &hexValue));
printf(" %8.3f (0x%08X) ", voltage, hexValue);
/* Retrieve Drive Enable */
check_status(naibrd_PWM_GetDriveEnable(cardIndex, module, channel, &driveEnabled));
check_status(naibrd_PWM_GetChannelRaw(cardIndex, module, channel, NAI_PWM_CHAN_RAW_DRIVE_ENABLE, &hexValue));
if (driveEnabled == TRUE)
{
printf(" Enabled");
}
else
{
printf(" Disabled");
}
printf(" (0x%08X)", hexValue);
printf("\n");
}
return NAI_SUCCESS;
}
static bool_t setPWMChannelControls(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t bCmdFound = FALSE;
int32_t cmd;
int32_t channel;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
sprintf((char*)g_op, "\nPlease select the channel to update or Q to quit (default: 1): ");
channel = queryPWMChannel(g_op, pwm_basicOps_params->maxChannels, 1);
if (channel > 0)
{
naiapp_utils_LoadParamMenuCommands(PWM_CMD_CHAN_CONTROL_COUNT, PWM_ChannelControlMenuCmds);
naiapp_display_ParamMenuCommands((int8_t *)"PWM Channel Control Menu");
printf("Type Channel Control command or %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(g_responseCnt, g_op, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case PWM_CMD_CHAN_CURRENT:
case PWM_CMD_CHAN_VOLTAGE:
case PWM_CMD_CHAN_DRIVE_ENABLE:
case PWM_CMD_CHAN_DRIVE_RESET:
PWM_ChannelControlMenuCmds[cmd].func(paramCount, p_params);
break;
default:
break;
}
}
}
}
}
else
{
bQuit = TRUE;
}
return bQuit;
}
static nai_status_t setCurrentCommand(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
float32_t current;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Current Command in amps for Channel %d: ", channel);
bQuit = queryFloat32Value(g_op, ¤t);
if (!bQuit)
{
/* Note, the current API is units of mA */
status = check_status(naibrd_PWM_SetCurrent(cardIndex, module, channel, current * 1000.0f));
}
return status;
}
static nai_status_t setVoltageCommand(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
float32_t voltage;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Voltage Command in volts for Channel %d: ", channel);
bQuit = queryFloat32Value(g_op, &voltage);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetVoltage(cardIndex, module, channel, voltage));
}
//naibrd_ReadReg32(cardIndex, module, 0x10, &outvoltage);
//printf("\nsetVoltageCommand cardIdx:0x%x, module: 0x%x, outvoltage: 0x%x", cardIndex, module, outvoltage);
return status;
}
static nai_status_t setDriveEnable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enable the PWM Drive for Channel %d (Y or N)?: ", channel);
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetDriveEnable(cardIndex, module, channel, responseYes));
}
return status;
}
static nai_status_t resetDrive(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
return check_status(naibrd_PWM_ResetDrive(cardIndex, module, channel));
}
/*****************************/
/* PWM DAC Control Functions */
/*****************************/
static nai_status_t handleDACControls(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getDACControls(paramCount, p_params);
printf("Hit Enter to refresh data or type %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (bQuit)
{
bContinue = FALSE;
}
}
return NAI_SUCCESS;
}
static nai_status_t getDACControls(int32_t paramCount, int32_t* p_params)
{
float32_t dacOutput = 0;
uint32_t hexValue = 0;
int32_t dac;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nDAC Controls:\n");
printf("==============\n");
printf("DAC Output Value\n");
printf("------------------\n");
for (dac = 1; dac <= MAX_PWM_DAC_CHANNELS; dac++)
{
printf(" %d ", dac);
/* Retrieve DAC Output */
check_status(naibrd_PWM_GetDACOutput(cardIndex, module, dac, &dacOutput));
check_status(naibrd_PWM_GetDAChannelRaw(cardIndex, module, dac, NAI_PWM_CHAN_RAW_DA_OUTPUT, &hexValue));
printf("%8.3f (0x%08X)", dacOutput, hexValue);
printf("\n");
}
printf("\n");
return NAI_SUCCESS;
}
/*****************************/
/* PWM ADC Control Functions */
/*****************************/
static nai_status_t handleADCControls(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getADCControls(paramCount, p_params);
if (g_selectedDevice == DEVICE_64PW2)
{
bQuit = setADCControls(paramCount, p_params);
if (bQuit)
{
bContinue = FALSE;
}
}
else
{
printf("Hit Enter to refresh data or type %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (bQuit)
{
bContinue = FALSE;
}
}
}
return NAI_SUCCESS;
}
static nai_status_t getADCControls(int32_t paramCount, int32_t* p_params)
{
float32_t voltage = 0;
nai_pwm_adc_source_t source;
bool_t adcEnabled;
uint32_t hexValue = 0;
int32_t adc;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nADC Controls:\n");
printf("==============\n");
printf("ADC Voltage Source Enabled \n");
printf("-----------------------------------------------------------------------\n");
for (adc = 1; adc <= MAX_PWM_ADC_CHANNELS; adc++)
{
printf(" %d ", adc);
/* Retrieve ADC Input */
check_status(naibrd_PWM_GetADCInput(cardIndex, module, adc, &voltage));
check_status(naibrd_PWM_GetADChannelRaw(cardIndex, module, adc, NAI_PWM_CHAN_RAW_AD_INPUT, &hexValue));
printf("%8.3f (0x%08X)", voltage, hexValue);
/* Retrieve ADC Source */
check_status(naibrd_PWM_GetADCSource(cardIndex, module, adc, &source));
switch (source)
{
case NAI_PWM_ADC_SOURCE_SERIAL:
printf(" Serial");
break;
case NAI_PWM_ADC_SOURCE_ETHERNET:
printf(" Ethernet");
break;
case NAI_PWM_ADC_SOURCE_PWM_CH1:
printf(" PWM Ch 1");
break;
case NAI_PWM_ADC_SOURCE_PWM_CH2:
printf(" PWM Ch 2");
break;
default:
printf(" Unknown");
break;
}
printf(" (0x%08X) ", source);
/* Retrieve AD Enable */
check_status(naibrd_PWM_GetADCEnable(cardIndex, module, adc, &adcEnabled));
check_status(naibrd_PWM_GetADChannelRaw(cardIndex, module, adc, NAI_PWM_CHAN_RAW_AD_ENABLE, &hexValue));
if (adcEnabled == TRUE)
{
printf(" Enabled");
}
else
{
printf("Disabled");
}
printf(" (0x%08X)", hexValue);
printf("\n");
}
return NAI_SUCCESS;
}
static bool_t setADCControls(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t bCmdFound = FALSE;
int32_t cmd;
int32_t adc;
sprintf((char*)g_op, "\nPlease select the ADC channel to update or Q to quit (default: 1): ");
adc = queryPWMChannel(g_op, MAX_PWM_ADC_CHANNELS, 1);
if (adc > 0)
{
naiapp_utils_LoadParamMenuCommands(PWM_CMD_ADC_CONTROL_COUNT, PWM_ADCControlMenuCmds);
naiapp_display_ParamMenuCommands((int8_t *)"PWM ADC Control Menu");
printf("Type ADC Control command or %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(g_responseCnt, g_op, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case PWM_CMD_ADC_SOURCE:
case PWM_CMD_ADC_ENABLE:
PWM_ADCControlMenuCmds[cmd].func(paramCount, p_params);
break;
default:
break;
}
}
}
}
}
else
{
bQuit = TRUE;
}
return bQuit;
}
static nai_status_t setADCEnable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enable the ADC Input for Channel %d (Y or N)?: ", channel);
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetADCEnable(cardIndex, module, channel, responseYes));
}
return status;
}
static nai_status_t setADCSource(int32_t paramCount, int32_t* p_params)
{
nai_status_t status = NAI_SUCCESS;
bool_t bQuit = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("Set Source:\n");
printf("S - Serial\n");
printf("E - Ethernet\n");
printf("1 - PWM Ch 1\n");
printf("2 - PWM Ch 2\n");
printf(">");
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
if ((toupper(g_op[0]) == 'S'))
{
status = check_status(naibrd_PWM_SetADCSource(cardIndex, module, channel, NAI_PWM_ADC_SOURCE_SERIAL));
}
else if ((toupper(g_op[0]) == 'E'))
{
status = check_status(naibrd_PWM_SetADCSource(cardIndex, module, channel, NAI_PWM_ADC_SOURCE_ETHERNET));
}
else if ((toupper(g_op[0]) == '1'))
{
status = check_status(naibrd_PWM_SetADCSource(cardIndex, module, channel, NAI_PWM_ADC_SOURCE_PWM_CH1));
}
else if ((toupper(g_op[0]) == '2'))
{
status = check_status(naibrd_PWM_SetADCSource(cardIndex, module, channel, NAI_PWM_ADC_SOURCE_PWM_CH2));
}
}
}
return status;
}
/*****************************/
/* PWM Measurement Functions */
/*****************************/
static nai_status_t handlePWMMeasurements(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getPWMMeasurements(paramCount, p_params);
printf("Hit Enter to refresh data or type %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (bQuit)
{
bContinue = FALSE;
}
}
return NAI_SUCCESS;
}
static nai_status_t getPWMMeasurements(int32_t paramCount, int32_t* p_params)
{
float32_t current1_mA = 0.0f, current2_mA = 0.0f, current3_mA = 0.0f;
float32_t voltage1 = 0.0f, voltage2 = 0.0f, voltage3 = 0.0f;
int32_t temperature = 0;
uint32_t hexValue = 0;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nPWM Measurements:\n");
printf("================\n");
if (NAI_MODULE_ID_PW1 == pwm_basicOps_params->modId)
{
printf("Chan Current (A) Voltage (V) Temperature(C)\n");
printf("---------------------------------------------------------------\n");
for (channel = 1; channel <= pwm_basicOps_params->maxChannels; channel++)
{
printf(" %d ", channel);
/* Retrieve Measured Current */
check_status(naibrd_PWM_GetMeasuredCurrent(cardIndex, module, channel, ¤t1_mA));
check_status(naibrd_PWM_GetChannelRaw(cardIndex, module, channel, NAI_PWM_CHAN_RAW_MEASURED_CURRENT, &hexValue));
printf("%8.3f (0x%08X)", current1_mA/1000.f, hexValue);
/* Retrieve Voltage */
check_status(naibrd_PWM_GetMeasuredVoltage(cardIndex, module, channel, &voltage1));
check_status(naibrd_PWM_GetChannelRaw(cardIndex, module, channel, NAI_PWM_CHAN_RAW_MEASURED_VOLTAGE, &hexValue));
printf("%8.3f (0x%08X)", voltage1, hexValue);
/* Retrieve Temperature */
check_status(naibrd_PWM_GetMeasuredTemperature(cardIndex, module, channel, &temperature));
printf(" %d", temperature);
printf("\n\n");
printf("PS Voltage (V) Temperature(C)\n");
printf("-------------------------------------------\n");
/* Retrieve Power Supply Voltage */
check_status(naibrd_PWM_GetMeasuredPSVoltage(cardIndex, module, &voltage1));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_PS_VOLTAGE, &hexValue));
printf(" %8.3f (0x%08X) ", voltage1, hexValue);
/* Retrieve Power Supply Temperature */
check_status(naibrd_PWM_GetMeasuredPSTemperature(cardIndex, module, &temperature));
printf(" %d", temperature);
}
}
else if (NAI_MODULE_ID_PW2 == pwm_basicOps_params->modId)
{
printf("Chan Current1(A) Current2(A) Current3(A) Voltage1 Voltage2 Voltage3 PSCurrent(A) PSVoltage\n");
printf("----------------------------------------------------------------------------------------------------\n");
for (channel = 1; channel <= pwm_basicOps_params->maxChannels; channel++)
{
printf(" %d ", channel);
/* Retrieve Measured Current */
check_status(naibrd_PWM_GetDriveMeasureCurrent(cardIndex, module, channel, 1, ¤t1_mA));
check_status(naibrd_PWM_GetDriveMeasureCurrent(cardIndex, module, channel, 2, ¤t2_mA));
check_status(naibrd_PWM_GetDriveMeasureCurrent(cardIndex, module, channel, 3, ¤t3_mA));
printf("%8.3f %8.3f %8.3f ", current1_mA/1000.0f, current2_mA/1000.0f, current3_mA/1000.0f);
/* Retrieve Voltage */
check_status(naibrd_PWM_GetDriveMeasureVoltage(cardIndex, module, channel, 1, &voltage1));
check_status(naibrd_PWM_GetDriveMeasureVoltage(cardIndex, module, channel, 2, &voltage2));
check_status(naibrd_PWM_GetDriveMeasureVoltage(cardIndex, module, channel, 3, &voltage3));
printf("%8.3f %8.3f %8.3f ", voltage1, voltage2, voltage3);
/* Retrieve Power Supply Voltage */
check_status(naibrd_PWM_GetPSVoltageMeasure(cardIndex, module, channel, &voltage1));
/* Retrieve Power Supply Current */
check_status(naibrd_PWM_GetPSCurrentMeasure(cardIndex, module, channel, ¤t1_mA));
printf("%8.3f %8.3f", current1_mA/1000.0f, voltage1);
printf("\n");
}
}
else
{
printf("Feature is not supported by this module.\n");
}
printf("\n\n");
return NAI_SUCCESS;
}
/************************/
/* PWM Status Functions */
/************************/
static nai_status_t handlePWMStatus(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getPWMStatus(paramCount, p_params);
printf("Hit Enter to refresh data or type %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (bQuit)
{
bContinue = FALSE;
}
}
return NAI_SUCCESS;
}
static nai_status_t getPWMStatus(int32_t paramCount, int32_t* p_params)
{
uint32_t hexValue = 0;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nPWM Status:\n");
printf("===========\n");
printf(" Status Board Ready \n");
printf("----------------------------------\n");
/* Retrieve PWM Status */
check_status(naibrd_PWM_GetStatus(cardIndex, module, &hexValue));
printf("0x%08X ", hexValue);
/* Retrieve Board Ready Status */
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_BOARD_READY, &hexValue));
if (naibrd_PWM_IsBoardReady(cardIndex, module) == NAI_SUCCESS)
{
printf(" READY");
}
else
{
printf("NOT READY");
}
printf(" (0x%08X)", hexValue);
printf("\n");
return NAI_SUCCESS;
}
/**************************************/
/* PWM Module Configuration Functions */
/**************************************/
static nai_status_t handlePWMModuleCfg(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getPWMModuleCfg(paramCount, p_params);
bQuit = setPWMModuleCfg(paramCount, p_params);
if (bQuit)
{
bContinue = FALSE;
}
}
return NAI_SUCCESS;
}
static nai_status_t getPWMModuleCfg(int32_t paramCount, int32_t* p_params)
{
nai_pwm_drive_mode_t mode;
nai_pwm_source_t source;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nPWM Module Configuration:\n");
printf("=========================\n");
printf(" Drive Mode Source \n");
printf("-----------------------------------------------\n");
/* Retrieve Drive Mode */
check_status(naibrd_PWM_GetDriveMode(cardIndex, module, &mode));
switch (mode)
{
case NAI_PWM_CURRENT_DRIVE:
printf("Current");
break;
case NAI_PWM_VOLTAGE_DRIVE:
printf("Voltage");
break;
default:
printf("Unknown");
break;
}
printf(" (0x%08X) ", mode);
/* Retrieve Source Select */
check_status(naibrd_PWM_GetSource(cardIndex, module, &source));
switch (source)
{
case NAI_PWM_SOURCE_SERIAL:
printf(" Serial");
break;
case NAI_PWM_SOURCE_OTHER:
printf(" Other");
break;
default:
printf("Unknown");
break;
}
printf(" (0x%08X) ", source);
return NAI_SUCCESS;
}
static bool_t setPWMModuleCfg(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t bCmdFound = FALSE;
int32_t cmd;
naiapp_utils_LoadParamMenuCommands(PWM_CMD_MODULE_CFG_COUNT, PWM_ModuleCfgMenuCmds);
naiapp_display_ParamMenuCommands((int8_t *)"Board Configuration Menu");
printf("Type Module Configuration command or %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(g_responseCnt, g_op, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case PWM_CMD_MODULE_CFG_DRIVE:
case PWM_CMD_MODULE_CFG_SOURCE:
PWM_ModuleCfgMenuCmds[cmd].func(paramCount, p_params);
break;
default:
break;
}
}
}
}
return bQuit;
}
static nai_status_t setDriveMode(int32_t paramCount, int32_t* p_params)
{
nai_status_t status = NAI_SUCCESS;
bool_t bQuit = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("Set Drive Mode:\n");
printf("C - Current\n");
printf("V - Voltage\n");
printf(">");
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
if ((toupper(g_op[0]) == 'C'))
{
status = check_status(naibrd_PWM_SetDriveMode(cardIndex, module, NAI_PWM_CURRENT_DRIVE));
}
else if ((toupper(g_op[0]) == 'V'))
{
status = check_status(naibrd_PWM_SetDriveMode(cardIndex, module, NAI_PWM_VOLTAGE_DRIVE));
}
}
}
return status;
}
static nai_status_t setSourceSelect(int32_t paramCount, int32_t* p_params)
{
nai_status_t status = NAI_SUCCESS;
bool_t bQuit = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("Set Source:\n");
printf("S - Serial\n");
printf("O - Other (VME, PCIe, Ethernet)\n");
printf(">");
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
if ((toupper(g_op[0]) == 'S'))
{
status = check_status(naibrd_PWM_SetSource(cardIndex, module, NAI_PWM_SOURCE_SERIAL));
}
else if ((toupper(g_op[0]) == 'O'))
{
status = check_status(naibrd_PWM_SetSource(cardIndex, module, NAI_PWM_SOURCE_OTHER));
}
}
}
return status;
}
/************************************/
/* Channel Configuration Functions */
/************************************/
static nai_status_t handlePWMChannelCfg(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getPWMChannelCfg(paramCount, p_params);
bQuit = setPWMChannelCfg(paramCount, p_params);
if (bQuit)
{
bContinue = FALSE;
}
}
return NAI_SUCCESS;
}
static nai_status_t getPWMChannelCfg(int32_t paramCount, int32_t* p_params)
{
float32_t currentLimit_mA = 0.0;
uint32_t hexValue = 0;
int32_t cfgValue = 0;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nChannel Configuration:\n");
printf("====================\n");
printf("Chan Current Limit Input Scale(Kc) Global Gain(Kg) Integral Gain(Ki) Prop Gain(Kp) \n");
printf("------------------------------------------------------------------------------------------------------------\n");
for (channel = 1; channel <= pwm_basicOps_params->maxChannels; channel++)
{
printf(" %d ", channel);
/* Retrieve Current Limit */
check_status(naibrd_PWM_GetCurrentLimit(cardIndex, module, channel, ¤tLimit_mA));
check_status(naibrd_PWM_GetChannelRaw(cardIndex, module, channel, NAI_PWM_CHAN_RAW_CURRENT_LIMIT, &hexValue));
printf("%8.3f (0x%08X)", currentLimit_mA/1000.0f, hexValue);
/* Retrieve Input Scale */
check_status(naibrd_PWM_GetInputScale(cardIndex, module, channel, &cfgValue));
printf(" %6d (0x%08X)", cfgValue, cfgValue);
/* Retrieve Global Gain */
check_status(naibrd_PWM_GetGlobalGain(cardIndex, module, channel, &cfgValue));
printf(" %6d (0x%08X)", cfgValue, cfgValue);
/* Retrieve Integral Gain */
check_status(naibrd_PWM_GetIntegralGain(cardIndex, module, channel, &cfgValue));
printf(" %6d (0x%08X)", cfgValue, cfgValue);
/* Retrieve Proportional Gain */
check_status(naibrd_PWM_GetProportionalGain(cardIndex, module, channel, &cfgValue));
printf(" %6d (0x%08X)", cfgValue, cfgValue);
printf("\n");
}
return NAI_SUCCESS;
}
static bool_t setPWMChannelCfg(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t bCmdFound = FALSE;
int32_t cmd;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t channel = pwm_basicOps_params->channel;
sprintf((char*)g_op, "\nPlease select the channel to update or Q to quit (default: 1): ");
channel = queryPWMChannel(g_op, pwm_basicOps_params->maxChannels, 1);
if (channel > 0)
{
naiapp_utils_LoadParamMenuCommands(PWM_CMD_CHAN_CFG_COUNT, PWM_ChannelCfgMenuCmds);
naiapp_display_ParamMenuCommands((int8_t *)"Channel Configuration Menu");
printf("Type Channel Configuration command or %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(g_responseCnt, g_op, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case PWM_CMD_CHAN_CFG_CURRENT_LIMIT:
case PWM_CMD_CHAN_CFG_INPUT_SCALE:
case PWM_CMD_CHAN_CFG_GLOBAL_GAIN:
case PWM_CMD_CHAN_CFG_INTEGRAL_GAIN:
case PWM_CMD_CHAN_CFG_PROPORTIONAL_GAIN:
PWM_ChannelCfgMenuCmds[cmd].func(paramCount, p_params);
break;
default:
break;
}
}
}
}
}
else
{
bQuit = TRUE;
}
return bQuit;
}
static nai_status_t setCurrentLimit(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
float32_t currentLimit;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Current Limit in amps for Channel %d: ", channel);
bQuit = queryFloat32Value(g_op, ¤tLimit);
if (!bQuit)
{
/* Note, the current API is units of mA */
status = check_status(naibrd_PWM_SetCurrentLimit(cardIndex, module, channel, currentLimit * 1000.0f));
}
return status;
}
static nai_status_t setInputScale(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
int32_t cfgValue;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Input Scale for Channel %d: ", channel);
bQuit = queryInt32Value(g_op, &cfgValue);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetInputScale(cardIndex, module, channel, cfgValue));
}
return status;
}
static nai_status_t setGlobalGain(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
int32_t cfgValue;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Global Gain for Channel %d: ", channel);
bQuit = queryInt32Value(g_op, &cfgValue);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetGlobalGain(cardIndex, module, channel, cfgValue));
}
return status;
}
static nai_status_t setIntegralGain(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
int32_t cfgValue;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Integral Gain for Channel %d: ", channel);
bQuit = queryInt32Value(g_op, &cfgValue);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetIntegralGain(cardIndex, module, channel, cfgValue));
}
return status;
}
static nai_status_t setProportionalGain(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
int32_t cfgValue;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
int32_t channel = pwm_basicOps_params->channel;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Proportional Gain for Channel %d: ", channel);
bQuit = queryInt32Value(g_op, &cfgValue);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetProportionalGain(cardIndex, module, channel, cfgValue));
}
return status;
}
/********************************************/
/* PWM VME/PCIe/Ethernet Watchdog Functions */
/********************************************/
static nai_status_t handlePWMWatchdogCfg(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getPWMWatchdogCfg(paramCount, p_params);
bQuit = setPWMWatchdogCfg(paramCount, p_params);
if (bQuit)
{
bContinue = FALSE;
}
}
return NAI_SUCCESS;
}
static nai_status_t getPWMWatchdogCfg(int32_t paramCount, int32_t* p_params)
{
float32_t watchdogTimeout = 0;
bool_t watchdogEnabled;
uint32_t hexValue = 0;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nWatchdog Configuration:\n");
printf("=======================\n");
printf(" Timeout Enabled \n");
printf("---------------------------------------\n");
/* Retrieve Watchdog Timeout */
check_status(naibrd_PWM_GetWatchdogTimeout(cardIndex, module, &watchdogTimeout));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_WATCHDOG_TIMEOUT, &hexValue));
printf("%7.2f (0x%08X)", watchdogTimeout, hexValue);
/* Retrieve Watchdog Enable State */
check_status(naibrd_PWM_GetWatchdogEnable(cardIndex, module, &watchdogEnabled));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_WATCHDOG_ENABLE, &hexValue));
if (watchdogEnabled == TRUE)
{
printf(" Enabled");
}
else
{
printf(" Disabled");
}
printf(" (0x%08X)", hexValue);
printf("\n");
return NAI_SUCCESS;
}
static bool_t setPWMWatchdogCfg(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t bCmdFound = FALSE;
int32_t cmd;
naiapp_utils_LoadParamMenuCommands(PWM_CMD_WATCHDOG_COUNT, PWM_WatchdogMenuCmds);
naiapp_display_ParamMenuCommands((int8_t *)"PWM Watchdog Menu");
printf("Type Watchdog command or %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(g_responseCnt, g_op, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case PWM_CMD_WATCHDOG_TIMEOUT:
case PWM_CMD_WATCHDOG_ENABLE:
PWM_WatchdogMenuCmds[cmd].func(paramCount, p_params);
break;
default:
break;
}
}
}
}
return bQuit;
}
static nai_status_t setPWMWatchdogTimeout(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
float32_t cfgValue;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Watchdog Timeout in milliseconds: ");
bQuit = queryFloat32Value(g_op, &cfgValue);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetWatchdogTimeout(cardIndex, module, cfgValue));
}
return status;
}
static nai_status_t setPWMWatchdogEnable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enable the Watchdog (Y or N)?: ");
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetWatchdogEnable(cardIndex, module, responseYes));
}
return status;
}
/*********************************/
/* PWM General Control Functions */
/*********************************/
static nai_status_t handlePWMGeneralControls(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getPWMGeneralControls(paramCount, p_params);
bQuit = setPWMGeneralControls(paramCount, p_params);
if (bQuit)
{
bContinue = FALSE;
}
}
return NAI_SUCCESS;
}
static nai_status_t getPWMGeneralControls(int32_t paramCount, int32_t* p_params)
{
bool_t battlefieldOverrideEnabled;
bool_t psOvertempOverrideEnabled;
uint32_t hexValue = 0;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nGeneral Controls:\n");
printf("=================\n");
printf("Battlefield Override PS Over-temp Override\n");
printf(" Enabled Enabled\n");
printf("----------------------------------------------\n");
/* Retrieve Battlefield Override Enable State */
check_status(naibrd_PWM_GetBattlefieldOverrideEnable(cardIndex, module, &battlefieldOverrideEnabled));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_BATTLEFIELD_OVERRIDE_ENABLE, &hexValue));
if (battlefieldOverrideEnabled == TRUE)
{
printf(" Enabled");
}
else
{
printf("Disabled");
}
printf(" (0x%08X) ", hexValue);
/* Retrieve PS Over-Temperature Override Enable State */
check_status(naibrd_PWM_GetPSOverTempOverrideEnable(cardIndex, module, &psOvertempOverrideEnabled));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_PS_OVERTEMP_DISABLE_OVERRIDE, &hexValue));
if (psOvertempOverrideEnabled == TRUE)
{
printf(" Enabled");
}
else
{
printf("Disabled");
}
printf(" (0x%08X)", hexValue);
printf("\n");
return NAI_SUCCESS;
}
static bool_t setPWMGeneralControls(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t bCmdFound = FALSE;
int32_t cmd;
do
{
naiapp_utils_LoadParamMenuCommands(PWM_CMD_GENERAL_CONTROL_COUNT, PWM_GeneralControlMenuCmds);
naiapp_display_ParamMenuCommands((int8_t*)"PWM General Control Menu");
printf("\n\nPlease enter a command or 'q' to quit:");
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(g_responseCnt, g_op, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case PWM_CMD_BATTLEFIELD_OVERRIDE_ENABLE:
case PWM_CMD_PS_OVERTEMP_OVERRIDE_ENABLE:
case PWM_CMD_SOFT_RESET:
PWM_GeneralControlMenuCmds[cmd].func(paramCount, p_params);
break;
default:
break;
}
}
}
}
} while (!bQuit);
return bQuit;
}
static nai_status_t setPWMSoftReset(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Reset PWM (Y or N)?: ");
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
if (responseYes == TRUE)
{
check_status(naibrd_PWM_SoftReset(cardIndex, module));
}
}
return NAI_SUCCESS;
}
static nai_status_t setPWMBattlefieldOverrideEnable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enable the Battlefield Override (Y or N)?: ");
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
check_status(naibrd_PWM_SetBattlefieldOverrideEnable(cardIndex, module, responseYes));
}
return NAI_SUCCESS;
}
static nai_status_t setPWMPSOvertempOverrideEnable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enable the PS Over-Temperature Override (Y or N)?: ");
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
check_status(naibrd_PWM_SetPSOverTempOverrideEnable(cardIndex, module, responseYes));
}
return NAI_SUCCESS;
}
/****************************/
/* Serial Control Functions */
/****************************/
static nai_status_t handlePWMSerialControls(int32_t paramCount, int32_t* p_params)
{
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
while (bContinue)
{
getPWMSerialControls(paramCount, p_params);
bQuit = setPWMSerialControls(paramCount, p_params);
if (bQuit)
{
bContinue = FALSE;
}
}
return NAI_SUCCESS;
}
static nai_status_t getPWMSerialControls(int32_t paramCount, int32_t* p_params)
{
nai_pwm_clock_edge_t clockEdge;
float32_t watchdogTimeout;
bool_t bEnabled;
uint32_t testBits;
int32_t count;
bool_t bDisabled;
uint32_t hexValue = 0;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("\n\nSerial Controls:\n");
printf("====================\n");
printf("Serial Configuration\n");
printf("--------------------\n");
printf("Rx Clock Serial Watchdog Serial Watchdog Serial Test Serial Transmit\n");
printf(" Edge Timeout (ms) Enable Bits Enable\n");
printf("----------------------------------------------------------------------------------------------------\n");
/* Retrieve Rx Clock Edge */
check_status(naibrd_PWM_GetSerialRxClockEdge(cardIndex, module, &clockEdge));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_SERIAL_RX_CLOCK_EDGE, &hexValue));
switch (clockEdge)
{
case NAI_PWM_CLOCK_EDGE_RISING:
printf(" Rising");
break;
case NAI_PWM_CLOCK_EDGE_FALLING:
printf("Falling");
break;
default:
printf("Unknown");
break;
}
printf(" (0x%08X) ", hexValue);
/* Retrieve Serial Watchdog Timeout */
check_status(naibrd_PWM_GetSerialWatchdogTimeout(cardIndex, module, &watchdogTimeout));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_SERIAL_WATCHDOG_TIMEOUT, &hexValue));
printf("%7.2f (0x%08X)", watchdogTimeout, hexValue);
/* Retrieve Serial Watchdog Enable State */
check_status(naibrd_PWM_GetSerialWatchdogEnable(cardIndex, module, &bEnabled));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_SERIAL_WATCHDOG_ENABLE, &hexValue));
if (bEnabled == TRUE)
{
printf(" Enabled");
}
else
{
printf(" Disabled");
}
printf(" (0x%08X)", hexValue);
/* Retrieve Serial Test Bits */
check_status(naibrd_PWM_GetSerialTestBits(cardIndex, module, &testBits));
printf(" 0x%08X ", testBits);
/* Retrieve Serial Transmit Enable */
check_status(naibrd_PWM_GetSerialTransmitEnable(cardIndex, module, &bEnabled));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_SERIAL_TRANSMIT_ENABLE, &hexValue));
if (bEnabled == TRUE)
{
printf(" Enabled");
}
else
{
printf(" Disabled");
}
printf(" (0x%08X)", hexValue);
printf("\n\n");
printf("CRC Error/Data Frame\n");
printf("--------------------\n");
printf(" CRC Error Data Frame CRC Error Count Data Frame Count Data Frame\n");
printf(" Count Count Disable Disabled Status\n");
printf("----------------------------------------------------------------------------------\n");
/* Retrieve CRC Error Count */
check_status(naibrd_PWM_GetCRCErrorCount(cardIndex, module, &count));
printf(" %5d", count);
/* Retrieve Data Frame Count */
check_status(naibrd_PWM_GetDataFrameCount(cardIndex, module, &count));
printf(" %5d ", count);
/* Retrieve CRC Error Count Disable */
check_status(naibrd_PWM_GetCRCErrorCountDisable(cardIndex, module, &bDisabled));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_SERIAL_CRC_ERROR_COUNT_DISABLE, &hexValue));
if (bDisabled == FALSE)
{
printf(" Enabled");
}
else
{
printf(" Disabled");
}
printf(" (0x%08X)", hexValue);
/* Retrieve Data Frame Count Diable */
check_status(naibrd_PWM_GetDataFrameCountDisable(cardIndex, module, &bDisabled));
check_status(naibrd_PWM_GetRaw(cardIndex, module, NAI_PWM_RAW_SERIAL_DATA_FRAME_COUNT_DISABLE, &hexValue));
if (bDisabled == FALSE)
{
printf(" Enabled");
}
else
{
printf(" Disabled");
}
printf(" (0x%08X)", hexValue);
/* Retrieve Data Frame Status */
check_status(naibrd_PWM_GetDataFrameStatus(cardIndex, module, &hexValue));
printf(" 0x%08X", hexValue);
printf("\n");
return NAI_SUCCESS;
}
static bool_t setPWMSerialControls(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t bCmdFound = FALSE;
int32_t cmd;
naiapp_utils_LoadParamMenuCommands(PWM_CMD_SERIAL_CONTROL_COUNT, PWM_SerialControlMenuCmds);
naiapp_display_ParamMenuCommands((int8_t *)"PWM Serial Control Menu");
printf("Type Serial Control command or %c to quit : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
bCmdFound = naiapp_utils_GetParamMenuCmdNum(g_responseCnt, g_op, &cmd);
if (bCmdFound)
{
switch (cmd)
{
case PWM_CMD_SERIAL_RX_CLOCK_EDGE:
case PWM_CMD_SERIAL_WATCHDOG_TIMEOUT:
case PWM_CMD_SERIAL_WATCHDOG_ENABLE:
case PWM_CMD_SERIAL_TESTBITS:
case PWM_CMD_SERIAL_TRANSMIT_ENABLE:
case PWM_CMD_SERIAL_DISABLE_CRC_ERROR_COUNT:
case PWM_CMD_SERIAL_DISABLE_DATA_FRAME_COUNT:
PWM_SerialControlMenuCmds[cmd].func(paramCount, p_params);
break;
default:
break;
}
}
}
}
return bQuit;
}
static nai_status_t setPWMSerialRxClockEdge(int32_t paramCount, int32_t* p_params)
{
nai_status_t status = NAI_SUCCESS;
bool_t bQuit = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
printf("Set Clock Edge:\n");
printf("R - Rising\n");
printf("F - Falling\n");
printf(">");
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
if ((toupper(g_op[0]) == 'R'))
{
status = check_status(naibrd_PWM_SetSerialRxClockEdge(cardIndex, module, NAI_PWM_CLOCK_EDGE_RISING));
}
else if ((toupper(g_op[0]) == 'F'))
{
status = check_status(naibrd_PWM_SetSerialRxClockEdge(cardIndex, module, NAI_PWM_CLOCK_EDGE_FALLING));
}
}
}
return status;
}
static nai_status_t setPWMSerialWatchdogTimeout(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
float32_t cfgValue;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Serial Watchdog Timeout in milliseconds: ");
bQuit = queryFloat32Value(g_op, &cfgValue);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetSerialWatchdogTimeout(cardIndex, module, cfgValue));
}
return status;
}
static nai_status_t setPWMSerialWatchdogEnable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enable the Serial Watchdog (Y or N)?: ");
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetSerialWatchdogEnable(cardIndex, module, responseYes));
}
return status;
}
static nai_status_t setPWMSerialTestBits(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
uint32_t hexValue;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enter the Serial Test Value in Hex: ");
bQuit = queryHex32Value(g_op, &hexValue);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetSerialTestBits(cardIndex, module, hexValue));
}
return status;
}
static nai_status_t setPWMSerialTransmitEnable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Enable the Serial Transmit (Y or N)?: ");
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetSerialTransmitEnable(cardIndex, module, responseYes));
}
return status;
}
static nai_status_t setPWMCRCErrorCountDisable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Disable the CRC Error Count (Y or N)?: ");
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetCRCErrorCountDisable(cardIndex, module, responseYes));
}
return status;
}
static nai_status_t setPWMDataFrameCountDisable(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t responseYes = FALSE;
p_naiapp_AppParameters_t pwm_basicOps_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = pwm_basicOps_params->cardIndex;
int32_t module = pwm_basicOps_params->module;
nai_status_t status = NAI_SUCCESS;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
sprintf((char*)g_op, "Disable the Data Frame Count (Y or N)?: ");
bQuit = queryYesNoValue(g_op, &responseYes);
if (!bQuit)
{
status = check_status(naibrd_PWM_SetDataFrameCountDisable(cardIndex, module, responseYes));
}
return status;
}
/*********************************/
/* Private Query Routines */
/*********************************/
static int32_t queryPWMChannel(int8_t* p_queryText, int32_t maxChannel, int32_t defaultValue)
{
bool_t bQuit = FALSE;
bool_t bContinue = TRUE;
int32_t channel = defaultValue;
if (maxChannel > 1)
{
while (bContinue)
{
printf("%s", p_queryText);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
channel = (int32_t)atol((const char*)g_op);
if ((channel > 0) && (channel <= maxChannel))
{
bContinue = FALSE;
}
else
{
printf("ERROR: Invalid channel entered\n");
}
}
else
{
channel = defaultValue;
bContinue = FALSE;
}
}
else
{
channel = 0;
bContinue = FALSE;
}
}
}
return channel;
}
static bool_t queryFloat32Value(int8_t* p_queryText, float32_t* p_outFloat32)
{
bool_t bQuit = FALSE;
printf("%s ", p_queryText);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
*p_outFloat32 = (float32_t)atof((const char*)g_op);
}
else
{
printf("Invalid value entered\n");
}
}
return bQuit;
}
static bool_t queryInt32Value(int8_t* p_queryText, int32_t* p_outInt32)
{
bool_t bQuit = FALSE;
printf("%s ", p_queryText);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
*p_outInt32 = (int32_t)atol((const char*)g_op);
}
else
{
printf("Invalid value entered\n");
}
}
return bQuit;
}
static bool_t queryYesNoValue(int8_t* p_queryText, bool_t* p_outresponseYes)
{
bool_t bQuit = FALSE;
printf("%s ", p_queryText);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
if (toupper(g_op[0]) == 'Y')
{
*p_outresponseYes = TRUE;
}
else if (toupper(g_op[0]) == 'N')
{
*p_outresponseYes = FALSE;
}
else
{
printf("Invalid value entered\n");
*p_outresponseYes = FALSE;
}
}
else
{
printf("Invalid value entered\n");
}
}
return bQuit;
}
static bool_t queryHex32Value(int8_t* p_queryText, uint32_t* p_outHex32)
{
bool_t bQuit = FALSE;
printf("%s ", p_queryText);
bQuit = naiapp_query_ForQuitResponse(sizeof(g_op), NAI_QUIT_CHAR, g_op, &g_responseCnt);
if (!bQuit)
{
if (g_responseCnt > 0)
{
*p_outHex32 = naiapp_utils_HexStrToDecUInt32(g_op);
}
else
{
printf("Invalid value entered\n");
}
}
return bQuit;
}