Integrator Resources

The official home for NAI Support

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

Toggle Components with Visual Button
JavaScript Form Processing

DS SetAngle

DS SetAngle Sample Application (SSK 1.x)

Overview

The DS SetAngle sample application demonstrates how to configure the output angle and associated parameters on synchro/resolver (D/S) modules using the NAI Software Support Kit (SSK 1.x). It covers the angle configuration operations you will need in your own application: setting output angles, configuring expected signal and reference voltages, setting voltage loss thresholds, selecting fixed or ratio output mode, enabling channel status reporting, and managing channel power.

D/S modules convert digital angle values into analog synchro or resolver format signals. The output amplitude depends on the selected mode: in ratio mode, the output scales proportionally with the reference input voltage; in fixed mode, the output is held at a constant level. Voltage thresholds control when the module reports signal or reference loss conditions — the module compares its measured input voltages against these thresholds and sets status flags when a voltage drops below the configured level.

This sample supports all DS module types (see the DS1-DSN Manual for module variants and specifications). It serves as a practical API reference — each menu command maps directly to one or more naibrd_DS_*() API calls that you can lift into your own code.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a DS module installed.

  • 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 DS_SetAngle executable from your build output directory. On startup the application looks for a configuration file (default_DsSetAngle.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, select a module and channel, then enter the angle configuration submenu.

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 DS. For details on board connection configuration, see the First Time Setup Guide.

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

  1. Call naiapp_RunBoardMenu() to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_DsSetAngle.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear.

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

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

  4. Retrieve the module ID with naibrd_GetModuleID().

#if defined (__VXWORKS__)
int32_t DS_RunAngleProgramSample(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
                  DS_RunAngleProgram(cardIndex, module, moduleID);
            }
         }
         printf("\nType Q to quit or Enter key to restart application:\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }
   naiapp_access_CloseAllOpenCards();
   return 0;
}
Important

Common connection errors you may encounter at this stage:

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

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

  • Invalid card or module index — indices are zero-based for cards and one-based for modules. Ensure the values you pass match your hardware setup.

  • Module not present at selected slot — the slot you selected does not contain a DS module. Use the board menu to verify which slots are populated.

Program Structure

Entry Point

On standard platforms the entry point is main(). On VxWorks the entry point is DS_RunAngleProgramSample() — the SSK 1.x build system selects the correct variant via a preprocessor guard:

#if defined (__VXWORKS__)
int32_t DS_RunAngleProgramSample(void)
#else
int32_t main(void)
#endif

Command Loop

DS_RunAngleProgram() presents a top-level menu where the user selects a module, channel, and then enters the angle configuration submenu via the ANG command. The channel count is retrieved using naibrd_DS_GetChannelCount().

The top-level commands are:

Command Description

ANG

Enter the angle configuration submenu

M

Select module

C

Select channel

Within the angle configuration submenu (DS_RunAngleFunc()):

Command Description

ANG

Set output angle

VLL

Set expected signal voltage (VLL)

VREF

Set expected reference voltage

VLLTH

Set VLL threshold voltage

REFTH

Set VRef threshold voltage

MODE

Set fixed/ratio output mode

CSTATUS

Set channel status enable (formerly "active channel")

PWR

Set power enable/disable

READ

Read register (direct access)

WRITE

Write register (direct access)

U

Update/refresh the status display

The menu-driven structure is a convenience of the sample application. In your own application, you would call the same underlying naibrd_DS_*() API functions directly.

Angle and Voltage Configuration

This section covers the API calls for setting the output angle, configuring expected voltages, and defining voltage loss thresholds.

Set Output Angle

To set the output angle on a channel in your own application, call naibrd_DS_SetAngle():

float64_t angle = 90.0;
check_status(naibrd_DS_SetAngle(cardIndex, module, channel, NAI_DS_ANGLE_SINGLE, angle));
  • cardIndex — identifies the board.

  • module — the slot containing the DS module.

  • channel — the channel to configure.

  • NAI_DS_ANGLE_SINGLE — specifies single-speed angle mode.

  • angle — the desired angle in degrees (0.0 to 359.9954).

Set Expected VLL (Signal Voltage)

To set the expected line-to-line signal voltage for a channel, call naibrd_DS_SetExpectedVoltage(). The module uses this value to scale its output in ratio mode and to determine signal loss status. Set this to match the actual signal voltage of your synchro/resolver:

float64_t expectedVLL = 11.8;
check_status(naibrd_DS_SetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_SIGNAL, expectedVLL));
  • cardIndex — identifies the board.

  • module — the slot containing the DS module.

  • channel — the channel to configure.

  • NAI_DS_EXP_VOLT_SIGNAL — selects the signal (VLL) voltage parameter.

  • expectedVLL — the expected signal voltage (0.0 to 115.0 V). Consult the DS1-DSN Manual for the valid range on your module variant.

Set Expected VRef (Reference Voltage)

To set the expected reference voltage:

