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

LL2 BasicOps

LL2 BasicOps Sample Application (SSK 2.x)

Overview

The LL2 BasicOps sample application demonstrates how to perform basic LVDT (Linear Variable Differential Transformer) operations on the LL2 module using the NAI Software Support Kit (SSK 2.x). It illustrates configuration setup, DLV (Digital-to-LVDT) command data management, LVD (LVDT-to-Digital) data retrieval, CRC validation, and update rate configuration. This sample provides a practical API reference for integrating LL2 module control into your own applications.

The LL2 module supports dual-channel LVDT position control with features including configurable bandwidth, reference fault thresholds, transformation ratios, and CRC error detection. The sample allows you to configure initialization settings, send and verify configuration data, compose and transmit DLV command frames, and request LVD response data — all through an interactive command menu.

Note
This sample is new to SSK 2.x and has no SSK 1.x counterpart.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with an LL2 module installed.

  • SSK 2.x installed on your development host.

  • The sample applications built. Refer to the SSK 2.x Software Development Guide for platform-specific build instructions.

How to Run

Launch the LL2_basic_ops executable from your build output directory. On startup the application looks for a configuration file (default_LL2_BasicOps.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, a status display shows the current DLV command data and LVD request data side by side, followed by a command menu that lets you exercise each LL2 operation.

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

The main() function follows a standard SSK 2.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_LL2_BasicOps.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear.

  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_GetModuleName() so downstream code can adapt to the specific module installed.

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

   if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == (bool_t)NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         /* Select Card Index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Select Module */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               if ((moduleID != 0))
               {
                  Run_LL2BasicMenu(cardIndex, module, moduleID);
               }
            }
         }
         naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }
   naiif_printf("\r\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();
   return 0;
}

Note the SSK 2.x differences from SSK 1.x in this startup sequence:

  • The VxWorks preprocessor guard uses NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS (SSK 1.x uses __VXWORKS__).

  • The module identifier is retrieved with naibrd_GetModuleName() (SSK 1.x uses naibrd_GetModuleID()).

  • Boolean constants are NAI_TRUE / NAI_FALSE (SSK 1.x uses TRUE / FALSE).

  • Console output uses naiif_printf() from the platform abstraction layer (SSK 1.x uses printf() directly).

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 an LL2 module. Use the board menu to verify which slots are populated.

Program Structure

Entry Point

On standard platforms (Petalinux, DEOS) the entry point is main(). On VxWorks the entry point is LL2_BasicOps() — the SSK 2.x build system selects the correct variant via a preprocessor guard:

#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t LL2_BasicOps(void)
#else
int32_t main(void)
#endif

The startup flow is the same in both cases:

  1. Attempt to load the saved configuration file via naiapp_RunBoardMenu(DEF_CONFIG_FILE). If the file does not yet exist, the interactive board menu is presented instead.

  2. Enter a loop that queries for card index and module slot.

  3. Call Run_LL2BasicMenu() to enter the interactive command loop.

  4. On exit, close all open board connections with naiapp_access_CloseAllOpenCards().

Command Loop

The Run_LL2BasicMenu() function loads the command table, displays the current DLV and LVD data, and enters a do…​while loop that processes user commands. The application populates an naiapp_AppParameters_t structure with the selected card index, module, and module ID, then passes it to each command handler.

The command table is defined as follows:

Command Description

Config

Configure initialization settings (bandwidth, thresholds, transformation ratios, update rate)

VerifyConfig

Send configuration data to the module and verify CRC pass/fail

DLV_Config

Configure DLV command data (frame number, sequence number, channel positions, delays)

Send

Send DLV command data to the module

LVD_Request

Request LVD data from the module

ResetCRC

Reset the CRC error count

Configure Initialization Settings

The LL2BasicMenu_ConfigSettings() function reads the current raw configuration data from the module, prompts the user for updated values, computes a CRC over the new configuration, and writes the result back.

