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 MultiSpd

DS MultiSpd Sample Application (SSK 1.x)

Overview

The DS MultiSpd sample application demonstrates how to configure multi-speed (two-speed) operation on synchro/resolver (D/S) modules using the NAI Software Support Kit (SSK 1.x). Multi-speed operation pairs a coarse channel and a fine channel on the same module to achieve higher angular resolution than a single channel alone. The coarse channel resolves the full 360-degree range, while the fine channel resolves a subdivided portion based on the speed ratio — for example, a ratio of 36 means the fine channel completes 36 full revolutions for every one revolution of the coarse channel.

This sample covers: setting the multi-speed ratio, programming two-speed angles, configuring expected voltages and thresholds, selecting fixed/ratio output mode, and controlling channel power.

This sample supports DS module types that have multi-speed capability (see the DS1-DSN Manual for module variants and multi-speed 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 that supports multi-speed operation.

  • 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_MultiSpd executable from your build output directory. On startup the application looks for a configuration file (default_DsMultiSpd.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 then enter the multi-speed command 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_DsMultiSpd.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().

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

   if (naiapp_RunBoardMenu(CONFIG_FILE) == (bool_t)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)
               DS_RunAngleProgram(cardIndex, module, moduleCnt);
            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_RunMultSpdProgramSample() — the SSK 1.x build system selects the correct variant via a preprocessor guard:

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

Command Loop

The multi-speed sample defaults to channel 1 (the coarse channel). The top-level menu provides module selection and the RM command enters the multi-speed submenu:

Command Description

RM

Enter the multi-speed control submenu

M

Select module

Within the multi-speed submenu:

Command Description

ANG

Set multi-speed angle (two-speed)

VLL

Set expected signal voltage

VREF

Set expected reference voltage

VLLTH

Set VLL threshold voltage

REFTH

Set VRef threshold voltage

MODE

Set fixed/ratio output mode

MULTSPD

Set multi-speed ratio

PWR

Set power enable/disable

UPDATE

Refresh the status display

The menu-driven structure is a convenience of the sample application. In your own code, call the underlying API functions directly.

Multi-Speed Configuration

Set Multi-Speed Ratio

The multi-speed ratio defines the relationship between the coarse and fine channels. If the ratio is 36, the fine channel completes 36 electrical revolutions for each mechanical revolution of the coarse channel. To set this ratio in your own application:

uint32_t ratio = 36;
check_status(naibrd_DS_SetMultiSpeedRatio(cardIndex, module, NAI_DS_MULTI_SPD_CH1_2_PAIR, ratio));
  • cardIndex — identifies the board.

  • module — the slot containing the DS module.

  • NAI_DS_MULTI_SPD_CH1_2_PAIR — selects the channel 1/2 pair for multi-speed operation. Channel 1 is coarse, channel 2 is fine.

  • ratio — the speed ratio between coarse and fine channels (1 to 255). Consult the DS1-DSN Manual for supported ratio values on your module.

Note
The ratio must be set before programming a two-speed angle. The API uses the ratio to compute the correct fine channel angle from the requested coarse angle.

Set Two-Speed Angle

In multi-speed mode, the angle is set using NAI_DS_ANGLE_TWO_SPEED instead of NAI_DS_ANGLE_SINGLE. The API computes and distributes the appropriate coarse and fine angles based on the configured multi-speed ratio:

float64_t angle = 123.456;
uint32_t coarseChannel = 1;
check_status(naibrd_DS_SetAngle(cardIndex, module, coarseChannel, NAI_DS_ANGLE_TWO_SPEED, angle));
  • cardIndex — identifies the board.

  • module — the slot containing the DS module.

  • coarseChannel — the coarse channel number (channel 1). The fine channel (channel 2) is set automatically by the API based on the multi-speed ratio.

  • NAI_DS_ANGLE_TWO_SPEED — specifies two-speed angle mode.

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

Set Expected Voltages and Thresholds

These calls are identical to the single-speed case. They configure the expected signal and reference voltages and the loss detection thresholds for the specified channel:

/* Set expected signal voltage */
check_status(naibrd_DS_SetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_SIGNAL, expectedVLL));

/* Set expected reference voltage */
check_status(naibrd_DS_SetExpectedVoltage(cardIndex, module, channel, NAI_DS_EXP_VOLT_REFERENCE, expectedVRef));

/* Set signal voltage loss threshold */
check_status(naibrd_DS_SetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_SIGNAL, vllThreshold));