float64_t expectedVRef = 26.0;
check_status(naibrd_DS_SetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_REFERENCE, expectedVRef));
  • NAI_DS_EXP_VOLT_REFERENCE — selects the reference voltage parameter.

  • expectedVRef — the expected reference voltage (0.0 to 115.0 V).

Set VLL Threshold

The VLL threshold determines the minimum signal voltage below which the module reports a signal loss condition. When the measured VLL drops below this threshold, the signal loss status flag is set:

float64_t vllThreshold = 5.0;
check_status(naibrd_DS_SetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_SIGNAL, vllThreshold));
  • cardIndex — identifies the board.

  • module — the slot containing the DS module.

  • channel — the channel to configure.

  • NAI_DS_THRESHOLD_VOLT_SIGNAL — selects the signal voltage threshold.

  • vllThreshold — the minimum acceptable signal voltage (0.0 to 115.0 V).

Set VRef Threshold

The VRef threshold determines the minimum reference voltage below which the module reports a reference loss condition:

float64_t vrefThreshold = 10.0;
check_status(naibrd_DS_SetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_REFERENCE, vrefThreshold));
  • NAI_DS_THRESHOLD_VOLT_REFERENCE — selects the reference voltage threshold.

  • vrefThreshold — the minimum acceptable reference voltage (0.0 to 115.0 V).

Note
Consult the DS1-DSN Manual for the valid range of threshold values and recommended settings for your hardware configuration. A common practice is to set the threshold to approximately 80% of the expected voltage.

Set Fixed/Ratio Mode

To select how the module generates its output voltage — either at a fixed level or as a ratio of the reference input:

/* Fixed mode -- output voltage is constant regardless of reference */
check_status(naibrd_DS_SetRatioFixedMode(cardIndex, module, channel, NAI_DS_OUTPUT_FIXED));

/* Ratio mode -- output voltage scales proportionally with reference */
check_status(naibrd_DS_SetRatioFixedMode(cardIndex, module, channel, NAI_DS_OUTPUT_RATIO));
  • cardIndex — identifies the board.

  • module — the slot containing the DS module.

  • channel — the channel to configure.

  • NAI_DS_OUTPUT_FIXED — fixed output mode. The output amplitude is constant.

  • NAI_DS_OUTPUT_RATIO — ratio output mode. The output amplitude tracks the reference voltage.

In ratio mode, if the reference voltage changes, the output changes proportionally. In fixed mode, the output stays at its programmed level. Choose ratio mode when your system has a variable reference source and you want the output to track it.

Important

Common Errors

  • Signal or reference loss status — The expected voltage values do not match the actual signal on the module. Call naibrd_DS_SetExpectedVoltage() with values that match your external signal source.

  • Invalid threshold — Threshold values that exceed the expected voltage range will cause false fault indications. Use thresholds below the expected voltage.

  • Angle out of range — The angle value must be between 0.0 and 359.9954 degrees.

Channel Control

Set Channel Status Enable

To enable or disable status reporting for a channel, call naibrd_DS_SetChanStatusEnable(). This was formerly called "active channel" in older SSK versions. When status is enabled, the module monitors the channel for signal loss, reference loss, BIT, and phase conditions:

/* Enable status reporting */
check_status(naibrd_DS_SetChanStatusEnable(cardIndex, module, channel, NAI_ENABLE));

/* Disable status reporting */
check_status(naibrd_DS_SetChanStatusEnable(cardIndex, module, channel, NAI_DISABLE));
  • cardIndex — identifies the board.

  • module — the slot containing the DS module.

  • channel — the channel to configure.

  • The fourth parameter — NAI_ENABLE (1) to enable status monitoring, NAI_DISABLE (0) to disable it.

Note
Disabling channel status suppresses fault detection and any interrupts tied to status conditions for that channel.

Set Power Enable

To turn power on or off for a channel:

/* Power on */
check_status(naibrd_DS_SetPowerEnable(cardIndex, module, channel, (uint8_t)NAI_ENABLE));

/* Power off */
check_status(naibrd_DS_SetPowerEnable(cardIndex, module, channel, (uint8_t)NAI_DISABLE));
  • cardIndex — identifies the board.

  • module — the slot containing the DS module.

  • channel — the channel to control.

  • The fourth parameter — NAI_ENABLE (1) to power on, NAI_DISABLE (0) to power off.

Important

Common Errors

  • Measured values read zero — The channel is not powered or status is not enabled. Enable power and channel status first.

  • Status flags stuck in fault state — The expected voltage settings do not match the actual signal, or the thresholds are set too high relative to the expected values.

Reading Configuration and Status

The sample displays a comprehensive status line on each loop iteration via DS_ShowSetAngleTestResult(). This includes the set angle, measured angle, expected voltages, measured voltages, thresholds, ratio/fixed mode, multi-speed ratio, status flags, channel status enable state, and power state. To read these values in your own application:

float64_t angle, measAngle, expVLL, expVRef, measVLL, measVRef, measRefFreq;
float64_t vllThresh, vrefThresh;
uint32_t ratioFixed, multiSpdRatio, chanStatusEnable;
uint8_t powerState;