static nai_status_t LL2BasicMenu_ConfigSettings(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   p_naiapp_AppParameters_t p_LL2Params = (p_naiapp_AppParameters_t)p_params;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt = 0;
   naibrd_LL2_config_raw_t configDataRaw;
   uint32_t crc = 0u;

   check_status(naibrd_LL2_GetConfigDataRaw(p_LL2Params->cardIndex, p_LL2Params->module, &configDataRaw, &crc));
   /* ... prompt user for each config field ... */
   crc = naibrd_LL2_calcConfigCRCRaw(configDataRaw);
   check_status(naibrd_LL2_SetConfigDataRaw(p_LL2Params->cardIndex, p_LL2Params->module, configDataRaw, crc));

   return NAI_SUCCESS;
}

Key API calls:

  • naibrd_LL2_GetConfigDataRaw() — reads the current configuration data and CRC from the module.

  • naibrd_LL2_calcConfigCRCRaw() — computes a CRC over the configuration structure.

  • naibrd_LL2_SetConfigDataRaw() — writes the updated configuration and CRC to the module.

Configuration parameters include:

  • Channel status enable

  • Per-channel bandwidth (Hz) and bandwidth select

  • Per-channel reference fault low threshold

  • Per-channel signal and reference upper thresholds

  • Per-channel transformation ratio

  • Request update rate (0 for manual mode, nonzero for auto mode in microseconds)

Send and Verify Configuration

The LL2BasicMenu_SendConfigData() function initiates the configuration transfer to the module hardware and checks whether the CRC passed or failed. It polls the initiate-config register with a timeout to avoid blocking indefinitely.

static nai_status_t LL2BasicMenu_SendConfigData(int32_t paramCount, int32_t* p_params)
{
   uint32_t configDataCmd = 0u, timeout = 100;
   p_naiapp_AppParameters_t p_LL2Params = (p_naiapp_AppParameters_t)p_params;

   do
   {
      check_status(naibrd_LL2_GetInitiateConfigData(p_LL2Params->cardIndex, p_LL2Params->module, &configDataCmd));
      if (configDataCmd == NAIBRD_LL2_CONFIG_CRC_BUSY)
      {
         naiif_msDelay(10);
         timeout--;
      }
      else
      {
         timeout = 0u;
         check_status(naibrd_LL2_InitiateConfigData(p_LL2Params->cardIndex, p_LL2Params->module));
         naiif_msDelay(10);
         check_status(naibrd_LL2_GetInitiateConfigData(p_LL2Params->cardIndex, p_LL2Params->module, &configDataCmd));
         /* Check configDataCmd for PASS or FAIL */
      }
   } while ( (configDataCmd != NAIBRD_LL2_CONFIG_CRC_PASS) && (configDataCmd != NAIBRD_LL2_CONFIG_CRC_FAIL) && (timeout > 0));

   return NAI_SUCCESS;
}

Key API calls:

  • naibrd_LL2_GetInitiateConfigData() — reads the current state of the config initiation register (busy, pass, or fail).

  • naibrd_LL2_InitiateConfigData() — triggers the configuration data transfer.

Important
The function uses a polling loop with a 100-iteration timeout (10 ms delay per iteration). If the module is still processing a previous configuration when you issue a new one, the send will time out.

Configure and Send DLV Command Data

The LL2BasicMenu_ConfigDLVCmdData() function allows you to compose a DLV command frame with frame number, sequence number, per-channel position (percentage), and per-channel delay (microseconds). A CRC is computed over the command data and included in the write.

check_status(naibrd_LL2_GetDLVData(p_LL2Params->cardIndex, p_LL2Params->module, &cmdData, &cmdCrc));
/* ... prompt user for frame number, sequence number, positions, delays ... */
cmdCrc = naibrd_LL2_calcCmdCRC(cmdData);
check_status(naibrd_LL2_SetDLVData(p_LL2Params->cardIndex, p_LL2Params->module, cmdData, cmdCrc));

Key API calls:

  • naibrd_LL2_GetDLVData() — reads the current DLV command data and CRC.

  • naibrd_LL2_calcCmdCRC() — computes CRC over the command data structure.

  • naibrd_LL2_SetDLVData() — writes the DLV command data and CRC to the module.

The LL2BasicMenu_SendDLVData() function transmits the prepared DLV data to the module using a poll-and-send pattern similar to the configuration send:

  • naibrd_LL2_GetInitiateSendCmd() — checks whether the send register is ready.

  • naibrd_LL2_InitiateSendCmd() — triggers the DLV data transmission.