/* Set reference voltage loss threshold */
check_status(naibrd_DS_SetThresholdVoltage(cardIndex, module, channel, NAI_DS_THRESHOLD_VOLT_REFERENCE, vrefThreshold));
  • Voltage and threshold values range from 0.0 to 115.0 V. Consult the DS1-DSN Manual for module-specific limits.

Set Fixed/Ratio Mode

/* 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));

Set Power Enable

check_status(naibrd_DS_SetPowerEnable(cardIndex, module, channel, (uint8_t)NAI_ENABLE));
check_status(naibrd_DS_SetPowerEnable(cardIndex, module, channel, (uint8_t)NAI_DISABLE));
Important

Common Errors

  • Multi-speed ratio out of range — The ratio must be between 1 and 255.

  • NAI_ERROR_NOT_SUPPORTED — The module does not support multi-speed operation or the selected channel pair is not valid for multi-speed.

  • Coarse and fine angles do not correlate — The multi-speed ratio must be set before programming a two-speed angle. If you set the angle first and then change the ratio, the coarse and fine angles will be inconsistent.

  • Fine channel reads unexpected angle — Verify that the ratio was configured before the angle was written. The API computes the fine angle from the coarse angle and the ratio at the time naibrd_DS_SetAngle() is called.

Reading Multi-Speed Status

The sample displays both coarse (channel 1) and fine (channel 2) measured angles alongside the set angle, multi-speed ratio, expected voltages, measured voltages, thresholds, and power state via DS_ShowSetAngleTestResult(). To read these values in your own application:

float64_t setAngle, coarseAngle, fineAngle;
uint32_t multiSpdRatio;
uint32_t coarseChannel = 1;
uint32_t fineChannel = 2;

/* Read the programmed two-speed angle */
naibrd_DS_GetAngle(cardIndex, module, coarseChannel, NAI_DS_ANGLE_TWO_SPEED, &setAngle);

/* Read measured coarse angle (channel 1) */
naibrd_DS_GetMeasuredValue(cardIndex, module, coarseChannel, NAI_DS_MEASURED_ANGLE, &coarseAngle);

/* Read measured fine angle (channel 2) */
naibrd_DS_GetMeasuredValue(cardIndex, module, fineChannel, NAI_DS_MEASURED_ANGLE, &fineAngle);

/* Read multi-speed ratio */
naibrd_DS_GetMultiSpeedRatio(cardIndex, module, NAI_DS_MULTI_SPD_CH1_2_PAIR, &multiSpdRatio);
  • setAngle — the programmed two-speed angle (the value you passed to naibrd_DS_SetAngle()).

  • coarseAngle — the measured angle from the coarse channel. This reflects the full 360-degree position.

  • fineAngle — the measured angle from the fine channel. This resolves a fraction of the full revolution based on the multi-speed ratio.

  • multiSpdRatio — the configured speed ratio.

The remaining read-back calls for voltages, thresholds, and power state are the same as in the single-speed samples:

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_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_GetRatioFixedMode(cardIndex, module, channel, &ratioFixed);
naibrd_DS_GetPowerEnable(cardIndex, module, channel, &powerState);

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_DsMultiSpd.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

Multi-speed ratio rejected

Value outside the 1-255 range

Use a valid ratio value

NAI_ERROR_NOT_SUPPORTED

Module does not support multi-speed or channel pair not valid

Verify that your DS module supports multi-speed operation

Fine angle reads incorrectly

Ratio not set before programming the angle

Always set the ratio first with naibrd_DS_SetMultiSpeedRatio(), then set the angle

Measured angles both zero

Channel not powered

Enable power on the channel before reading

Voltage or threshold out of range

Value exceeds the 0.0-115.0 V limit

Use values within the supported range

Full Source

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

Full Source — DS_MultiSpd.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_DsMultiSpd.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, int32_t maxModule);
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_SetMultiSpd(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 uint32_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_COUNT
};
/****** User Input Table *******/
enum dsfunc_userInputs
{
   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_MULT_SPD,
   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 *)"RM",  (int8_t *)"Run Multi-speed",      DS_FUNC_CMD_SET_ANGLE,    DS_RunAngleFunc},\
   {(int8_t *)"M ",  (int8_t *)"Select Module",        DS_FUNC_CMD_SET_MODULE,   NULL},\
    {NULL,            NULL,                            0,                        NULL}
};