naibrd_DS_GetAngle(cardIndex, module, channel, NAI_DS_ANGLE_SINGLE, &angle);
naibrd_DS_GetMeasuredValue(cardIndex, module, channel, NAI_DS_MEASURED_ANGLE, &measAngle);
naibrd_DS_GetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_SIGNAL, &expVLL);
naibrd_DS_GetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_REFERENCE, &expVRef);
naibrd_DS_GetRatioFixedMode(cardIndex, module, channel, &ratioFixed);
naibrd_DS_GetMeasuredValue(cardIndex, module, channel, NAI_DS_MEASURED_SIGNAL_VOLTAGE, &measVLL);
naibrd_DS_GetMeasuredValue(cardIndex, module, channel, NAI_DS_MEASURED_REF_VOLTAGE, &measVRef);
naibrd_DS_GetMeasuredValue(cardIndex, module, channel, NAI_DS_MEASURED_REF_FREQUENCY, &measRefFreq);
naibrd_DS_GetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_SIGNAL, &vllThresh);
naibrd_DS_GetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_REFERENCE, &vrefThresh);
naibrd_DS_GetMultiSpeedRatio(cardIndex, module, NAI_DS_MULTI_SPD_CH1_2_PAIR, &multiSpdRatio);
naibrd_DS_GetChanStatusEnable(cardIndex, module, channel, &chanStatusEnable);
naibrd_DS_GetPowerEnable(cardIndex, module, channel, &powerState);

The status flags (signal loss, reference loss, BIT loss, phase loss) are read using real-time status registers in this sample, rather than latched registers:

uint32_t signalLoss, refLoss, bitLoss, phaseLoss;

naibrd_DS_GetStatus(cardIndex, module, channel, NAI_DS_STATUS_REAL_TIME_SIGNAL_LOST, &signalLoss);
naibrd_DS_GetStatus(cardIndex, module, channel, NAI_DS_STATUS_REAL_TIME_REFERENCE_LOST, &refLoss);
naibrd_DS_GetStatus(cardIndex, module, channel, NAI_DS_STATUS_REAL_TIME_BIT_LOST, &bitLoss);
naibrd_DS_GetStatus(cardIndex, module, channel, NAI_DS_STATUS_REAL_TIME_PHASE_LOST, &phaseLoss);
Note
Real-time status reflects the current condition of the channel. For latched status (which holds until explicitly cleared), use NAI_DS_STATUS_LATCH_* variants instead.

Troubleshooting Reference

Note
This section summarizes errors covered in the preceding sections. Consult the DS1-DSN Manual for hardware-specific diagnostics.
Error / Symptom Possible Causes Suggested Resolution

No board found or connection timeout

Board not powered, incorrect or missing configuration file, network issue

Verify hardware is powered and connected. If default_DsSetAngle.txt exists, check that it lists the correct interface and address.

Module not recognized at selected slot

Slot does not contain a DS module

Verify module installation with the board menu

Angle out of range

Value outside 0.0-359.9954

Correct the angle value

Signal loss status set

Expected VLL does not match actual signal, or VLL threshold set too high

Adjust expected voltage with naibrd_DS_SetExpectedVoltage() or lower the threshold

Reference loss status set

Expected VRef does not match actual reference, or VRef threshold set too high

Adjust expected reference voltage or lower the threshold

Measured values all zero

Channel not powered or channel status not enabled

Enable power and channel status before reading

Mode set to ratio but output does not track reference

Reference voltage is missing or below threshold

Verify external reference connection and voltage level

Full Source

The complete source for this sample is provided below for reference. The sections above explain each part in detail.

Full Source — DS_SetAngle.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.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 "DS_Common.h"
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_ds.h"
#include "advanced/nai_ether_adv.h"

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

/* Function prototypes */
static void DS_ShowSetAngleTestResult(int32_t cardIndex, int32_t module, int32_t channel);
static void DS_RunAngleProgram(int32_t cardIndex, int32_t module, uint32_t moduleID);
static void DS_RunAngleFunc(int32_t cardIndex, int32_t module, int32_t channel);
static void DS_SetNewAngle(int32_t cardIndex, int32_t module, int32_t channel);
static void DS_SetExpVLL(int32_t cardIndex, int32_t module, int32_t channel);
static void DS_SetExpVref(int32_t cardIndex, int32_t module, int32_t channel);
static void DS_SetVllThrehold(int32_t cardIndex, int32_t module, int32_t channel);
static void DS_SetVrefThreshold(int32_t cardIndex, int32_t module, int32_t channel);
static void DS_SetFixedRatioMode(int32_t cardIndex, int32_t module, int32_t channel);
static void DS_SetPower(int32_t cardIndex, int32_t module, int32_t channel);
static void DS_SetChannelStatusCtrl(int32_t cardIndex, int32_t module, int32_t channel);

static void Show_DSDemoFunc_Commands(void);
static void printInvalidUserInputMessage(uint32_t uTypeIdx, float64_t dUserInput);
static void showCurrentModChan(int32_t nModule, int32_t nChannel);
static void getStatus(int32_t cardIndex, int32_t module, int32_t channel, uint8_t *u8Status);