Request LVD Data

The LL2BasicMenu_RequestLVDData() function requests LVDT measurement data from the module. Like the send operations, it polls the request-data register before initiating the request.

check_status(naibrd_LL2_GetInitiateReqData(p_LL2Params->cardIndex, p_LL2Params->module, &requestDataCmd));
/* ... poll until ready, then ... */
check_status(naibrd_LL2_InitiateReqData(p_LL2Params->cardIndex, p_LL2Params->module));

Key API calls:

  • naibrd_LL2_GetInitiateReqData() — checks the request register state.

  • naibrd_LL2_InitiateReqData() — triggers the LVD data request.

Note
When the update rate is set to 0 (manual mode), you must explicitly request data each time. When set to a nonzero value (auto mode), the module provides data at the configured interval in microseconds.

Display Information

The LL2BasicMenu_displayInfo() function reads and displays both the DLV command data and LVD request data in a side-by-side table format. It shows frame numbers, sequence numbers, CRC values, per-channel positions, delays or relay states, timestamps, and the current CRC error count and update rate.

Key API calls used in the display function:

  • naibrd_LL2_GetDLVData() — retrieves DLV command data.

  • naibrd_LL2_GetLVDTReqData() — retrieves LVD request data (positions, relay states, timestamps, CRC).

  • naibrd_LL2_GetInitiateSendCmd() — reads the send command state.

  • naibrd_LL2_GetInitiateReqData() — reads the request data state.

  • naibrd_LL2_GetReqUpdateRate() — reads the configured update rate.

  • naibrd_LL2_GetCRCErrorCount() — reads the CRC error counter.

Reset CRC Error Count

The LL2BasicMenu_ResetCRCErrorCount() function resets the module’s CRC error counter to zero.

check_status(naibrd_LL2_ResetCRCErrorCount(p_LL2Params->cardIndex, p_LL2Params->module));

Troubleshooting Reference

Error / Symptom Possible Causes Suggested Resolution

No board found

Board not powered or not connected

Verify power and physical connections; check configuration file

Connection timeout

Network/bus misconfiguration

Confirm IP address, subnet, or PCI/PCIe settings

Invalid card or module index

Wrong index values entered

Cards are zero-based, modules are one-based

Module not present at selected slot

Slot is empty or contains a different module type

Use the board menu to verify slot population

Configuration CRC FAILED

Configuration data corrupted during transfer

Retry the send; ensure no concurrent writes to the module

Send command timeout

Previous operation still in progress

Wait for the previous operation to complete before issuing a new send

Request command timeout

Module busy processing previous request

Increase timeout or wait for the previous request to finish

CRC error count incrementing

Data integrity issues on the bus

Check cabling and signal integrity; reset the CRC error count after resolving

Position values show zero

Module not configured or no signal connected

Ensure initialization settings have been sent and verified; check LVDT connections

Update rate shows MANUAL when AUTO expected

Request update rate set to 0

Use the Config command to set a nonzero update rate value

Full Source

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

Full Source — LL2_basic_ops.c (SSK 2.x)
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"

/* naibrd include files */
#include "nai_libs/naibrd/include/naibrd.h"
#include "nai_libs/naibrd/include/functions/naibrd_LL2.h"

/* naiif include files */
#include "nai_libs/naiif/include/naiif.h"
#include "nai_libs/naiif/include/naiif_stdio.h"

/* Common Sample Program include files */
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_menu.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_query.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_access.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_display.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_utils.h"

static const int8_t *DEF_CONFIG_FILE = (const int8_t *)"default_LL2_BasicOps.txt";

/* Function prototypes */
static nai_status_t Run_LL2BasicMenu(int32_t cardIndex, int32_t module, uint32_t modId);
static nai_status_t LL2BasicMenu_displayInfo(int32_t cardIndex, int32_t module, uint32_t modId);

