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

ENC SSI BasicOps

ENC SSI BasicOps

Explanation

About the Sample Code

This C application demonstrates interacting with North Atlantic Industries (NAI) embedded function modules using their System Support Kit (SSK). It focuses on controlling and reading data from encoder modules using SSI (Synchronous Serial Interface).

Code Overview

Header Files - Standard Libraries: Includes common standard libraries for functions such as stdio.h, stdlib.h, etc. - NAI Specific Libraries: Include files from NAI meant for board access, querying, display, and utility functions.

#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"

#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_enc.h"
#include "advanced/nai_ether_adv.h"

Static Variables and Constants - CONFIG_FILE: Configuration file path. - DEF_ENC_CHANNEL: Default encoder channel.

Enumerations - enc_ssi_basicops_commands: Defines command identifiers for various operations related to the encoder.

Function Prototypes List of functions used including their purpose: - Run_ENC_SSI_BasicOps: Runs basic operations for encoder modules. - Cfg_ENC_Channel: Configures encoder channel settings. - Display_ENC_SSIChannelCfg: Displays channel configuration for the encoder. - Display_ENC_SSIStatus: Displays the status of the encoder channel. - Various configure functions: Handle specific configuration aspects for SSI like input configuration, SSI mode, clock period, data bits, etc.

int32_t Run_ENC_SSI_BasicOps(int32_t cardIndex, int32_t module, int32_t ModuleID);
static void Cfg_ENC_Channel(int32_t cardIndex, int32_t module, int32_t MaxChannel);
static void Display_ENC_SSIChannelCfg(int32_t cardIndex, int32_t module, int32_t chan);
static nai_status_t Display_ENC_SSIStatus(int32_t paramCount, int32_t* p_params);
// ... other configuration functions

Main Function The main function serves as the entry point of the application: 1. Runs the menu using the CONFIG_FILE. 2. Queries the user for card and module information. 3. Calls Run_ENC_SSI_BasicOps to perform operations if inputs are valid. 4. Provides a loop to restart or quit the application.

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

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  Run_ENC_SSI_BasicOps(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;
}

Core Functions

Run_ENC_SSI_BasicOps This function handles configuring and running encoder module operations: 1. Retrieves the maximum channel count. 2. Checks if the module is recognized. 3. Calls Cfg_ENC_Channel to handle configuration for each channel.