static int32_t getUserInput(void);
static bool_t checkUserInput(uint32_t uTypeIdx, float64_t dUserInput);

/****** Command Table *******/
enum dsfunc_commands
{
   DS_FUNC_CMD_SET_ANGLE,
   DS_FUNC_CMD_SET_MODULE,
   DS_FUNC_CMD_SET_CHANNEL,
   DS_FUNC_CMD_COUNT
};
/****** User Input Table *******/
enum dsfunc_userInputs
{
   DS_USER_INPUT_READ_REG,
   DS_USER_INPUT_WRITE_REG,
   DS_USER_INPUT_SET_ANGLE,
   DS_USER_INPUT_SET_EXP_VLL,
   DS_USER_INPUT_SET_EXP_VREF,
   DS_USER_INPUT_SET_VLL_THRESHOLD,
   DS_USER_INPUT_SET_VREF_THRESHOLD,
   DS_USER_INPUT_FIX_RATIO_MODE,
   DS_USER_INPUT_CHAN_STATUS_ENABLE,
   DS_USER_INPUT_POWER,
   DS_USER_INPUT_REFRESH,
   DS_USER_INPUT_QUIT,
   DS_USER_INVALID_INPUT,
   DS_USER_INPUT_COUNT
};

/* "what to type", "what is displayed", assigned cmd #, function called */
struct dsdemofunc_cmdtbl {
   int8_t *cmdstr;
   int8_t *menustr;
   int32_t  cmdnum;
   void(*func)(int32_t cardIndex, int32_t module, int32_t channel);
};

/* assigned cmd #, uppwer Limit, lower Limit*/
struct dsUserInputLimitTable {
   int32_t  cmdnum;
   int8_t *cmdstr;
   float64_t upperLimit;
   float64_t lowerLimit;
};

/****** Command Tables *******/
static struct dsdemofunc_cmdtbl DS_DemoFuncMenuCmds[] = {
   {(int8_t *)"ANG", (int8_t *)"Run Angle",            DS_FUNC_CMD_SET_ANGLE,          DS_RunAngleFunc},\
   {(int8_t *)"M ",  (int8_t *)"Select Module",        DS_FUNC_CMD_SET_MODULE,         NULL},\
   {(int8_t *)"C ",  (int8_t *)"Select Channel",       DS_FUNC_CMD_SET_CHANNEL,        NULL},\
   {NULL,            NULL,                             0,                              NULL}
};

/****** User Input Command Tables *******/
static struct dsdemofunc_cmdtbl DS_DemoUserInputs[] = {
   {(int8_t *)"READ   ",   (int8_t *)"Read Register",                                  DS_USER_INPUT_READ_REG,             NULL },\
   {(int8_t *)"WRITE  ",   (int8_t *)"Write Register",                                 DS_USER_INPUT_WRITE_REG,            NULL}, \
   {(int8_t *)"ANG    ",   (int8_t *)"Set Angle",                                      DS_USER_INPUT_SET_ANGLE,            DS_SetNewAngle},
   {(int8_t *)"VLL    ",   (int8_t *)"Set Exp. VLL",                                   DS_USER_INPUT_SET_EXP_VLL,          DS_SetExpVLL},
   {(int8_t *)"VREF   ",   (int8_t *)"Set Exp. Ref Volt",                              DS_USER_INPUT_SET_EXP_VREF,         DS_SetExpVref},
   {(int8_t *)"VLLTH  ",   (int8_t *)"Set VLL Threshold Volt",                         DS_USER_INPUT_SET_VLL_THRESHOLD,    DS_SetVllThrehold},
   {(int8_t *)"REFTH  ",   (int8_t *)"Set VREF Threshold Volt",                        DS_USER_INPUT_SET_VREF_THRESHOLD,   DS_SetVrefThreshold},
   {(int8_t *)"MODE   ",   (int8_t *)"Set Fixed / Ratio Mode",                         DS_USER_INPUT_FIX_RATIO_MODE,       DS_SetFixedRatioMode},
   {(int8_t *)"CSTATUS",   (int8_t *)"Set Chan Status Enable(Formally Active Chan.)",  DS_USER_INPUT_CHAN_STATUS_ENABLE,   DS_SetChannelStatusCtrl},
   {(int8_t *)"PWR    ",   (int8_t *)"Set Power",                                      DS_USER_INPUT_POWER,                DS_SetPower},
   {(int8_t *)"U",         (int8_t *)"Update",                                         DS_USER_INPUT_REFRESH,              NULL},
   {(int8_t *)"Q      ",   (int8_t *)"Quit",                                           DS_USER_INPUT_QUIT,                 NULL},
   {(int8_t *)"",          (int8_t *)"",                                               DS_USER_INVALID_INPUT,              NULL},
   {NULL,                  NULL,                                                       0,                                  NULL}
};