/* LVDT Basic Ops Command Functions */
static nai_status_t LL2BasicMenu_ConfigSettings(int32_t paramCount, int32_t* p_params);
static nai_status_t LL2BasicMenu_SendConfigData(int32_t paramCount, int32_t* p_params);
static nai_status_t LL2BasicMenu_ConfigDLVCmdData(int32_t paramCount, int32_t* p_params);
static nai_status_t LL2BasicMenu_SendDLVData(int32_t paramCount, int32_t* p_params);
static nai_status_t LL2BasicMenu_RequestLVDData(int32_t paramCount, int32_t* p_params);
static nai_status_t LL2BasicMenu_ResetCRCErrorCount(int32_t paramCount, int32_t* p_params);

/****** Command Table *******/
enum LL2_basicOpsMenu_commands
{
   LL2_BASICMENU_CMD_CONFIG_SETTINGS,
   LL2_BASICMENU_CMD_SEND_VERIFY_CFG,
   LL2_BASICMENU_CMD_CONFIG_DLV_DATA,
   LL2_BASICMENU_CMD_SEND_DLV_DATA,
   LL2_BASICMENU_CMD_REQUEST_LVD_DATA,
   LL2_BASICMENU_CMD_RESET_CRC_ERROR_COUNT,
   LL2_BASICMENU_CMD_COUNT
};

static naiapp_cmdtbl_params_t LL2_BasicOpMenuCmds[] =
{
   {"Config",           "Configure Init Settings",       LL2_BASICMENU_CMD_CONFIG_SETTINGS,        LL2BasicMenu_ConfigSettings     },
   {"VerifyConfig",     "Send/Verify Config Settings",   LL2_BASICMENU_CMD_SEND_VERIFY_CFG,        LL2BasicMenu_SendConfigData     },
   {"DLV_Config",       "Configure DLV Data",            LL2_BASICMENU_CMD_CONFIG_DLV_DATA,        LL2BasicMenu_ConfigDLVCmdData   },
   {"Send",             "Send DLV Data",                 LL2_BASICMENU_CMD_SEND_DLV_DATA,          LL2BasicMenu_SendDLVData        },
   {"LVD_Request",      "Request LVD Data",              LL2_BASICMENU_CMD_REQUEST_LVD_DATA,       LL2BasicMenu_RequestLVDData     },
   {"ResetCRC",         "Reset CRC Error Count",         LL2_BASICMENU_CMD_RESET_CRC_ERROR_COUNT,  LL2BasicMenu_ResetCRCErrorCount },
};

/*****************************************************************************/
/**
 * <summary>
 * The purpose of the LVDT_BasicOpsMenu is to illustrate the methods to call in the
 * naibrd library to perform basic operations with the LVDT modules for
 * configuration setup and reading the channels.
 *
 * 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 LVDT routines.
 * - ConfigDevice
 * - DisplayDeviceCfg
 * - GetBoardSNModCfg
 * - CheckModule
 * </summary>
 */
/*****************************************************************************/
#if defined (NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS)
int32_t LL2_BasicOps(void)
#else
int32_t main(void)
#endif
{
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   bool_t  stop = NAI_FALSE;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(DEF_CONFIG_FILE) == (bool_t)NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         /* Select Card Index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Select Module */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               if ((moduleID != 0))
               {
                  Run_LL2BasicMenu(cardIndex, module, moduleID);
               }
            }
         }
         naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }
   naiif_printf("\r\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_LVDTBasicMenu illustrates the channel configuration and prepares the menu
 * which will handle user command requests. Returns NAI_TRUE if the user enters
 * the Quit Command at any point within its scope.
 * </summary>
 */
/*****************************************************************************/
static nai_status_t Run_LL2BasicMenu(int32_t cardIndex, int32_t module, uint32_t modId)
{
   bool_t bQuit = NAI_FALSE;
   int32_t cmd;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   naiapp_AppParameters_t lvdtParams;
   p_naiapp_AppParameters_t p_lvdtParams = &lvdtParams;
   memset(&lvdtParams, 0, sizeof(naiapp_AppParameters_t));
   p_lvdtParams->cardIndex = cardIndex;
   p_lvdtParams->module = module;
   p_lvdtParams->modId = modId;
   naiapp_utils_LoadParamMenuCommands(LL2_BASICMENU_CMD_COUNT, LL2_BasicOpMenuCmds);
   do
   {
      LL2BasicMenu_displayInfo(p_lvdtParams->cardIndex, p_lvdtParams->module, p_lvdtParams->modId);
      naiapp_display_ParamMenuCommands((int8_t*)"LL2 Commands");
      naiif_printf("\r\n Type command or %c to quit : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit && inputResponseCnt > 0)
      {
         if (naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd) == NAI_TRUE)
            LL2_BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)p_lvdtParams);
         else
            naiif_printf(" Invalid command entered\r\n");
      }
   } while (!bQuit);
   return (nai_status_t)bQuit;
}