/****** User Input Command Tables *******/
static struct dsdemofunc_cmdtbl DS_DemoUserInputs[] =  {
   {(int8_t *)"ANG    ",             (int8_t *)"Set Multi-speed 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 *)"MULTSPD",            (int8_t *)"Set Mulit Speed Ratio",         DS_USER_INPUT_MULT_SPD,             DS_SetMultiSpd},
    {(int8_t *)"PWR    ",            (int8_t *)"Set Power",                     DS_USER_INPUT_POWER,                DS_SetPower},
    {(int8_t *)"UPDATE ",            (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_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_MULT_SPD,            (int8_t *)"Multi Speed",        255.0,      1.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_RunMultSpdProgramSample(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t moduleCnt;
   int32_t cardIndex;
   int32_t module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == (bool_t)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));
            /* Select Module */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               DS_RunAngleProgram(cardIndex, module, moduleCnt);
            }
            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, int32_t maxModule)
{
   bool_t bQuit;
   int32_t channel = 0;
   int32_t cmdIdx;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   channel = 1;

   /*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)
               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;

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

static void Show_DSDemoFunc_Commands(void)
{
   int i;
   printf("\n\t\t DS Set Multi Speed 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_MultiSpd_UserInput_Commands(void)
{
   int i;

   printf("\n\t\t Multi-Speed 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 multi-speed ratio in    ");
    printf("\na D/S module.  It also reports back its measured coarse and     ");
    printf("\nfine angle of the channel.  The following D/S properties can    ");
    printf("\nbe changed by the upser:                                        ");
    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 Mulit-speed ratio");
    printf("\n8. Set Module Power");
    printf("\n================================================================\n");

    do
    {
        DS_ShowSetAngleTestResult(cardIndex, module, channel);
        showCurrentModChan(module, channel);
        Show_MultiSpd_UserInput_Commands();
        udUserInput = getUserInput();
        switch(udUserInput)
        {
            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_MULT_SPD:
            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;
    uint32_t  unCoarseChan = 1;
    uint32_t  unFineChan = 2;

    memset(u8Status, 0, sizeof(u8Status));
    printf("\nSet angle   Meas angle  Meas angle  Multi Spd   VLL         VRef        Mode        Meas. VLL   Meas. VRef  Meas.RFreq  VLL.Thres   VREF.Thres  Power      \n");
    printf("\n             (coarse)     (fine)     ratio                                                                                                                   ");
   printf("\n----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ---------- \n");
    /*Set Angle*/
   check_status( naibrd_DS_GetAngle(cardIndex, module, unCoarseChan, NAI_DS_ANGLE_TWO_SPEED, &dValue ) );
   printf("%-12.4f",dValue);
    /*get measured coarse angle Ch1*/
    check_status( naibrd_DS_GetMeasuredValue( cardIndex, module, unCoarseChan, NAI_DS_MEASURED_ANGLE, &dValue) );
    printf("%-12.4f",dValue);
    /*get measured fine angle Ch2*/
    check_status( naibrd_DS_GetMeasuredValue( cardIndex, module, unFineChan, NAI_DS_MEASURED_ANGLE, &dValue) );
    printf("%-12.4f",dValue);
    /*get multi-speed ratio*/
    check_status( naibrd_DS_GetMultiSpeedRatio( cardIndex, module, NAI_DS_MULTI_SPD_CH1_2_PAIR, &unValue) );
    printf("%-12d",unValue);
    /*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);
    /*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;
    uint32_t  unCoarseChan = 1;
    int8_t inputBuffer[80];
    int32_t inputResponseCnt;

    channel = unCoarseChan;
    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, unCoarseChan, NAI_DS_ANGLE_TWO_SPEED, 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_SetMultiSpd(int32_t cardIndex, int32_t module, int32_t channel)
{
    uint32_t unValue = 0;
    bool_t bQuit = FALSE;
    int8_t inputBuffer[80];
    int32_t inputResponseCnt;

    channel = 0;
    printf("\nSet Multi Speed Ratio [1-255]\n");
    bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
    unValue = atoi((const char *)inputBuffer);
    bQuit = checkUserInput(DS_USER_INPUT_MULT_SPD, unValue);
    if(bQuit == TRUE)
        printInvalidUserInputMessage(DS_USER_INPUT_MULT_SPD, unValue);
    else
    {
        check_status( naibrd_DS_SetMultiSpeedRatio(cardIndex, module, NAI_DS_MULTI_SPD_CH1_2_PAIR, (uint32_t)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 uint32_t getUserInput()
{
    uint32_t unCmdNumber=0;
    int8_t str1[80];
    int8_t str2[80];
    uint32_t udCommand=0;
    int32_t x;
    int8_t inputBuffer[80];
    int32_t inputResponseCnt;

    naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
    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)
            {
                udCommand = unCmdNumber;
                break;
            }
        }
    return(udCommand);
}

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)
{
    nChannel = 1;
    printf("\nModule  :%d", nModule);
    printf("\nChannel :%d", nChannel);
}

Help Bot

X