static struct dsUserInputLimitTable DS_Inputs_Limits[] = {
   {DS_USER_INPUT_READ_REG,            (int8_t *)"Read Reg.",        (float64_t)((2 ^ 32) - 1),     -(float64_t)((2 ^ 32) - 1)},
   {DS_USER_INPUT_WRITE_REG,           (int8_t *)"Write Reg.",       (float64_t)((2 ^ 32) - 1),     -(float64_t)((2 ^ 32) - 1)},
   {DS_USER_INPUT_SET_ANGLE,           (int8_t *)"Angle",            359.9954,                      0.0},
   {DS_USER_INPUT_SET_EXP_VLL,         (int8_t *)"Exp VLL",          115.0,                         0.0},
   {DS_USER_INPUT_SET_EXP_VREF,        (int8_t *)"Exp Vref",         115.0,                         0.0},
   {DS_USER_INPUT_SET_VLL_THRESHOLD,   (int8_t *)"VLL Threshold",    115.0,                         0.0},
   {DS_USER_INPUT_SET_VREF_THRESHOLD,  (int8_t *)"Vref Threshold",   115.0,                         0.0},
   {DS_USER_INPUT_FIX_RATIO_MODE,      (int8_t *)"Ratio/Fixed Mode", 1.0,                           0.0},
   {DS_USER_INPUT_CHAN_STATUS_ENABLE,  (int8_t *)"Active Channel",   1.0,                           0.0},
   {DS_USER_INPUT_POWER,               (int8_t *)"Set Power",        1.0,                           0.0},
   {DS_USER_INPUT_QUIT,                (int8_t *)"",                 0.0,                           0.0},
   {DS_USER_INVALID_INPUT,             (int8_t *)"",                 0.0,                           0.0},
   {DS_USER_INPUT_COUNT,               (int8_t *)"",                 0.0,                           0.0}
};

#if defined (__VXWORKS__)
int32_t DS_RunAngleProgramSample(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         /* Query the user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Query the user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  DS_RunAngleProgram(cardIndex, module, moduleID);
               }
            }
         }

         printf("\nType Q to quit or Enter key to restart application:\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

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

   return 0;
}

static void DS_RunAngleProgram(int32_t cardIndex, int32_t module, uint32_t moduleID)
{
   bool_t bQuit;
   int32_t channel = 0;
   int32_t MaxModule = 0;
   int32_t MaxChannel = 0;
   int32_t cmdIdx;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* Get the number of D/S channels on the module */
   moduleID = naibrd_GetModuleID(cardIndex, module);
   MaxChannel = naibrd_DS_GetChannelCount(moduleID);
   /*Show data*/
   do
   {
      Show_DSDemoFunc_Commands();
      printf("\nType DS command or %c to quit : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         for (cmdIdx = 0; cmdIdx < DS_FUNC_CMD_COUNT; cmdIdx++)
         {
            if (0 == naiapp_strnicmp((const int8_t*)inputBuffer, (const int8_t*)DS_DemoFuncMenuCmds[cmdIdx].cmdstr, inputResponseCnt))
               break;
         }
         switch (cmdIdx)
         {
         case DS_FUNC_CMD_SET_ANGLE:
            if ((module > 0) && (channel > 0))
               DS_RunAngleFunc(cardIndex, module, channel);
            break;

         case DS_FUNC_CMD_SET_MODULE:
            printf("\nEnter Module Number:\n");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            module = atoi((const char *)inputBuffer);
            if ((module < 1) || (module > MaxModule))
            {
               printf("\n%s: %d is outside the limits[%d - %d]", "Module #", module, 1, MaxModule);
            }
            break;

         case DS_FUNC_CMD_SET_CHANNEL:
            printf("\nEnter Channel Number:\n");
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            channel = atoi((const char *)inputBuffer);
            if ((channel < 1) || (channel > MaxChannel))
            {
               printf("\n%s: %d is outside the limits[%d - %d]", "Channel #", channel, 1, MaxChannel);
            }
            break;

         default:
            break;
         }
      }
   } while (bQuit == FALSE);
}

static void Show_DSDemoFunc_Commands(void)
{
   int i;
   printf("\n\t\t DS Set Angle Menu");
   printf("\n\t\t =================\n");
   printf("\n\nCommands");
   printf("\n--------");
   for (i = 0; i < DS_FUNC_CMD_COUNT && DS_DemoFuncMenuCmds[i].cmdstr != NULL; i++)
      printf("\n%s\t%s", DS_DemoFuncMenuCmds[i].cmdstr, DS_DemoFuncMenuCmds[i].menustr);
   printf("\n");
}

static void Show_SetAngle_UserInput_Commands(void)
{
   int i;

   printf("\n\t\t Set Angle User Inputs\n ");
   printf("\n\nCommands");
   for (i = 0; i < DS_USER_INPUT_COUNT && DS_DemoUserInputs[i].cmdstr != NULL; i++)
      printf("\n%s\t%s", DS_DemoUserInputs[i].cmdstr, DS_DemoUserInputs[i].menustr);
   printf("\n");
}