static nai_status_t LL2BasicMenu_displayInfo(int32_t cardIndex, int32_t module, uint32_t modId)
{
   naibrd_LL2_req_data_t reqData;
   naibrd_LL2_cmd_data_t cmdData;
   uint32_t cmdCrc = 0u;
   uint32_t sendDataCmd = 0u;
   uint32_t reqDataCmd = 0u;
   uint32_t updateRate = 0u;
   uint32_t crcErrorCount = 0u;

   check_status(naibrd_LL2_GetDLVData(cardIndex, module, &cmdData, &cmdCrc));
   check_status(naibrd_LL2_GetLVDTReqData(cardIndex, module, &reqData));
   check_status(naibrd_LL2_GetInitiateSendCmd(cardIndex, module, &sendDataCmd));
   check_status(naibrd_LL2_GetInitiateReqData(cardIndex, module, &reqDataCmd));
   check_status(naibrd_LL2_GetReqUpdateRate(cardIndex, module, &updateRate));
   check_status(naibrd_LL2_GetCRCErrorCount(cardIndex, module, &crcErrorCount));

   naiif_printf("\r\n\r\n         DLV Command Data         |         LVD Request Data\r\n");
   naiif_printf("-------------------------------------------------------------------\r\n");
   naiif_printf("Frame Number:       %-10u    |  Frame Number:       %-10u\r\n", cmdData.frameNum, reqData.frameNum);
   naiif_printf("Sequence Number:    %-10u    |  Sequence Number:    %-10u\r\n", cmdData.seqNum, reqData.seqNum);
   naiif_printf("CRC:                0x%08X    |  CRC:                0x%08X\r\n", cmdCrc, reqData.cmdCRC);
   naiif_printf("                                  |  TimeStamp(uS):      %-10u\r\n", reqData.timestamp_us);
   naiif_printf("Ch1 Position(%%):    %-8.3f      |  Ch1 Position(%%):    %-8.3f\r\n", cmdData.posCh1, reqData.posCh1);
   naiif_printf("Ch1 Delay(uS):      %-10u    |  Ch1 Relay State:    %s\r\n", cmdData.delayCh1_us,
      reqData.relayStateCh1 == RELAY_STATE_LVDT ? "LVDT" : "DLV ");
   naiif_printf("Ch2 Position(%%):    %-8.3f      |  Ch2 Position(%%):    %-8.3f\r\n", cmdData.posCh2, reqData.posCh2);
   naiif_printf("Ch2 Delay(uS):      %-10u    |  Ch2 Relay State:    %s\r\n", cmdData.delayCh2_us,
      reqData.relayStateCh2 == RELAY_STATE_LVDT ? "LVDT" : "DLV ");
   naiif_printf("                                  |  Data CRC:           0x%08X\r\n", reqData.dataCRC);
   naiif_printf("===================================================================\r\n");

   naiif_printf("CRC Error Count: %-7u          |  Update Rate: %uuS (%s MODE)\r\n", crcErrorCount, updateRate,
      0 == updateRate ? "MANUAL" : "AUTO" );

   naiif_printf("\r\n\r\n*Displayed positions may be slightly more accurate than actual due to the resolution of the module.\r\n");

   return NAI_SUCCESS;
}