int32_t Run_ENC_SSI_BasicOps(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
   int32_t MaxChannel;

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

Cfg_ENC_Channel Handles the configuration and display of encoder channel configuration: 1. Prompts the user to select a channel and displays configurations. 2. Displays a menu of commands and executes corresponding functions for each command. 3. Commands have an associated function to handle operations like setting input configuration, SSI mode, clock period, etc.

static void Cfg_ENC_Channel(int32_t cardIndex, int32_t module, int32_t MaxChannel)
{
   // code for handling channel configuration and user interface
}

Display Functions - Display_ENC_SSIChannelCfg: Retrieves and prints SSI data for the specified channel. - View_ENC_Config: Shows all configurable settings for the chosen encoder channel. - Display_ENC_SSIStatus: Displays the current SSI status including new data, overflow, parity errors, etc.

Configuration Functions These functions handle various specific configurations for the encoder module. Each function: 1. Prompts the user for specific configuration input. 2. Calls the appropriate naibrd library function to update settings based on user input.

Examples include: - Configure_ENC_InputConfig - Configure_ENC_SSIMode - Configure_ENC_SSIClockPeriod - Configure_ENC_SSIDataBits - Configure_ENC_SSIParity

Each function ensures proper fetching of input from the user and updating encoder settings as per the provided values.

Conclusion This sample application demonstrates how to use NAI’s SSK to interact with encoder modules for basic SSI operations. It guides the user through configuration steps and performs essential operations by interacting with the NAI library functions. The detailed user interaction and proper error handling ensure the application is user-friendly and robust.

#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_enc.h"
#include "advanced/nai_ether_adv.h"

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

/* Function prototypes */
int32_t Run_ENC_SSI_BasicOps(int32_t cardIndex, int32_t module, int32_t ModuleID);
static void Cfg_ENC_Channel(int32_t cardIndex, int32_t module, int32_t MaxChannel);

static void Display_ENC_SSIChannelCfg(int32_t cardIndex, int32_t module, int32_t chan);
static nai_status_t Display_ENC_SSIStatus(int32_t paramCount, int32_t* p_params);

static nai_status_t View_ENC_Config(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_ENC_InputConfig(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_ENC_SSIMode(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_ENC_SSIClockPeriod(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_ENC_SSIClockEdge(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_ENC_SSIDataBits(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_ENC_SSIParity(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_ENC_SSIParityEn(int32_t paramCount, int32_t* p_params);
static nai_status_t Configure_ENC_SSIZeroBitEn(int32_t paramCount, int32_t* p_params);

static const int32_t DEF_ENC_CHANNEL = 1;

/****** Command Table *******/
enum enc_ssi_basicops_commands
{
   ENC_SSI_BAISCOP_CMD_VIEW_CONFIG,
   ENC_SSI_BASICOP_CMD_INPUT_CONFIG,
   ENC_SSI_BASICOP_CMD_SETMODE,
   ENC_SSI_BASICOP_CMD_CLOCK_PERIOD,
   ENC_SSI_BASICOP_CMD_CLOCK_EDGE,
   ENC_SSI_BASICOP_CMD_DATABITS,
   ENC_SSI_BASICOP_CMD_PARITY,
   ENC_SSI_BASICOP_CMD_PARITY_EN,
   ENC_SSI_BASICOP_CMD_ZEROBIT_EN,
   ENC_SSI_BASICOP_CMD_TRIGGER_DATA,
   ENC_SSI_BASICOP_CMD_STATUS,
   ENC_SSI_BASICOP_CMD_COUNT
};

/****** Command Tables *******/
naiapp_cmdtbl_params_t ENC_SSI_BasicOpMenuCmds[] =
{
   {"V",     "View Current Config",        ENC_SSI_BAISCOP_CMD_VIEW_CONFIG,      View_ENC_Config},
   {"I",     "Set Input Configuration",    ENC_SSI_BASICOP_CMD_INPUT_CONFIG,     Configure_ENC_InputConfig},
   {"M",     "Set SSI Mode",               ENC_SSI_BASICOP_CMD_SETMODE,          Configure_ENC_SSIMode},
   {"C",     "Set SSI Clock Period",       ENC_SSI_BASICOP_CMD_CLOCK_PERIOD,     Configure_ENC_SSIClockPeriod},
   {"E",     "Set SSI Clock EdgeLevel",    ENC_SSI_BASICOP_CMD_CLOCK_EDGE,       Configure_ENC_SSIClockEdge},
   {"D",     "Set SSI DataBits",           ENC_SSI_BASICOP_CMD_DATABITS,         Configure_ENC_SSIDataBits},
   {"P",     "Set SSI Parity",             ENC_SSI_BASICOP_CMD_PARITY,           Configure_ENC_SSIParity},
   {"PC",    "Enable/Disable ParityCheck", ENC_SSI_BASICOP_CMD_PARITY_EN,        Configure_ENC_SSIParityEn},
   {"ZB",    "Enable/Disable ZeroBit",     ENC_SSI_BASICOP_CMD_ZEROBIT_EN,       Configure_ENC_SSIZeroBitEn},
   {"T",     "Trigger Data Transfer",      ENC_SSI_BASICOP_CMD_TRIGGER_DATA,     NULL},
   {"STAT",  "Display SSI Status",         ENC_SSI_BASICOP_CMD_STATUS,           Display_ENC_SSIStatus}
};

/**************************************************************************************************************/
/**
<summary>
The purpose of the ENC_SSI_BasicOps is to illustrate the methods to call in the naibrd library to perform basic
 SSI operations with the encoder modules for configuration setup, controlling the drive outputs, and reading
 SSI data.

The following system configuration routines from the nai_sys_cfg.c file are called to assist with the configuration
setup for this program prior to calling the naibrd ENC routines.
 - ClearDeviceCfg
 - QuerySystemCfg
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - SaveDeviceCfg
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t ENC_SSI_BasicOps(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

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

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

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

   return 0;
}

/**************************************************************************************************************/
/**
<summary>
Run_ENC_SSI_BasicOps prompts the user for the card, module and channel to use for the application and calls
Cfg_ENC_Channel if the card, module, channel is valid for as a discrete module.
</summary>
*/
/**************************************************************************************************************/
int32_t Run_ENC_SSI_BasicOps(int32_t cardIndex, int32_t module, int32_t ModuleID)
{
   int32_t MaxChannel;

   MaxChannel = naibrd_ENC_GetChannelCount(ModuleID);

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

/**************************************************************************************************************/
/**
<summary>
Cfg_ENC_Channel handles calling the Display_ENC_ChannelCfg routine to display the encoder channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
static void Cfg_ENC_Channel(int32_t cardIndex, int32_t module, int32_t MaxChannel)
{
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   bool_t bCmdFound = FALSE;
   int32_t defaultchan = 1;
   nai_status_t status = (nai_status_t)0;
   int32_t cmd;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   naiapp_AppParameters_t  enc_params;
   p_naiapp_AppParameters_t enc_ssi_params = &enc_params;
   enc_ssi_params->cardIndex = cardIndex;
   enc_ssi_params->module = module;
   enc_ssi_params->maxChannels = MaxChannel;

   while (bContinue)
   {
      printf("    \r\n\r\n");
      printf("Channel selection \r\n");
      printf("================= \r\n");
      defaultchan = DEF_ENC_CHANNEL;
      bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &enc_ssi_params->channel);

      naiapp_utils_LoadParamMenuCommands(ENC_SSI_BASICOP_CMD_COUNT, ENC_SSI_BasicOpMenuCmds);
      while (bContinue)
      {
         Display_ENC_SSIChannelCfg(cardIndex, module, enc_ssi_params->channel);
         naiapp_display_ParamMenuCommands((int8_t *)"ENC SSI Basic Operation Menu");
         printf("\nType ENC SSI command or %c to quit : ", NAI_QUIT_CHAR);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (!bQuit)
         {
            if (inputResponseCnt > 0)
            {
               bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
               if (bCmdFound)
               {
                  switch (cmd)
                  {
                     case ENC_SSI_BAISCOP_CMD_VIEW_CONFIG:
                     case ENC_SSI_BASICOP_CMD_INPUT_CONFIG:
                     case ENC_SSI_BASICOP_CMD_SETMODE:
                     case ENC_SSI_BASICOP_CMD_CLOCK_PERIOD:
                     case ENC_SSI_BASICOP_CMD_CLOCK_EDGE:
                     case ENC_SSI_BASICOP_CMD_DATABITS:
                     case ENC_SSI_BASICOP_CMD_PARITY:
                     case ENC_SSI_BASICOP_CMD_PARITY_EN:
                     case ENC_SSI_BASICOP_CMD_ZEROBIT_EN:
                     case ENC_SSI_BASICOP_CMD_STATUS:
                        ENC_SSI_BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)enc_ssi_params);
                        break;
                     case ENC_SSI_BASICOP_CMD_TRIGGER_DATA:
                        status = check_status(naibrd_ENC_SSI_TriggerData(cardIndex, module, enc_ssi_params->channel));
                        if (status == NAI_SUCCESS)
                        {
                           printf("Triggered SSI clock, SSI data refreshed. \n\n");
                        }
                        break;
                     default:
                        printf("Invalid command entered\n");
                        break;
                  }
               }
               else
                  printf("Invalid command entered\n");
            }
         }
         else
            bContinue = FALSE;
      }
   }
}

/**************************************************************************************************************/
/**
<summary>
Display_ENC_SSIChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for basic operation.
</summary>
*/
/**************************************************************************************************************/
static void Display_ENC_SSIChannelCfg(int32_t cardIndex, int32_t module, int32_t chan)
{
   uint32_t ssiData = 0u;
   uint32_t ssiGrayData = 0u;

   check_status(naibrd_ENC_GetSSI_Data(cardIndex, module, chan, &ssiData));
   check_status(naibrd_ENC_GetSSI_GreyData(cardIndex, module, chan, &ssiGrayData));

   printf("\n");
   printf("-----------------Data------------------\n");
   printf("    SSI Data:            0x%08x \n", ssiData);
   printf("    SSI Data GreyFormat: 0x%08x \n", ssiGrayData);
   printf("---------------------------------------\n");
}

/**************************************************************************************************************/
/**
<summary>
View_ENC_Config displays all menu configurable Encoder settings
</summary>
*/
/**************************************************************************************************************/
static nai_status_t View_ENC_Config(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   nai_enc_input_mode_t inputMode = 0;
   nai_enc_term_t termA = 0, termB = 0, termIndx = 0;
   nai_enc_ssi_mode_t ssiMode = 0;
   nai_enc_ioformat_t ioformatA = 0, ioformatB = 0, ioformatIndx = 0;
   nai_enc_ssi_clock_t clockEdge = 0;
   nai_enc_ssi_parity_t parity = 0;
   float64_t inputThreshold = 0;
   bool_t highVoltA = 0, highVoltB = 0, highVoltIndx = 0;
   bool_t parityEn = 0;
   bool_t zeroBitEn = 0;
   int32_t clockRate = 0;
   int32_t dataBits = 0;

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

   check_status(naibrd_ENC_GetInputMode(cardIndex, module, chan, &inputMode));
   check_status(naibrd_ENC_GetInputTermination(cardIndex, module, chan, NAI_ENC_PORT_A, &termA));
   check_status(naibrd_ENC_GetInputTermination(cardIndex, module, chan, NAI_ENC_PORT_B, &termB));
   check_status(naibrd_ENC_GetInputTermination(cardIndex, module, chan, NAI_ENC_PORT_Index, &termIndx));
   check_status(naibrd_ENC_GetInputThreshold(cardIndex, module, chan, &inputThreshold));
   check_status(naibrd_ENC_GetHighVoltEnable(cardIndex, module, chan, NAI_ENC_PORT_A, &highVoltA));
   check_status(naibrd_ENC_GetHighVoltEnable(cardIndex, module, chan, NAI_ENC_PORT_B, &highVoltB));
   check_status(naibrd_ENC_GetHighVoltEnable(cardIndex, module, chan, NAI_ENC_PORT_Index, &highVoltIndx));

   check_status(naibrd_ENC_GetSSI_Mode(cardIndex, module, chan, &ssiMode));
   check_status(naibrd_ENC_GetIOFormat(cardIndex, module, chan, NAI_ENC_PORT_A, &ioformatA));
   check_status(naibrd_ENC_GetIOFormat(cardIndex, module, chan, NAI_ENC_PORT_B, &ioformatB));
   check_status(naibrd_ENC_GetIOFormat(cardIndex, module, chan, NAI_ENC_PORT_Index, &ioformatIndx));
   check_status(naibrd_ENC_GetSSI_ClockRate(cardIndex, module, chan, &clockRate));
   check_status(naibrd_ENC_GetSSI_ClockEdgeLevel(cardIndex, module, chan, &clockEdge));
   check_status(naibrd_ENC_GetSSI_DataBits(cardIndex, module, chan, &dataBits));
   check_status(naibrd_ENC_GetSSI_Parity(cardIndex, module, chan, &parity));
   check_status(naibrd_ENC_GetSSI_ParityEnable(cardIndex, module, chan, &parityEn));
   check_status(naibrd_ENC_GetSSI_ZeroBitEnable(cardIndex, module, chan, &zeroBitEn));

   printf("\n === Channel %d Configuration ===\n\n", chan);
   printf("InputMode:                   %s\n", inputMode ? "Single-Ended" : "Differential");
   printf("InputTermination PortA:      %s\n", termA ? "Terminated" : "Non-Terminated");
   printf("InputTermination PortB:      %s\n", termB ? "Terminated" : "Non-Terminated");
   printf("InputTermination PortIndx:   %s\n", termIndx ? "Terminated" : "Non-Terminated");
   printf("InputThreshold(V):           %.7f\n", inputThreshold);
   printf("HighVoltage Mode PortA:      %s\n", highVoltA ? "Enabled" : "Disabled");
   printf("HighVoltage Mode PortB:      %s\n", highVoltB ? "Enabled" : "Disabled");
   printf("HighVoltage Mode PortIndx:   %s\n", highVoltIndx ? "Enabled" : "Disabled");
   printf("\n\n");

   printf("SSI Mode:                    %s\n", ssiMode ? "Listener" : "Interface Controller");
   printf("IOFormat PortA:              %s\n", ioformatA ? "Output" : "Input");
   printf("IOFormat PortB:              %s\n", ioformatB ? "Output" : "Input");
   printf("IOFormat PortIndx:           %s\n", ioformatIndx ? "Output" : "Input");
   printf("ClockPeriod(uS):             %i\n", clockRate);
   printf("ClockEdgeLevel:              %s\n", clockEdge ? "Falling" : "Rising");
   printf("DataBits:                    %i\n", dataBits);
   printf("Parity:                      %s\n", parity ? "Odd" : "Even");
   printf("Parity Check:                %s\n", parityEn ? "Enabled" : "Disabled");
   printf("ZeroBit:                     %s\n", zeroBitEn ? "Enabled" : "Disabled");

   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_ENC_InputConfig handles the user request to configure input mode, input threshold, termination and
high voltage mode for the selected channel.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_ENC_InputConfig(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   bool_t bQuit = FALSE;
   bool_t bUpdateMode = FALSE, bUpdateThreshold = FALSE, bUpdateTerm = FALSE, bUpdateHighVolt = FALSE;
   nai_enc_input_mode_t inputMode = NAI_ENC_INPUT_DIFFERENTIAL;
   nai_enc_term_t termination = NAI_ENC_NOT_TERMINATED;
   float64_t inputThreshold = 0;
   bool_t highVoltageEn = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   /* Set the input mode on channel. */
   printf("\nType the desired Input Mode: ");
   printf("'D'=Differential, 'S'=Single Ended, 'X'=Skip): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         switch (toupper(inputBuffer[0]))
         {
            case 'D':
               inputMode = NAI_ENC_INPUT_DIFFERENTIAL;
               bUpdateMode = TRUE;
               break;
            case 'S':
               inputMode = NAI_ENC_INPUT_SINGLE_ENDED;
               bUpdateMode = TRUE;
               break;
            case 'X':
               break;
            default:
               printf("ERROR: Invalid input mode entry\n");
               break;
         }
      }
   }

   /* Set the termination type on channel. */
   printf("\nType the desired Termination: ");
   printf("'T'=Terminated, 'N'=Non-Terminated, 'X'=Skip): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         switch (toupper(inputBuffer[0]))
         {
            case 'T':
               termination = NAI_ENC_TERMINATED;
               bUpdateTerm = TRUE;
               break;
            case 'N':
               termination = NAI_ENC_NOT_TERMINATED;
               bUpdateTerm = TRUE;
               break;
            case 'X':
               break;
            default:
               printf("ERROR: Invalid termination entry\n");
               break;
         }
      }
   }

   /* Set the input threshold voltage on channel. */
   printf("\nEnter the desired input threshold voltage (0-3.75)V, 'X'=Skip: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         if (toupper(inputBuffer[0]) == 'X')
         {
            bUpdateThreshold = FALSE;
         }
         inputThreshold = atof((const char *)inputBuffer);
         bUpdateThreshold = TRUE;
      }
   }

   /* Enable/Disable high voltage mode on channel. */
   printf("\nType the desired input to enable/disable parity checking: ");
   printf("'E'=Enable, 'D'=Disable, 'X'=Skip): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         switch (toupper(inputBuffer[0]))
         {
            case 'E':
               highVoltageEn = TRUE;
               bUpdateHighVolt = TRUE;
               break;
            case 'D':
               highVoltageEn = FALSE;
               bUpdateHighVolt = TRUE;
               break;
            case 'X':
               break;
            default:
               printf("ERROR: Invalid entry\n");
               break;
         }
      }
   }

   if (!bQuit)
   {
      if (bUpdateMode)
      {
         check_status(naibrd_ENC_SetInputMode(cardIndex, module, chan, inputMode));
      }
      if (bUpdateTerm)
      {
         check_status(naibrd_ENC_SetInputTermination(cardIndex, module, chan, NAI_ENC_PORT_A, termination));
         check_status(naibrd_ENC_SetInputTermination(cardIndex, module, chan, NAI_ENC_PORT_B, termination));
         check_status(naibrd_ENC_SetInputTermination(cardIndex, module, chan, NAI_ENC_PORT_Index, termination));
      }
      if (bUpdateThreshold)
      {
         check_status(naibrd_ENC_SetInputThreshold(cardIndex, module, chan, inputThreshold));
      }
      if (bUpdateHighVolt)
      {
         check_status(naibrd_ENC_SetHighVoltEnable(cardIndex, module, chan, NAI_ENC_PORT_A, highVoltageEn));
         check_status(naibrd_ENC_SetHighVoltEnable(cardIndex, module, chan, NAI_ENC_PORT_B, highVoltageEn));
         check_status(naibrd_ENC_SetHighVoltEnable(cardIndex, module, chan, NAI_ENC_PORT_Index, highVoltageEn));
      }
   }
   return NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_ENC_SSIMode handles the user request to configure the SSI mode for the selected channel and calls
the method in the naibrd library to set the SSI mode. SSI input/output pins are also configured based on the
SSI mode requested. Common control mode is also set to SSI upon selecting an SSI mode.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_ENC_SSIMode(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   bool_t bQuit = FALSE;
   bool_t bUpdateMode = FALSE;
   nai_enc_ssi_mode_t mode = NAI_ENC_SSI_CONTROLLER;
   nai_enc_ioformat_t portAFormat = NAI_ENC_IOFORMAT_OUTPUT;
   nai_enc_ioformat_t portBFormat = NAI_ENC_IOFORMAT_INPUT;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   /* Set the SSI mode (Interface controller or Listener) on channel. */
   printf("\nType the desired SSI mode ");
   printf("'C'=SSI Interface Controller, 'L'=SSI Listener): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         switch (toupper(inputBuffer[0]))
         {
            case 'C':
               mode = NAI_ENC_SSI_CONTROLLER;
               portAFormat = NAI_ENC_IOFORMAT_OUTPUT; /*Clock*/
               portBFormat = NAI_ENC_IOFORMAT_INPUT;  /*Data*/
               bUpdateMode = TRUE;
               break;
            case 'L':
               mode = NAI_ENC_SSI_LISTENER;
               portAFormat = NAI_ENC_IOFORMAT_INPUT; /*Clock*/
               portBFormat = NAI_ENC_IOFORMAT_INPUT; /*Data*/
               bUpdateMode = TRUE;
               break;
            default:
               printf("ERROR: Invalid SSI mode Entry\n");
               break;
         }
      }
   }
   if (!bQuit)
   {
      if (bUpdateMode)
      {
         check_status(naibrd_ENC_SetControlMode(cardIndex, module, chan, NAI_ENC_MODE_SSI));
         check_status(naibrd_ENC_SetSSI_Mode(cardIndex, module, chan, mode));
         check_status(naibrd_ENC_SetIOFormat(cardIndex, module, chan, NAI_ENC_PORT_A, portAFormat));
         check_status(naibrd_ENC_SetIOFormat(cardIndex, module, chan, NAI_ENC_PORT_B, portBFormat));
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Display_ENC_SSIStatus illustrates the methods to call in the naibrd library to retrieve the SSI status states.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Display_ENC_SSIStatus(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   nai_status_bit_t status;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   /* Available status:
         NAI_ENC_SSI_STATUS_NEWDATA
         NAI_ENC_SSI_STATUS_OVERFLOW
         NAI_ENC_SSI_STATUS_PARITY_ERROR
         NAI_ENC_SSI_STATUS_BUSY
         NAI_ENC_SSI_STATUS_WATCHDOG_ERROR
         NAI_ENC_SSI_STATUS_EXTRA
   */
   printf("\n");
   printf(" -------------------------- Status ------------------------------\n");
   printf("  NewData    Overflow   ParityErr    Busy    WatchDogErr  Extra\n");
   printf(" ---------- ---------- ---------- ---------- ---------- ---------\n");

   check_status(naibrd_ENC_GetSSI_Status(cardIndex, module, chan, NAI_ENC_SSI_STATUS_NEWDATA, &status));
   printf("   %3i    ", status);
   check_status(naibrd_ENC_GetSSI_Status(cardIndex, module, chan, NAI_ENC_SSI_STATUS_OVERFLOW, &status));
   printf("    %3i    ", status);
   check_status(naibrd_ENC_GetSSI_Status(cardIndex, module, chan, NAI_ENC_SSI_STATUS_PARITY_ERROR, &status));
   printf("    %3i    ", status);
   check_status(naibrd_ENC_GetSSI_Status(cardIndex, module, chan, NAI_ENC_SSI_STATUS_BUSY, &status));
   printf("    %3i    ", status);
   check_status(naibrd_ENC_GetSSI_Status(cardIndex, module, chan, NAI_ENC_SSI_STATUS_WATCHDOG_ERROR, &status));
   printf("    %3i    ", status);
   check_status(naibrd_ENC_GetSSI_Status(cardIndex, module, chan, NAI_ENC_SSI_STATUS_EXTRA, &status));
   printf("    %3i    ", status);
   printf("\n\n");

   return NAI_ERROR_UNKNOWN;
}

/**************************************************************************************************************/
/**
<summary>
Configure_ENC_SSIClockPeriod handles the user request to configure the SSI clock period for the selected channel
and calls the method in the naibrd library to set the SSI clock period. Clock period is configurable from
range of 1 to 32 in steps of 1uS.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_ENC_SSIClockPeriod(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   bool_t bQuit = FALSE;
   bool_t bUpdatePeriod = FALSE;
   int32_t clockRate = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   /* Set the SSI clock period on channel. */
   printf("\nEnter the desired clock period (1-32)uS:  ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         clockRate = atoi((const char *)inputBuffer);
         bUpdatePeriod = TRUE;
      }
   }
   if (!bQuit)
   {
      if (bUpdatePeriod)
      {
         check_status(naibrd_ENC_SetSSI_ClockRate(cardIndex, module, chan, clockRate));
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_ENC_SSIClockEdge handles the user request to configure the SSI clock edge for the selected channel
and calls the method in the naibrd library to set the SSI clock edge. Clock edge level determines whether
SSI data is clocked on rising or falling edge.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_ENC_SSIClockEdge(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   bool_t bQuit = FALSE;
   bool_t bUpdateClockEdge = FALSE;
   nai_enc_ssi_clock_t clockEdgeLvl = NAI_ENC_SSI_CLOCK_RISING;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   /* Set the SSI clock edge level on channel. */
   printf("\nType the desired edge level to clock SSI data on: ");
   printf("'R'=Rising Edge, 'F'=Falling Edge): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         switch (toupper(inputBuffer[0]))
         {
            case 'R':
               clockEdgeLvl = NAI_ENC_SSI_CLOCK_RISING;
               bUpdateClockEdge = TRUE;
               break;
            case 'F':
               clockEdgeLvl = NAI_ENC_SSI_CLOCK_FALLING;
               bUpdateClockEdge = TRUE;
               break;
            default:
               printf("ERROR: Invalid SSI clock edge entry\n");
               break;
         }
      }
   }
   if (!bQuit)
   {
      if (bUpdateClockEdge)
      {
         check_status(naibrd_ENC_SetSSI_ClockEdgeLevel(cardIndex, module, chan, clockEdgeLvl));
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_ENC_SSIDataBits handles the user request to configure the number of SSI data bits for the selected
channel and calls the method in the naibrd library to set the number of SSI data bits. DataBits correspond to
expected data width are configurable from 1 to 31.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_ENC_SSIDataBits(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   bool_t bQuit = FALSE;
   bool_t bUpdatePeriod = FALSE;
   int32_t dataBits = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   /* Set the SSI data bits on channel. */
   printf("\nEnter the expected number of data bits (1-31):  ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         dataBits = atoi((const char *)inputBuffer);
         bUpdatePeriod = TRUE;
      }
   }
   if (!bQuit)
   {
      if (bUpdatePeriod)
      {
         check_status(naibrd_ENC_SetSSI_DataBits(cardIndex, module, chan, dataBits));
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_ENC_SSIParity handles the user request to configure the SSI parity for the selected channel
and calls the method in the naibrd library to set the SSI parity. Parity can be configured as even or odd.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_ENC_SSIParity(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   bool_t bQuit = FALSE;
   bool_t bUpdateParity = FALSE;
   nai_enc_ssi_parity_t parity = NAI_ENC_SSI_PARITY_EVEN;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   /* Set the SSI clock edge level on channel. */
   printf("\nType the desired SSI parity: ");
   printf("'E'=Even, 'O'=Odd): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         switch (toupper(inputBuffer[0]))
         {
            case 'E':
               parity = NAI_ENC_SSI_PARITY_EVEN;
               bUpdateParity = TRUE;
               break;
            case 'O':
               parity = NAI_ENC_SSI_PARITY_ODD;;
               bUpdateParity = TRUE;
               break;
            default:
               printf("ERROR: Invalid SSI parity entry\n");
               break;
         }
      }
   }
   if (!bQuit)
   {
      if (bUpdateParity)
      {
         check_status(naibrd_ENC_SetSSI_Parity(cardIndex, module, chan, parity));
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_ENC_SSIParityEn handles the user request to enable/disable the SSI parity check for the selected
channel and calls the method in the naibrd library to enable/disable the SSI parity check.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_ENC_SSIParityEn(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   bool_t bQuit = FALSE;
   bool_t bUpdateParityEn = FALSE;
   bool_t enable = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   /* Set the SSI clock edge level on channel. */
   printf("\nType the desired input to enable/disable parity checking: ");
   printf("'E'=Enable, 'D'=Disable): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         switch (toupper(inputBuffer[0]))
         {
            case 'E':
               enable = TRUE;
               bUpdateParityEn = TRUE;
               break;
            case 'D':
               enable = FALSE;
               bUpdateParityEn = TRUE;
               break;
            default:
               printf("ERROR: Invalid entry\n");
               break;
         }
      }
   }
   if (!bQuit)
   {
      if (bUpdateParityEn)
      {
         check_status(naibrd_ENC_SetSSI_ParityEnable(cardIndex, module, chan, enable));
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
Configure_ENC_SSIZeroBitEn handles the user request to enable/disable the SSI zero bit for the selected
channel and calls the method in the naibrd library to enable/disable the SSI zero bit.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t Configure_ENC_SSIZeroBitEn(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_enc_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_enc_params->cardIndex;
   int32_t module = p_enc_params->module;
   int32_t chan = p_enc_params->channel;
   bool_t bQuit = FALSE;
   bool_t bUpdateZeroBitEn = FALSE;
   bool_t enable = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   /* Set the SSI clock edge level on channel. */
   printf("\nType the desired input to enable/disable zero bit: ");
   printf("'E'=Enable, 'D'=Disable): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         switch (toupper(inputBuffer[0]))
         {
            case 'E':
               enable = TRUE;
               bUpdateZeroBitEn = TRUE;
               break;
            case 'D':
               enable = FALSE;
               bUpdateZeroBitEn = TRUE;
               break;
            default:
               printf("ERROR: Invalid entry\n");
               break;
         }
      }
   }
   if (!bQuit)
   {
      if (bUpdateZeroBitEn)
      {
         check_status(naibrd_ENC_SetSSI_ZeroBitEnable(cardIndex, module, chan, enable));
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

Help Bot

X