static void DS_RunAngleFunc(int32_t cardIndex, int32_t module, int32_t channel)
{
   uint32_t udUserInput;
   bool_t bYes = FALSE;

   printf("\n================================================================");
   printf("\nThis program allows the user to set the output angle of a       ");
   printf("\nspecified channel of a D/S module.  The user can change the     ");
   printf("\nfollowing module properties.                                     ");
   printf("\n1. Set Angle.");
   printf("\n2. Set Expected VLL");
   printf("\n3. Set Expected VREF");
   printf("\n4. Set VLL Threshold");
   printf("\n5. Set VREF Threshold");
   printf("\n6. Set Fixed/Ratio Mode");
   printf("\n7. Set Active Channel");
   printf("\n8. Set Module Power");
   printf("\n================================================================\n");

   do
   {
      DS_ShowSetAngleTestResult(cardIndex, module, channel);
      showCurrentModChan(module, channel);
      Show_SetAngle_UserInput_Commands();
      if (getUserInput() >= 0)
      {
         udUserInput = (uint32_t)getUserInput();
         switch (udUserInput)
         {
         case DS_USER_INPUT_READ_REG:
         case DS_USER_INPUT_WRITE_REG:
         case DS_USER_INPUT_SET_ANGLE:
         case DS_USER_INPUT_SET_EXP_VLL:
         case DS_USER_INPUT_SET_EXP_VREF:
         case DS_USER_INPUT_SET_VLL_THRESHOLD:
         case DS_USER_INPUT_SET_VREF_THRESHOLD:
         case DS_USER_INPUT_FIX_RATIO_MODE:
         case DS_USER_INPUT_CHAN_STATUS_ENABLE:
         case DS_USER_INPUT_POWER:
            DS_DemoUserInputs[udUserInput].func(cardIndex, module, channel);
            break;

         case DS_USER_INPUT_QUIT:
            bYes = TRUE;
            break;

         case DS_USER_INPUT_REFRESH:
         case DS_USER_INVALID_INPUT:
            break;
         }
      }
   } while (bYes == FALSE);
}

static void DS_ShowSetAngleTestResult(int32_t cardIndex, int32_t module, int32_t channel)
{
   float64_t dValue = 0.0;
   uint32_t  unValue = 0;
   uint8_t   u8Status[10];
   uint8_t   u8Value = 0;

   memset(u8Status, 0, sizeof(u8Status));
   printf("\nSet angle   Meas angle  VLL         VRef        Mode        Meas. VLL   Meas. VRef  Meas.RFreq  VLL.Thres   VREF.Thres  Multi-Spd   Status      Act.Chan.   Power     \n");
   printf("\n                                                                                                                          Ratio     S/R/B/P                             ");
   printf("\n----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ---------- \n");
   /*Set Angle*/
   check_status(naibrd_DS_GetAngle(cardIndex, module, channel, NAI_DS_ANGLE_SINGLE, &dValue));
   printf("%-12.4f", dValue);
   /*get measured angle*/
   check_status(naibrd_DS_GetMeasuredValue(cardIndex, module, channel, NAI_DS_MEASURED_ANGLE, &dValue));
   printf("%-12.4f", dValue);
   /*expected VLl */
   check_status(naibrd_DS_GetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_SIGNAL, &dValue));
   printf("%-12.4f", dValue);
   /*expected Vref */
   check_status(naibrd_DS_GetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_REFERENCE, &dValue));
   printf("%-12.4f", dValue);
   /*fixed/ratio mode */
   check_status(naibrd_DS_GetRatioFixedMode(cardIndex, module, channel, &unValue));
   if ((nai_ds_output_ratio_fixed_mode_t)unValue == NAI_DS_OUTPUT_RATIO)
      printf("%-12s", DS_RATIO);
   else
      printf("%-12s", DS_FIXED);
  /*measured Vll */
   check_status(naibrd_DS_GetMeasuredValue(cardIndex, module, channel, NAI_DS_MEASURED_SIGNAL_VOLTAGE, &dValue));
   printf("%-12.4f", dValue);
   /*measured Vref */
   check_status(naibrd_DS_GetMeasuredValue(cardIndex, module, channel, NAI_DS_MEASURED_REF_VOLTAGE, &dValue));
   printf("%-12.4f", dValue);
   /*measured RefFreq */
   check_status(naibrd_DS_GetMeasuredValue(cardIndex, module, channel, NAI_DS_MEASURED_REF_FREQUENCY, &dValue));
   printf("%-12.4f", dValue);
   /*Vll Threshold*/
   check_status(naibrd_DS_GetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_SIGNAL, &dValue));
   printf("%-12.4f", dValue);
   /*VREF Threshold*/
   check_status(naibrd_DS_GetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_REFERENCE, &dValue));
   printf("%-12.4f", dValue);
   /*Multi-Spd*/
   check_status(naibrd_DS_GetMultiSpeedRatio(cardIndex, module, NAI_DS_MULTI_SPD_CH1_2_PAIR, &unValue));
   printf("%-12d", unValue);
   /*get Status: S=Signal Loss, R=Reference Loss, B=BIT Loss, P=Phase Loss*/
   getStatus(cardIndex, module, channel, u8Status);
   printf("%-12s", u8Status);
   /*get Channel Status Enable (formly Active Channel))*/
   check_status(naibrd_DS_GetChanStatusEnable(cardIndex, module, channel, &unValue));
   if (unValue == NAI_ENABLE)
      printf("%-12s", DS_ENABLE);
   else
      printf("%-12s", DS_DISABLE);
   /*get power State*/
   check_status(naibrd_DS_GetPowerEnable(cardIndex, module, channel, &u8Value));
   if (u8Value == NAI_ENABLE)
      printf("%-12s", DS_ENABLE);
   else
      printf("%-12s", DS_DISABLE);
   printf("\n");
}