static nai_status_t LL2BasicMenu_ConfigSettings(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   p_naiapp_AppParameters_t p_LL2Params = (p_naiapp_AppParameters_t)p_params;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt = 0;
   naibrd_LL2_config_raw_t configDataRaw;
   uint32_t crc = 0u;

   check_status(naibrd_LL2_GetConfigDataRaw(p_LL2Params->cardIndex, p_LL2Params->module, &configDataRaw, &crc));

   naiif_printf("\r\n\r\nEnter the required info below. Enter new value in decimal when prompted, or press ENTER to keep existing value:\r\n");
   naiif_printf("Channel Status Enable [%u (0x%08X)]: ", configDataRaw.chanStatusEnable, configDataRaw.chanStatusEnable);
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.chanStatusEnable), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch1 Bandwidth Hz [%u (0x%08X)]: ", configDataRaw.bandwidthCh1_Hz, configDataRaw.bandwidthCh1_Hz);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.bandwidthCh1_Hz), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch1 Bandwidth Select [%u (0x%08X)]: ", configDataRaw.bandwidthSelectCh1, configDataRaw.bandwidthSelectCh1);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.bandwidthSelectCh1), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch1 Reference Lower Threshold [%u (0x%08X)]: ", configDataRaw.refFaultLowThreshCh1, configDataRaw.refFaultLowThreshCh1);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.refFaultLowThreshCh1), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch2 Bandwidth Hz [%u (0x%08X)]: ", configDataRaw.bandwidthCh2_Hz, configDataRaw.bandwidthCh2_Hz);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.bandwidthCh2_Hz), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch2 Bandwidth Select [%u (0x%08X)]: ", configDataRaw.bandwidthSelectCh2, configDataRaw.bandwidthSelectCh2);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.bandwidthSelectCh2), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch2 Reference Lower Threshold [%u (0x%08X)]: ", configDataRaw.refFaultLowThreshCh2, configDataRaw.refFaultLowThreshCh2);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.refFaultLowThreshCh2), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch1 Signal Upper Threshold [%u (0x%08X)]: ", configDataRaw.sigUpperThreshCh1, configDataRaw.sigUpperThreshCh1);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.sigUpperThreshCh1), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch2 Signal Upper Threshold [%u (0x%08X)]: ", configDataRaw.sigUpperThreshCh2, configDataRaw.sigUpperThreshCh2);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.sigUpperThreshCh2), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch1 Reference Upper Threshold [%u (0x%08X)]: ", configDataRaw.refUpperThreshCh1, configDataRaw.refUpperThreshCh1);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.refUpperThreshCh1), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch2 Reference Upper Threshold [%u (0x%08X)]: ", configDataRaw.refUpperThreshCh2, configDataRaw.refUpperThreshCh2);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.refUpperThreshCh2), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch1 Transformation Ratio [%u (0x%08X)]: ", configDataRaw.transformationRationCh1, configDataRaw.transformationRationCh1);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.transformationRationCh1), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch2 Transformation Ratio [%u (0x%08X)]: ", configDataRaw.transformationRationCh2, configDataRaw.transformationRationCh2);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.transformationRationCh2), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Request Update Rate [%u (0x%08X)]: ", configDataRaw.requestUpdateRate, configDataRaw.requestUpdateRate);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(configDataRaw.requestUpdateRate), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      crc = naibrd_LL2_calcConfigCRCRaw(configDataRaw);
      naiif_printf("CRC [%u (0x%08X)]: ", crc, crc);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&crc, inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      check_status(naibrd_LL2_SetConfigDataRaw(p_LL2Params->cardIndex, p_LL2Params->module, configDataRaw, crc));
   }

   return NAI_SUCCESS;
}

static nai_status_t LL2BasicMenu_SendConfigData(int32_t paramCount, int32_t* p_params)
{
   uint32_t configDataCmd = 0u, timeout = 100;
   p_naiapp_AppParameters_t p_LL2Params = (p_naiapp_AppParameters_t)p_params;

   do
   {
      check_status(naibrd_LL2_GetInitiateConfigData(p_LL2Params->cardIndex, p_LL2Params->module, &configDataCmd));
      naiif_printf("Checking Initiate Config Command state:");

      if (configDataCmd == NAIBRD_LL2_CONFIG_CRC_BUSY)
      {
         naiif_printf("BUSY: 0x%08X\r\n", configDataCmd);
         naiif_msDelay(10);
         timeout--;
      }
      else
      {
         timeout = 0u;
         naiif_printf("CLEAR\r\nSending Config Data...");
         check_status(naibrd_LL2_InitiateConfigData(p_LL2Params->cardIndex, p_LL2Params->module));
         naiif_msDelay(10);
         check_status(naibrd_LL2_GetInitiateConfigData(p_LL2Params->cardIndex, p_LL2Params->module, &configDataCmd));
         if (configDataCmd == NAIBRD_LL2_CONFIG_CRC_PASS)
         {
            naiif_printf("Complete and CRC PASSED!\r\n");
         }
         else if (configDataCmd == NAIBRD_LL2_CONFIG_CRC_FAIL)
         {
            naiif_printf("Complete and CRC FAILED!\r\n");
         }
         else
         {
            naiif_printf("ERROR- Send Command timeout! Configuration data may not have been sent.\r\n");
         }
      }
   } while ( (configDataCmd != NAIBRD_LL2_CONFIG_CRC_PASS) && (configDataCmd != NAIBRD_LL2_CONFIG_CRC_FAIL) && (timeout > 0));

   if ((configDataCmd != NAIBRD_LL2_CONFIG_CRC_PASS) && (configDataCmd != NAIBRD_LL2_CONFIG_CRC_FAIL))
   {
      naiif_printf("**SEND FAILED! Initiate config has timed-out with 0x%08X waiting for the previous send to complete.\r\n", configDataCmd);
   }

   return NAI_SUCCESS;
}

static nai_status_t LL2BasicMenu_ConfigDLVCmdData(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = NAI_FALSE;
   p_naiapp_AppParameters_t p_LL2Params = (p_naiapp_AppParameters_t)p_params;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt = 0;
   naibrd_LL2_cmd_data_t cmdData;
   uint32_t cmdCrc = 0u;

   check_status(naibrd_LL2_GetDLVData(p_LL2Params->cardIndex, p_LL2Params->module, &cmdData, &cmdCrc));

   naiif_printf("\r\n\r\nEnter the required info below. Enter new value when prompted, or press ENTER to keep existing value:\r\n");
   naiif_printf("Frame Number [%u]: ", cmdData.frameNum);
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
         naiapp_query_UnsignedNumberFromResponse(&(cmdData.frameNum), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Sequence Number [%u]: ", cmdData.seqNum);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(cmdData.seqNum), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch1 Position from -%6.3f%% to %6.3f%% [%-6.3f]: ", NAIBRD_LL2_MAX_POSITION,
         NAIBRD_LL2_MAX_POSITION - 0.001, cmdData.posCh1);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_FloatNumberFromResponse(&(cmdData.posCh1), (char*)inputBuffer);
   }

   if (!bQuit)
   {
      naiif_printf("Ch1 Delay from 0 to %u(uS) [%u]: ", (NAIBRD_LL2_MAX_DELAY_RATE_uS / 1000), cmdData.delayCh1_us);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(cmdData.delayCh1_us), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      naiif_printf("Ch2 Position from -%6.3f%% to %6.3f%% [%-6.3f]: ", NAIBRD_LL2_MAX_POSITION,
         NAIBRD_LL2_MAX_POSITION - 0.001, cmdData.posCh2);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_FloatNumberFromResponse(&(cmdData.posCh2), (char*)inputBuffer);
   }

   if (!bQuit)
   {
      naiif_printf("Ch2 Delay from 0 to %u(uS) [%u]: ", (NAIBRD_LL2_MAX_DELAY_RATE_uS / 1000), cmdData.delayCh2_us);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&(cmdData.delayCh2_us), inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      cmdCrc = naibrd_LL2_calcCmdCRC(cmdData);
      naiif_printf("Calculated CRC [0x%08X (%u)]: ", cmdCrc, cmdCrc);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), 'Q', inputBuffer, &inputResponseCnt);
      if (!bQuit && (inputResponseCnt > 0))
         naiapp_query_UnsignedNumberFromResponse(&cmdCrc, inputBuffer, inputResponseCnt);
   }

   if (!bQuit)
   {
      check_status(naibrd_LL2_SetDLVData(p_LL2Params->cardIndex, p_LL2Params->module, cmdData, cmdCrc));
   }

   return NAI_SUCCESS;
}