static void DS_SetNewAngle(int32_t cardIndex, int32_t module, int32_t channel)
{
   float64_t dValue = 0.0;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nEnter New Angle\n");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   dValue = atof((const char *)inputBuffer);
   bQuit = checkUserInput(DS_USER_INPUT_SET_ANGLE, dValue);
   if (bQuit == TRUE)
      printInvalidUserInputMessage(DS_USER_INPUT_SET_ANGLE, dValue);
   else
   {
      check_status(naibrd_DS_SetAngle(cardIndex, module, channel, NAI_DS_ANGLE_SINGLE, dValue));
   }
}

static void DS_SetExpVLL(int32_t cardIndex, int32_t module, int32_t channel)
{
   float64_t dValue = 0.0;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nEnter Expected D/S VLL\n");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   dValue = atof((const char *)inputBuffer);
   bQuit = checkUserInput(DS_USER_INPUT_SET_EXP_VLL, dValue);
   if (bQuit == TRUE)
      printInvalidUserInputMessage(DS_USER_INPUT_SET_EXP_VLL, dValue);
   else
   {
      check_status(naibrd_DS_SetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_SIGNAL, dValue));
   }
}

static void DS_SetExpVref(int32_t cardIndex, int32_t module, int32_t channel)
{
   float64_t dValue = 0.0;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nEnter Expected D/S VREF\n");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   dValue = atof((const char *)inputBuffer);
   bQuit = checkUserInput(DS_USER_INPUT_SET_EXP_VREF, dValue);
   if (bQuit == TRUE)
      printInvalidUserInputMessage(DS_USER_INPUT_SET_EXP_VREF, dValue);
   else
   {
      check_status(naibrd_DS_SetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_REFERENCE, dValue));
   }
}

static void DS_SetVllThrehold(int32_t cardIndex, int32_t module, int32_t channel)
{
   float64_t dValue = 0.0;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nEnter VLL THRESHOLD\n");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   dValue = atof((const char *)inputBuffer);
   bQuit = checkUserInput(DS_USER_INPUT_SET_VLL_THRESHOLD, dValue);
   if (bQuit == TRUE)
      printInvalidUserInputMessage(DS_USER_INPUT_SET_VLL_THRESHOLD, dValue);
   else
   {
      check_status(naibrd_DS_SetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_SIGNAL, dValue));
   }
}

static void DS_SetVrefThreshold(int32_t cardIndex, int32_t module, int32_t channel)
{
   float64_t dValue = 0.0;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nEnter VREF THRESHOLD\n");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   dValue = atof((const char *)inputBuffer);
   bQuit = checkUserInput(DS_USER_INPUT_SET_VREF_THRESHOLD, dValue);
   if (bQuit == TRUE)
      printInvalidUserInputMessage(DS_USER_INPUT_SET_VREF_THRESHOLD, dValue);
   else
   {
      check_status(naibrd_DS_SetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_REFERENCE, dValue));
   }
}

static void DS_SetFixedRatioMode(int32_t cardIndex, int32_t module, int32_t channel)
{
   uint32_t unValue = 0;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nEnter Fixed/Ratio Mode [Fixed = 1, Ratio = 0]\n");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   unValue = atoi((const char *)inputBuffer);
   bQuit = checkUserInput(DS_USER_INPUT_FIX_RATIO_MODE, unValue);
   if (bQuit == TRUE)
      printInvalidUserInputMessage(DS_USER_INPUT_FIX_RATIO_MODE, unValue);
   else
   {
      check_status(naibrd_DS_SetRatioFixedMode(cardIndex, module, channel, unValue));
   }
}

static void DS_SetChannelStatusCtrl(int32_t cardIndex, int32_t module, int32_t channel)
{
   uint32_t unValue = 0;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nSet Active Channel [Disable = 0, Enable = 1]\n");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   unValue = atoi((const char *)inputBuffer);
   bQuit = checkUserInput(DS_USER_INPUT_CHAN_STATUS_ENABLE, unValue);
   if (bQuit == TRUE)
      printInvalidUserInputMessage(DS_USER_INPUT_CHAN_STATUS_ENABLE, unValue);
   else
   {
      check_status(naibrd_DS_SetChanStatusEnable(cardIndex, module, channel, unValue));
   }
}