static nai_status_t LL2BasicMenu_SendDLVData(int32_t paramCount, int32_t* p_params)
{
   uint32_t sendDataCmd = 0u, timeout = 100;
   p_naiapp_AppParameters_t p_LL2Params = (p_naiapp_AppParameters_t)p_params;

   do
   {
      check_status(naibrd_LL2_GetInitiateSendCmd(p_LL2Params->cardIndex, p_LL2Params->module, &sendDataCmd));
      naiif_printf("Checking Initiate Send Command state:");

      if (sendDataCmd != NAIBRD_LL2_SEND_DATA_COMPLETE)
      {
         naiif_printf("BUSY: 0x%08X\r\n", sendDataCmd);
         naiif_msDelay(10);
         timeout--;
      }
      else
      {
         timeout = 0u;
         naiif_printf("CLEAR\r\nSending DLV Data...");
         check_status(naibrd_LL2_InitiateSendCmd(p_LL2Params->cardIndex, p_LL2Params->module));
         naiif_msDelay(10);
         check_status(naibrd_LL2_GetInitiateSendCmd(p_LL2Params->cardIndex, p_LL2Params->module, &sendDataCmd));
         if (sendDataCmd == NAIBRD_LL2_SEND_DATA_COMPLETE)
         {
            naiif_printf("Complete!\r\n");
         }
         else
         {
            naiif_printf("ERROR- Send Command timeout! DLV Data may not have been sent.\r\n");
         }
      }
   } while ( (sendDataCmd != NAIBRD_LL2_SEND_DATA_COMPLETE) && (timeout > 0));

   if (sendDataCmd != NAIBRD_LL2_SEND_DATA_COMPLETE)
   {
      naiif_printf("**SEND FAILED! Initiate Send has timed-out with 0x%08X waiting for the previous send to complete.\r\n", sendDataCmd);
   }

   return NAI_SUCCESS;
}

static nai_status_t LL2BasicMenu_RequestLVDData(int32_t paramCount, int32_t* p_params)
{
   uint32_t requestDataCmd = 0u, timeout = 100;
   p_naiapp_AppParameters_t p_LL2Params = (p_naiapp_AppParameters_t)p_params;

   do
   {
      check_status(naibrd_LL2_GetInitiateReqData(p_LL2Params->cardIndex, p_LL2Params->module, &requestDataCmd));
      naiif_printf("Checking Initiate Request Data Command state:");

      if (requestDataCmd != NAIBRD_LL2_REQ_DATA_COMPLETE)
      {
         naiif_printf("BUSY: 0x%08X\r\n", requestDataCmd);
         naiif_msDelay(10);
         timeout--;
      }
      else
      {
         timeout = 0u;
         naiif_printf("CLEAR\r\nSending LVD Data Request...");
         check_status(naibrd_LL2_InitiateReqData(p_LL2Params->cardIndex, p_LL2Params->module));
         naiif_msDelay(10);
         check_status(naibrd_LL2_GetInitiateReqData(p_LL2Params->cardIndex, p_LL2Params->module, &requestDataCmd));
         if (requestDataCmd == NAIBRD_LL2_REQ_DATA_COMPLETE)
         {
            naiif_printf("Complete!\r\n");
         }
         else
         {
            naiif_printf("ERROR- Request Command timeout with 0x%08X! LVD Data may not have been received.\r\n", requestDataCmd);
         }
      }
   } while ( (requestDataCmd != NAIBRD_LL2_REQ_DATA_COMPLETE) && (timeout > 0));

   if (requestDataCmd != NAIBRD_LL2_REQ_DATA_COMPLETE)
   {
      naiif_printf("**REQUEST FAILED! Initiate Request has timed-out waiting for the previous request to complete.\r\n");
   }

   return NAI_SUCCESS;
}

static nai_status_t LL2BasicMenu_ResetCRCErrorCount(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_LL2Params = (p_naiapp_AppParameters_t)p_params;

   check_status(naibrd_LL2_ResetCRCErrorCount(p_LL2Params->cardIndex, p_LL2Params->module));

   return NAI_SUCCESS;
}

Help Bot

X