static void DS_SetPower(int32_t cardIndex, int32_t module, int32_t channel)
{
   float64_t dValue = 0;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nSet Power[DISABLE = 0, ENABLE = 1]\n");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   dValue = atof((const char *)inputBuffer);
   bQuit = checkUserInput(DS_USER_INPUT_POWER, dValue);
   if (bQuit == TRUE)
      printInvalidUserInputMessage(DS_USER_INPUT_POWER, dValue);
   else
   {
      check_status(naibrd_DS_SetPowerEnable(cardIndex, module, channel, (uint8_t)dValue));
   }
}

static int32_t getUserInput()
{
   uint32_t unCmdNumber = 0;
   int8_t str1[80];
   int8_t str2[80];
   int32_t dCommand = -1;
   int32_t x;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (inputResponseCnt > 0)
   {
      for (unCmdNumber = 0; unCmdNumber < DS_USER_INPUT_COUNT && DS_DemoUserInputs[unCmdNumber].cmdstr != NULL; unCmdNumber++)
      {
         memset(str1, 0, sizeof(str1));
         memset(str2, 0, sizeof(str2));
         strncpy((char*)str1, (const char*)DS_DemoUserInputs[unCmdNumber].cmdstr, inputResponseCnt);
         strncpy((char*)str2, (const char*)inputBuffer, inputResponseCnt);

         for (x = 0; x < inputResponseCnt; x++)
         {
            str1[x] = (int8_t)toupper(str1[x]);
            str2[x] = (int8_t)toupper(str2[x]);

         }
         if (strncmp((const char*)str1, (const char*)str2, inputResponseCnt) == 0)
         {
            dCommand = unCmdNumber;
            break;
         }
      }
   }
   return(dCommand);
}

static bool_t checkUserInput(uint32_t uTypeIdx, float64_t dUserInput)
{
   bool_t bValidInput = FALSE;

   if ((dUserInput > DS_Inputs_Limits[uTypeIdx].upperLimit) || (dUserInput < DS_Inputs_Limits[uTypeIdx].lowerLimit))
      bValidInput = TRUE;
   return(bValidInput);
}

static void printInvalidUserInputMessage(uint32_t uTypeIdx, float64_t dUserInput)
{
   printf("\n%s: %0.4f is outside the limits[%0.4f - %0.4f]", DS_Inputs_Limits[uTypeIdx].cmdstr, dUserInput, DS_Inputs_Limits[uTypeIdx].lowerLimit, DS_Inputs_Limits[uTypeIdx].upperLimit);
}

static void showCurrentModChan(int32_t nModule, int32_t nChannel)
{
   printf("\nModule  :%d", nModule);
   printf("\nChannel :%d", nChannel);
}

static void getStatus(int32_t cardIndex, int32_t module, int32_t channel, uint8_t *u8Status)
{
   uint32_t unSingalLoss = 0;
   uint32_t unRefLoss = 0;
   uint32_t unBitLoss = 0;
   uint32_t unPhaseLoss = 0;

   check_status(naibrd_DS_GetStatus(cardIndex, module, channel, NAI_DS_STATUS_REAL_TIME_SIGNAL_LOST, &unSingalLoss));
   check_status(naibrd_DS_GetStatus(cardIndex, module, channel, NAI_DS_STATUS_REAL_TIME_REFERENCE_LOST, &unRefLoss));
   check_status(naibrd_DS_GetStatus(cardIndex, module, channel, NAI_DS_STATUS_REAL_TIME_BIT_LOST, &unBitLoss));
   check_status(naibrd_DS_GetStatus(cardIndex, module, channel, NAI_DS_STATUS_REAL_TIME_PHASE_LOST, &unPhaseLoss));

   /*SIG*/
   if ((nai_ds_module_status_t)unSingalLoss == NAI_DS_MODULE_STATUS_GOOD)
      *u8Status++ = DS_STATUS_GOOD[0];
   else
      *u8Status++ = DS_STATUS_BAD[0];
   *u8Status++ = SYM_SLASH[0];

   /*REF*/
   if ((nai_ds_module_status_t)unRefLoss == NAI_DS_MODULE_STATUS_GOOD)
      *u8Status++ = DS_STATUS_GOOD[0];
   else
      *u8Status++ = DS_STATUS_BAD[0];
   *u8Status++ = SYM_SLASH[0];

   /*BIT*/
   if ((nai_ds_module_status_t)unBitLoss == NAI_DS_MODULE_STATUS_GOOD)
      *u8Status++ = DS_STATUS_GOOD[0];
   else
      *u8Status++ = DS_STATUS_BAD[0];
   *u8Status++ = SYM_SLASH[0];

   /*PLL*/
   if ((nai_ds_module_status_t)unPhaseLoss == NAI_DS_MODULE_STATUS_GOOD)
      *u8Status++ = DS_STATUS_GOOD[0];
   else
      *u8Status++ = DS_STATUS_BAD[0];
}

Help Bot

X