TC BasicOps Sample Application (SSK 1.x)

Overview

The TC BasicOps sample application demonstrates how to configure a Thermocouple (TC) module, read temperature and voltage measurements, and manage channel status using the NAI Software Support Kit (SSK 1.x). A TC module digitizes the small voltage produced by a thermocouple and converts it to temperature, applying cold-junction compensation (CJC) and the thermocouple linearization curve for the selected type (J, K, E, T, N, B, R, S).

This sample supports the TC1 (8-channel thermocouple) and TR1 (8-channel RTD/TC) modules. It serves as a practical API reference — each menu command maps directly to one or more naibrd_TC_*() API calls that you can lift into your own code.

Unlike most BasicOps samples, TC BasicOps operates on one channel at a time: you select a channel when you enter the module, and the menu then displays that channel’s full configuration and status on every iteration. The commands cover:

  • Reading — temperature (°C/°F), thermocouple voltage, and the configured sample rate are shown in the per-channel display.
  • Channel configuration — thermocouple type, sample rate, offset temperature, and per-channel status reporting.
  • Cold-junction compensation — enable/disable CJC, choose manual or automatic CJC, and set a manual compensation temperature.
  • Thresholds and status — alert/alarm low/high temperature thresholds, status read-back, and status clearing.
  • Diagnostics — power-on BIT check, on-demand system calibration / open-line check / BIT, and suspension of those background operations.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a TC1 or TR1 module installed.
  • SSK 1.x installed on your development host.
  • The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.
  • A thermocouple connected to at least one channel if you want to see live temperature readings.

How to Run

Launch the TC_BasicOps executable from your build output directory. On startup the application looks for a configuration file (default_TC_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. After selecting the module you are prompted for a channel, and the TC Basic Operation Menu opens for that channel.

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

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.
  2. Query the user for a card index with naiapp_query_CardIndex().
  3. Retrieve the module count with naibrd_GetModuleCount() and query for a module slot with naiapp_query_ModuleNumber().
  4. Retrieve the module ID with naibrd_GetModuleID() and, if valid, hand control to Run_TC_BasicOps().
#if defined (__VXWORKS__)
int32_t TC_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_TC_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);
      }
   }
 
   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 selection not recognized as TC module” — the selected slot does not contain a TC1 or TR1 module. naibrd_TC_GetChannelCount() returns 0 for non-TC modules, and the sample rejects the selection.

Program Structure

Entry Point

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

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

Module Initialization and Channel Selection

Run_TC_BasicOps() confirms the module is a TC module and prepares each channel before entering the menu. It retrieves the channel count with naibrd_TC_GetChannelCount() and, for every channel, calls naibrd_TC_SetConfiguration() with NAI_TC_CONFIG. On the TR1 (which can run channels as either RTD or thermocouple) this selects thermocouple operation; on the TC1 it is the standard configuration.

int32_t MaxChannel = naibrd_TC_GetChannelCount(ModuleID);
if (MaxChannel == 0)
{
   printf(" *** Module selection not recognized as TC module. ***\n\n");
}
else
{
   for (chanNum = 1; chanNum <= MaxChannel; chanNum++)
      check_status(naibrd_TC_SetConfiguration(cardIndex, module, chanNum, NAI_TC_CONFIG));
   Cfg_TC_Channel(cardIndex, module, MaxChannel, ModuleID);
}

Cfg_TC_Channel() then prompts for a single channel with naiapp_query_ChannelNumber() and stores it in the naiapp_AppParameters_t struct that is passed to every command handler:

naiapp_AppParameters_t  tc_basicops_params;
p_naiapp_AppParameters_t tc_basicOps_params = &tc_basicops_params;
tc_basicOps_params->cardIndex = cardIndex;
tc_basicOps_params->module    = module;
tc_basicOps_params->modId     = ModuleID;
naiapp_query_ChannelNumber(MaxChannel, 1, &tc_basicOps_params->channel);

Note

Every command in this sample acts on the single channel selected here. To work with a different channel, quit back out and re-select the module. (The Check Power-On BIT command is the one exception — it loops over every channel.)

Command Loop

Cfg_TC_Channel() drives the command loop. On each iteration it displays the selected channel’s full configuration via Display_TC_ChannelCfg(), prints the command menu, and dispatches the user’s selection:

while (!bQuit)
{
   Display_TC_ChannelCfg(cardIndex, module, tc_basicOps_params->channel);
   naiapp_display_ParamMenuCommands((int8_t *)"TC Basic Operation Menu");
   printf("\nType TC command or %c to quit : ", NAI_QUIT_CHAR);
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (bQuit) break;
   if (inputResponseCnt > 0 && naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd))
      TC_BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)tc_basicOps_params);
}

The commands are registered in the TC_BasicOpMenuCmds[] table:

CommandDescription
0Enable/disable channel status reporting
1Set the thermocouple type
2Set the sample rate
3Set the compensation temperature
4Enable/disable cold-junction compensation
5Set the CJC type (manual/auto)
6Set a threshold value (alert/alarm lo/hi)
7Clear a status
8Check power-on BIT
9Set the offset temperature
ASuspend BIT/open tests and system cal
BTrigger system calibration
CTrigger open-line check
DTrigger BIT

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

Reading Channel Data

Display_TC_ChannelCfg() reads back and prints everything about the selected channel on each loop iteration. These read-back calls are the ones you would use in your own application to retrieve measurements and configuration.

Temperature and Voltage

Read temperature in either unit with naibrd_TC_GetTemperature(), selecting the unit with a nai_tc_temperature_type_t. Read the raw thermocouple voltage with naibrd_TC_GetVoltage():

float64_t cTemp = 0.0, fTemp = 0.0, voltage = 0.0;
 
naibrd_TC_GetTemperature(cardIndex, module, channel, NAI_TC_TEMP_TYPE_CELSIUS,    &cTemp);
naibrd_TC_GetTemperature(cardIndex, module, channel, NAI_TC_TEMP_TYPE_FAHRENHEIT, &fTemp);
naibrd_TC_GetVoltage(cardIndex, module, channel, &voltage);
  • NAI_TC_TEMP_TYPE_CELSIUS / NAI_TC_TEMP_TYPE_FAHRENHEIT — select the temperature unit returned.
  • naibrd_TC_GetVoltage() returns the thermocouple voltage (the sample displays it in microvolts).

Note

On the TR1, when a channel is configured for RTD operation you can also read its resistance with naibrd_TC_GetResistance(). This sample configures channels for thermocouple operation, so it displays voltage rather than resistance.

Sample Rate and Thermocouple Type

The display also reads back the configured sample rate and thermocouple type:

float64_t rate = 0.0;
nai_tc_thermocouple_type_t tcType;
 
naibrd_TC_GetSampleRate(cardIndex, module, channel, &rate);
naibrd_TC_GetThermocoupleType(cardIndex, module, channel, &tcType);

The sample maps the nai_tc_thermocouple_type_t value (NAI_TC_THERMOCOUPLE_TYPE_J_S) back to its letter (J, K, E, T, N, B, R, S) for display.

Channel Configuration

Thermocouple Type

The thermocouple type determines which linearization curve the module applies. Set it with naibrd_TC_SetThermocoupleType():

naibrd_TC_SetThermocoupleType(cardIndex, module, channel, NAI_TC_THERMOCOUPLE_TYPE_K);

Valid types are NAI_TC_THERMOCOUPLE_TYPE_J, _K, _E, _T, _N, _B, _R, and _S.

Sample Rate

Set the per-channel sample rate (in Hz) with naibrd_TC_SetSampleRate():

float64_t rate = 60.0;
naibrd_TC_SetSampleRate(cardIndex, module, channel, rate);

Offset Temperature

An offset temperature is added to the channel’s computed temperature, letting you trim a known sensor or installation offset. Set it with naibrd_TC_SetOffsetTemperature():

float64_t offset = -1.5;   /* degrees */
naibrd_TC_SetOffsetTemperature(cardIndex, module, channel, offset);

Channel Status Enable

Enable or disable status reporting for the channel with naibrd_TC_SetChanStatusEnable(). When disabled, the module does not report status conditions (or assert status-driven interrupts) for that channel.

naibrd_TC_SetChanStatusEnable(cardIndex, module, channel, TRUE);

Note

naibrd_TC_SetOffsetTemperature() and naibrd_TC_SetBackgroundOpSuspend() are not supported on every TC firmware revision. The sample’s display functions check for NAI_ERROR_NOT_SUPPORTED and print “Not supported” rather than treating it as a hard error.

Cold-Junction Compensation

Thermocouples measure a temperature difference between the hot junction and the cold (reference) junction, so accurate absolute temperature requires knowing the cold-junction temperature. Cold-junction compensation (CJC) supplies that reference — either measured automatically by the module or provided manually.

Enable CJC

Turn CJC on or off for the module with naibrd_TC_SetCJCEnable():

naibrd_TC_SetCJCEnable(cardIndex, module, TRUE);

CJC Type (Manual or Automatic)

Select whether the cold-junction reference is measured automatically by the module or supplied manually, with naibrd_TC_SetCompType():

naibrd_TC_SetCompType(cardIndex, module, channel, NAI_TC_COMP_TYPE_AUTO);   /* or NAI_TC_COMP_TYPE_MANUAL */

Manual Compensation Temperature

When CJC type is manual, supply the reference temperature with naibrd_TC_SetCompTemperature():

float64_t compTemp = 25.0;   /* degrees C */
naibrd_TC_SetCompTemperature(cardIndex, module, channel, compTemp);

Important

Common Errors

  • Temperature readings off by a fixed amount — with manual CJC, the compensation temperature must match the actual cold-junction temperature. An incorrect value shifts every reading. Switch to NAI_TC_COMP_TYPE_AUTO to let the module measure it.
  • Wrong temperature scaling — verify the thermocouple type matches the physical sensor; the module applies a type-specific linearization curve.

Thresholds and Status

Setting Thresholds

Each channel has four temperature thresholds — alert and alarm, low and high. Alerts are the less-severe warning level; alarms are the more-severe level. Set each with naibrd_TC_SetThreshold(), selecting the threshold with a nai_tc_thresh_type_t:

naibrd_TC_SetThreshold(cardIndex, module, channel, NAI_TC_THRESH_ALERT_LO, -10.0);
naibrd_TC_SetThreshold(cardIndex, module, channel, NAI_TC_THRESH_ALARM_LO, -20.0);
naibrd_TC_SetThreshold(cardIndex, module, channel, NAI_TC_THRESH_ALERT_HI, 100.0);
naibrd_TC_SetThreshold(cardIndex, module, channel, NAI_TC_THRESH_ALARM_HI, 120.0);

The configured thresholds are read back for display with naibrd_TC_GetThreshold().

Reading Status

Each channel reports a set of status conditions, each with a real-time and a latched variant, read with naibrd_TC_GetStatus() and a nai_tc_status_type_t selector. The sample reads every status type into an array and prints the latched values:

nai_status_bit_t status;
naibrd_TC_GetStatus(cardIndex, module, channel, NAI_TC_STATUS_BIT_LATCHED,      &status);
naibrd_TC_GetStatus(cardIndex, module, channel, NAI_TC_STATUS_OPEN_LATCHED,     &status);
naibrd_TC_GetStatus(cardIndex, module, channel, NAI_TC_STATUS_ALERT_LO_LATCHED, &status);
naibrd_TC_GetStatus(cardIndex, module, channel, NAI_TC_STATUS_ALARM_LO_LATCHED, &status);
naibrd_TC_GetStatus(cardIndex, module, channel, NAI_TC_STATUS_ALERT_HI_LATCHED, &status);
naibrd_TC_GetStatus(cardIndex, module, channel, NAI_TC_STATUS_ALARM_HI_LATCHED, &status);
naibrd_TC_GetStatus(cardIndex, module, channel, NAI_TC_STATUS_SUMMARY_LATCHED,  &status);

Each status type has a _REALTIME and a _LATCHED form. Real-time reflects the current condition; latched holds the condition until explicitly cleared.

  • BIT — a built-in-test fault on the channel.
  • Open — an open thermocouple (broken or disconnected lead).
  • Alert Lo / Alarm Lo — temperature below the low alert / alarm threshold.
  • Alert Hi / Alarm Hi — temperature above the high alert / alarm threshold.
  • Summary — an aggregate of the channel’s error conditions.

Clearing Status

Clear a latched status with naibrd_TC_ClearStatus(), passing the latched status type to clear:

naibrd_TC_ClearStatus(cardIndex, module, channel, NAI_TC_STATUS_OPEN_LATCHED);

Diagnostics: Background Operations and BIT

TC modules continuously run background maintenance operations — system calibration, open-line detection, and BIT. You can trigger any of these on demand, suspend them, or check the power-on BIT result.

Triggering Background Operations

Trigger a single operation with naibrd_TC_TriggerBackgroundOperation(), selecting the operation with a nai_tc_background_op_type_t:

naibrd_TC_TriggerBackgroundOperation(cardIndex, module, channel, NAI_TC_BACKGROUND_OP_SYSTEM_CAL);
naibrd_TC_TriggerBackgroundOperation(cardIndex, module, channel, NAI_TC_BACKGROUND_OP_OPEN);
naibrd_TC_TriggerBackgroundOperation(cardIndex, module, channel, NAI_TC_BACKGROUND_OP_BIT);

Suspending Background Operations

While taking a precise reading you may want to suspend the automatic background operations. Control this with naibrd_TC_SetBackgroundOpSuspend() — passing TRUE suspends them, FALSE re-enables them:

naibrd_TC_SetBackgroundOpSuspend(cardIndex, module, channel, TRUE);   /* suspend */

Power-On BIT Check

Verify the module’s power-on BIT (PBIT) with naibrd_TC_CheckPowerOnBITComplete(), then read each channel’s latched BIT status. PBIT runs once, at power-on:

bool_t pbitComplete = FALSE;
nai_status_bit_t bitStatus = 0u;
int32_t channelCount = naibrd_TC_GetChannelCount(modId);
 
naibrd_TC_CheckPowerOnBITComplete(cardIndex, module, &pbitComplete);
if (pbitComplete)
{
   for (int32_t ch = 1; ch <= channelCount; ch++)
   {
      naibrd_TC_GetStatus(cardIndex, module, ch, NAI_TC_STATUS_BIT_LATCHED, &bitStatus);
      printf("Ch. %d: %s\n", ch, bitStatus ? "BIT FAILED" : "BIT Passed");
   }
}

Note

If the module has not been power-cycled since it was installed, PBIT may report “NOT COMPLETED.” This is normal and does not indicate a hardware failure.

Troubleshooting Reference

This table summarizes common errors and symptoms covered in the sections above. Consult your module’s manual for hardware-specific diagnostic procedures.

Error / SymptomPossible CausesSuggested Resolution
No board found or connection timeoutBoard not powered, incorrect or missing configuration file, network issueVerify hardware is powered and connected. If default_TC_BasicOps.txt exists, check that it lists the correct interface and address; otherwise configure and save your connection in the board menu.
”Module selection not recognized as TC module”Selected slot is not a TC1/TR1, or wrong module numbernaibrd_TC_GetChannelCount() returns 0 for non-TC modules. Verify the slot contains a TC1 or TR1.
Open status set / no readingThermocouple lead open or disconnectedCheck wiring; clear the latched open status after fixing it.
Temperature off by a constantManual CJC compensation temperature incorrect, or offset temperature setUse NAI_TC_COMP_TYPE_AUTO, verify the manual compensation temperature, and check the configured offset temperature.
Wrong temperature scalingThermocouple type does not match the physical sensorSet the correct nai_tc_thermocouple_type_t for the channel.
NAI_ERROR_NOT_SUPPORTED on offset / background-op suspendFeature not available on this firmware revisionThese features depend on FPGA revision; the display shows “Not supported” when unavailable.
PBIT reports NOT COMPLETEDModule not power-cycled since installPower-cycle the module and re-run the power-on BIT check.

Full Source

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

Full Source — TC_BasicOps.c (SSK 1.x)
#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_tc.h"
#include "advanced/nai_ether_adv.h"
 
static const int8_t *CONFIG_FILE = (const int8_t *)"default_TC_BasicOps.txt";
 
/* Function prototypes */
int32_t Run_TC_BasicOps(int32_t cardIndex, int32_t module, uint32_t ModuleID);
static void Cfg_TC_Channel(int32_t cardIndex, int32_t module, int32_t MaxChannel, uint32_t ModuleID);
static void Display_TC_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan);
 
/* Channel Display Helper Functions*/
static void TC_Display_ThermoCoupleType(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_Temperature(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_Voltage(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_SampleRate(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_CompTemp(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_CJCEnable(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_Statuses(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_Thresholds(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_CJCType(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_OffsetTemp(int32_t cardIndex, int32_t module, int32_t chan);
static void TC_Display_BackgroundOpSuspension(int32_t cardIndex, int32_t module, int32_t chan);
 
/* Menu Command Helper Functions*/
static nai_status_t TC_Set_ChanStatusEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Set_ThermoCoupleType(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Set_SampleRate(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Set_CompTemp(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Set_CJCEnable(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Set_Thresh(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_ClearStatus(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_CheckPowerOnBIT(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Set_CJCType(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Set_OffsetTemp(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Set_BackgroundOpSuspension(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Trigger_SystemCalibration(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Trigger_OpenCheck(int32_t paramCount, int32_t* p_params);
static nai_status_t TC_Trigger_BIT(int32_t paramCount, int32_t* p_params);
 
static uint32_t g_TCModId = 0u;
 
/****** Command Tables *******/
enum tc_basicops_commands
{
   TC_BASICOP_CMD_SET_CHAN_STATUS_ENABLE,
   TC_BASICOP_CMD_SET_THERMO_COUPLE_TYPE,
   TC_BASICOP_CMD_SET_SAMPLE_RATE,
   TC_BASICOP_CMD_SET_COMP_TEMP,
   TC_BASICOP_CMD_SET_CJC_ENABLE,
   TC_BASICOP_CMD_SET_CJC_TYPE,
   TC_BASICOP_CMD_SET_THRESH,
   TC_BASICOP_CMD_CLEAR_STATUS,
   TC_BASICOP_CMD_CHECK_POWER_ON_BIT,
   TC_BASICOP_CMD_SET_OFFSET_TEMP,
   TC_BASICOP_CMD_SET_BACKGROUND_OP_SUSPEND,
   TC_BASICOP_CMD_TRIGGER_SYSTEM_CAL,
   TC_BASICOP_CMD_TRIGGER_OPEN_CHECK,
   TC_BASICOP_CMD_TRIGGER_BIT,
   TC_BASICOP_CMD_COUNT
};
 
naiapp_cmdtbl_params_t TC_BasicOpMenuCmds[] = {
   {"0", "Enable/Disable Channel Status Reporting",      TC_BASICOP_CMD_SET_CHAN_STATUS_ENABLE,       TC_Set_ChanStatusEnable},
   {"1", "Set the Thermo Couple Type",                   TC_BASICOP_CMD_SET_THERMO_COUPLE_TYPE,       TC_Set_ThermoCoupleType},
   {"2", "Set the Sample Rate",                          TC_BASICOP_CMD_SET_SAMPLE_RATE,              TC_Set_SampleRate},
   {"3", "Set the Compensation Temperature",             TC_BASICOP_CMD_SET_COMP_TEMP,                TC_Set_CompTemp},
   {"4", "Enable/Disable Cold Junction Compensation",    TC_BASICOP_CMD_SET_CJC_ENABLE,               TC_Set_CJCEnable},
   {"5", "Set the CJC Type",                             TC_BASICOP_CMD_SET_CJC_TYPE,                 TC_Set_CJCType},
   {"6", "Set a Threshold Value",                        TC_BASICOP_CMD_SET_THRESH,                   TC_Set_Thresh},
   {"7", "Clear a Status",                               TC_BASICOP_CMD_CLEAR_STATUS,                 TC_ClearStatus},
   {"8", "Check Power-On BIT",                           TC_BASICOP_CMD_CHECK_POWER_ON_BIT,           TC_CheckPowerOnBIT},
   {"9", "Set the Offset Temperature",                   TC_BASICOP_CMD_SET_OFFSET_TEMP,              TC_Set_OffsetTemp},
   {"A", "Suspend BIT/Open tests and System Cal",        TC_BASICOP_CMD_SET_BACKGROUND_OP_SUSPEND,    TC_Set_BackgroundOpSuspension},
   {"B", "Trigger System Calibration",                   TC_BASICOP_CMD_TRIGGER_SYSTEM_CAL,           TC_Trigger_SystemCalibration},
   {"C", "Trigger Open-Line Check",                      TC_BASICOP_CMD_TRIGGER_OPEN_CHECK,           TC_Trigger_OpenCheck},
   {"D", "Trigger BIT",                                  TC_BASICOP_CMD_TRIGGER_BIT,                  TC_Trigger_BIT}
};
 
/**************************************************************************************************************/
/**
<summary>
The purpose of the TC_BasicOps is to illustrate the methods to call in the naibrd library to perform basic
 operations with the thermal coupling module 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 TC routines.
 - ClearDeviceCfg
 - QuerySystemCfg
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - SaveDeviceCfg
 
</summary>
*/
/**************************************************************************************************************/
 
#if defined (__VXWORKS__)
int32_t TC_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_TC_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_TC_BasicOps prompts the user for the card, module and channel to use for the application and calls
Cfg_TC_Channel if the card, module, channel is valid for as a discrete module.
</summary>
*/
/**************************************************************************************************************/
int32_t Run_TC_BasicOps(int32_t cardIndex, int32_t module, uint32_t ModuleID)
{
   int32_t MaxChannel;
   uint32_t ModuleVer;
   uint32_t ModuleRev;
   uint32_t ModInfo_Special;
   int32_t chanNum = 0;
 
   naibrd_GetModuleInfo(cardIndex, module, &ModuleID, &ModuleVer, &ModuleRev, &ModInfo_Special);
   MaxChannel = naibrd_TC_GetChannelCount(ModuleID);
   g_TCModId = ModuleID;
   if (MaxChannel == 0)
   {
      printf(" *** Module selection not recognized as TC module. ***\n\n");
   }
   else
   {
      for (chanNum = 1; chanNum <= MaxChannel; chanNum++)
      {
         check_status(naibrd_TC_SetConfiguration(cardIndex, module, chanNum, NAI_TC_CONFIG));
      }
      Cfg_TC_Channel(cardIndex, module, MaxChannel, ModuleID);
   }
 
   return cardIndex;
}
 
/**************************************************************************************************************/
/**
<summary>
Cfg_TC_Channel handles calling the Display_TC_ChannelCfg routine to display the discrete channel configuration
and calling the routines associated with the user's menu commands.
</summary>
*/
/**************************************************************************************************************/
static void Cfg_TC_Channel(int32_t cardIndex, int32_t module, int32_t MaxChannel, uint32_t ModuleID)
{
   bool_t bQuit = FALSE;
   bool_t bCmdFound = FALSE;
   int32_t cmd;
   int32_t defaultchan = 1;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
   naiapp_AppParameters_t  tc_basicops_params;
   p_naiapp_AppParameters_t tc_basicOps_params = &tc_basicops_params;
   tc_basicOps_params->cardIndex = cardIndex;
   tc_basicOps_params->module = module;
   tc_basicOps_params->maxChannels = naibrd_TC_GetChannelCount(MaxChannel);
   tc_basicOps_params->modId = ModuleID;
   tc_basicOps_params->displayHex = FALSE;
 
   printf("    \r\n\r\n");
   printf("Channel selection: \r\n");
   printf("================= \r\n");
   bQuit = naiapp_query_ChannelNumber(MaxChannel, defaultchan, &tc_basicOps_params->channel);
 
   naiapp_utils_LoadParamMenuCommands(TC_BASICOP_CMD_COUNT, TC_BasicOpMenuCmds);
 
   while (!bQuit)
   {
      /* Display the Channel Configuration */
      Display_TC_ChannelCfg(cardIndex, module, tc_basicOps_params->channel);
 
      /* Display the Menu Commands*/
      naiapp_display_ParamMenuCommands((int8_t *)"TC Basic Operation Menu");
 
      /* Prompt User For Command*/
      printf("\nType TC command or %c to quit : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (bQuit)
         break;
      if (inputResponseCnt > 0)
      {
         bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
         if (bCmdFound)
         {
            switch (cmd)
            {
               case TC_BASICOP_CMD_SET_CHAN_STATUS_ENABLE:
               case TC_BASICOP_CMD_SET_THERMO_COUPLE_TYPE:
               case TC_BASICOP_CMD_SET_SAMPLE_RATE:
               case TC_BASICOP_CMD_SET_COMP_TEMP:
               case TC_BASICOP_CMD_SET_CJC_ENABLE:
               case TC_BASICOP_CMD_SET_CJC_TYPE:
               case TC_BASICOP_CMD_SET_THRESH:
               case TC_BASICOP_CMD_CLEAR_STATUS:
               case TC_BASICOP_CMD_CHECK_POWER_ON_BIT:
               case TC_BASICOP_CMD_SET_OFFSET_TEMP:
               case TC_BASICOP_CMD_SET_BACKGROUND_OP_SUSPEND:
               case TC_BASICOP_CMD_TRIGGER_SYSTEM_CAL:
               case TC_BASICOP_CMD_TRIGGER_OPEN_CHECK:
               case TC_BASICOP_CMD_TRIGGER_BIT:
                  TC_BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)tc_basicOps_params);
                  break;
               default:
                  printf("\n\n\nInvalid command entered\n\n");
                  break;
            }
         }
         else
            printf("\n\n\nInvalid command entered\n\n");
      }
   }
 
}
 
/**************************************************************************************************************/
/**
<summary>
Display_TC_ChannelCfg illustrate the methods to call in the naibrd library to retrieve the configuration states
for basic operation.
</summary>
*/
/**************************************************************************************************************/
static void Display_TC_ChannelCfg(int32_t cardIndex, int32_t module, int32_t chan)
{
   printf("\n===============================================================\n");
   printf("CHANNEL %d\n", chan);
   printf("===============================================================\n");
   TC_Display_ThermoCoupleType(cardIndex, module, chan);
   TC_Display_Temperature(cardIndex, module, chan);
   TC_Display_Voltage(cardIndex, module, chan);
   TC_Display_SampleRate(cardIndex, module, chan);
   TC_Display_CompTemp(cardIndex, module, chan);
   TC_Display_CJCEnable(cardIndex, module, chan);
   TC_Display_CJCType(cardIndex, module, chan);
   TC_Display_OffsetTemp(cardIndex, module, chan);
   TC_Display_BackgroundOpSuspension(cardIndex, module, chan);
   TC_Display_Thresholds(cardIndex, module, chan);
   TC_Display_Statuses(cardIndex, module, chan);
   printf("\n===============================================================");
}
 
static void TC_Display_ThermoCoupleType(int32_t cardIndex, int32_t module, int32_t chan)
{
   bool_t isValidType = 1u;
   nai_tc_thermocouple_type_t TcType;
   char type = '\0';
   check_status(naibrd_TC_GetThermocoupleType(cardIndex, module, chan, &TcType));
 
   switch (TcType)
   {
      case NAI_TC_THERMOCOUPLE_TYPE_J:
         type = 'J';
         break;
      case NAI_TC_THERMOCOUPLE_TYPE_K:
         type = 'K';
         break;
      case NAI_TC_THERMOCOUPLE_TYPE_E:
         type = 'E';
         break;
      case NAI_TC_THERMOCOUPLE_TYPE_T:
         type = 'T';
         break;
      case NAI_TC_THERMOCOUPLE_TYPE_N:
         type = 'N';
         break;
      case NAI_TC_THERMOCOUPLE_TYPE_B:
         type = 'B';
         break;
      case NAI_TC_THERMOCOUPLE_TYPE_R:
         type = 'R';
         break;
      case NAI_TC_THERMOCOUPLE_TYPE_S:
         type = 'S';
         break;
      default:
         isValidType = 0u;
         break;
   }
 
   if (isValidType)
   {
      printf("\n%-35s %c\n", "ThermoCouple Type:", type);
   }
   else
   {
      printf("\n%-35s %s\n", "ThermoCouple Type:", "Invalid");
   }
}
 
static void TC_Display_Temperature(int32_t cardIndex, int32_t module, int32_t chan)
{
   float64_t cTemp = 0.0, fTemp = 0.0;
   check_status(naibrd_TC_GetTemperature(cardIndex, module, chan, NAI_TC_TEMP_TYPE_CELSIUS, &cTemp));
   check_status(naibrd_TC_GetTemperature(cardIndex, module, chan, NAI_TC_TEMP_TYPE_FAHRENHEIT, &fTemp));
 
   printf("%-35s %f C\n", "Temperature(Celsius):", cTemp);
   printf("%-35s %f F\n", "Temperature(Fahrenheit):", fTemp);
}
 
static void TC_Display_Voltage(int32_t cardIndex, int32_t module, int32_t chan)
{
   float64_t voltage = 0.0;
   check_status(naibrd_TC_GetVoltage(cardIndex, module, chan, &voltage));
 
   printf("%-35s %.3f microVolts\n", "Voltage:", voltage);
}
 
static void TC_Display_SampleRate(int32_t cardIndex, int32_t module, int32_t chan)
{
   float64_t rate = 0.0;
   check_status(naibrd_TC_GetSampleRate(cardIndex, module, chan, &rate));
 
   printf("%-35s %i Hz\n", "Sample Rate:", (int32_t)rate);
}
 
static void TC_Display_CompTemp(int32_t cardIndex, int32_t module, int32_t chan)
{
   float64_t temp = 0.0;
   check_status(naibrd_TC_GetCompTemperature(cardIndex, module, chan, &temp));
 
   printf("%-35s %f C\n", "Compensation Temperature:", temp);
}
 
static void TC_Display_CJCEnable(int32_t cardIndex, int32_t module, int32_t chan)
{
   bool_t enabled = FALSE;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(chan);
#endif
   check_status(naibrd_TC_GetCJCEnable(cardIndex, module, &enabled));
   printf("%-35s %s\n", "CJC Enabled:", enabled ? "True" : "False");
}
 
static void TC_Display_Statuses(int32_t cardIndex, int32_t module, int32_t chan)
{
   /* declare array to hold status bits */
   nai_status_bit_t statuses[NAI_TC_STATUS_TYPE_ENUM_COUNT];
 
   /* get status bits for the channel*/
   int i;
   for (i = 0; i < NAI_TC_STATUS_TYPE_ENUM_COUNT; i++)
   {
      check_status(naibrd_TC_GetStatus(cardIndex, module, chan, i, &statuses[i]));
   }
 
   /* print headers (hardcoded) */
   printf("\nStatus(latched):\n");
   printf("%-10s %-10s %-10s %-10s %-10s %-10s %-10s\n", "bit", "open", "alert_lo", "alarm_lo", "alert_hi", "alarm_hi", "summary");
   for (i = 0; i < 73; i++)
   {
      printf("-");
   }
   printf("\n");
 
   /* print status bits */
   for (i = 1; i < NAI_TC_STATUS_TYPE_ENUM_COUNT; i += 2)
   {
      printf("%-10i ", statuses[i]);
   }
 
}
 
static void TC_Display_Thresholds(int32_t cardIndex, int32_t module, int32_t chan)
{
   float64_t alert_lo, alarm_lo, alert_hi, alarm_hi;
   check_status(naibrd_TC_GetThreshold(cardIndex, module, chan, NAI_TC_THRESH_ALERT_LO, &alert_lo));
   check_status(naibrd_TC_GetThreshold(cardIndex, module, chan, NAI_TC_THRESH_ALARM_LO, &alarm_lo));
   check_status(naibrd_TC_GetThreshold(cardIndex, module, chan, NAI_TC_THRESH_ALERT_HI, &alert_hi));
   check_status(naibrd_TC_GetThreshold(cardIndex, module, chan, NAI_TC_THRESH_ALARM_HI, &alarm_hi));
   printf("\nThresholds:\n");
   printf("Alert Lo: %-13f C  Alarm Lo: %-13f C  \nAlert Hi: %-13f C  Alarm Hi: %-13f C\n", alert_lo, alarm_lo, alert_hi, alarm_hi);
}
 
static void TC_Display_CJCType(int32_t cardIndex, int32_t module, int32_t chan)
{
   nai_tc_comp_type_t type;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(chan);
#endif
   check_status(naibrd_TC_GetCompType(cardIndex, module, chan, &type));
 
   printf("%-35s ", "CJC Type:");
   switch (type)
   {
      case NAI_TC_COMP_TYPE_MANUAL:
         printf("Manual\n");
         break;
      case NAI_TC_COMP_TYPE_AUTO:
         printf("Auto\n");
         break;
      default:
         printf("Invalid CJC Type\n");
         break;
   }
}
 
static void TC_Display_OffsetTemp(int32_t cardIndex, int32_t module, int32_t chan)
{
   float64_t temp = 0.0;
   nai_status_t status = check_status(naibrd_TC_GetOffsetTemperature(cardIndex, module, chan, &temp));
 
   if (status == NAI_SUCCESS)
   {
      printf("%-35s %f C\n", "Offset Temperature:", temp);
   }
   else if (status == NAI_ERROR_NOT_SUPPORTED)
   {
      printf("%-35s Not supported\n", "Offset Temperature:");
   }
   else
   {
      printf("%-35s Unknown\n", "Offset Temperature:");
   }
}
 
static void TC_Display_BackgroundOpSuspension(int32_t cardIndex, int32_t module, int32_t chan)
{
   bool_t disabled = FALSE;
   nai_status_t status = check_status(naibrd_TC_GetBackgroundOpSuspend(cardIndex, module, chan, &disabled));
 
   if (status == NAI_SUCCESS)
   {
      printf("%-35s %s\n", "Background Ops Suspended:", disabled ? "True" : "False");
   }
   else if (status == NAI_ERROR_NOT_SUPPORTED)
   {
      printf("%-35s Not supported\n", "Background Ops Suspended:");
   }
   else
   {
      printf("%-35s Unknown\n", "Background Ops Suspended:");
   }
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Set_ChanStatusEnable handles the user request to enable or disable status reporting for the given channel
and calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Set_ChanStatusEnable(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t enable = 0u;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Enter Channel Status Enabled/Disabled setting to set (0 for Disabled, 1 for Enabled): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         enable = (bool_t)atoi((const char *)inputBuffer);
         switch (enable)
         {
            case FALSE:
            case TRUE:
               check_status(naibrd_TC_SetChanStatusEnable(cardIndex, module, chan, enable));
               break;
            default:
               printf("\n\n\nInvalid Channel Status Enable setting!\n\n");
               break;
         }
      }
      else
      {
         printf("\n\n\nInvalid Channel Status Enable setting!\n\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Set_ThermoCoupleType handles the user request to configure the thermo couple type for the given channel and
calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
 
static nai_status_t TC_Set_ThermoCoupleType(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   nai_tc_thermocouple_type_t type;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Enter new thermo couple type: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      switch (toupper(inputBuffer[0]))
      {
         case 'J':
            type = NAI_TC_THERMOCOUPLE_TYPE_J;
            break;
         case 'K':
            type = NAI_TC_THERMOCOUPLE_TYPE_K;
            break;
         case 'E':
            type = NAI_TC_THERMOCOUPLE_TYPE_E;
            break;
         case 'T':
            type = NAI_TC_THERMOCOUPLE_TYPE_T;
            break;
         case 'N':
            type = NAI_TC_THERMOCOUPLE_TYPE_N;
            break;
         case 'B':
            type = NAI_TC_THERMOCOUPLE_TYPE_B;
            break;
         case 'R':
            type = NAI_TC_THERMOCOUPLE_TYPE_R;
            break;
         case 'S':
            type = NAI_TC_THERMOCOUPLE_TYPE_S;
            break;
         default:
            printf("\n\n\nInvalid ThermoCouple Type\n\n");
            return bQuit;
      }
      check_status(naibrd_TC_SetThermocoupleType(cardIndex, module, chan, type));
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Set_SampleRate handles the user request to configure the sample rate for the given channel and
calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Set_SampleRate(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   float64_t rate = 0.0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Enter new sample rate: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         rate = atof((const char*)inputBuffer);
         check_status(naibrd_TC_SetSampleRate(cardIndex, module, chan, rate));
      }
      else
         printf("\n\n\nInvalid Sample Rate Entered\n\n");
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Set_CompTemp handles the user request to configure the compensation temperature for the given channel and
calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Set_CompTemp(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   float64_t temp = 0.0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Enter new compensation temperature: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         temp = atof((const char*)inputBuffer);
         check_status(naibrd_TC_SetCompTemperature(cardIndex, module, chan, temp));
      }
      else
         printf("\n\n\nInvalid Compensation Temperature Entered\n\n");
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Set_CJCEnable handles the user request to configure the cold junction compensation for the TC module and
calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Set_CJCEnable(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   bool_t bQuit = FALSE;
   bool_t enable = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Enable cold junction compensation? (1 - Yes, 0 - No): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         int response = atoi((const char*)inputBuffer);
         switch (response)
         {
            case 0:
               enable = FALSE;
               break;
            case 1:
               enable = TRUE;
               break;
            default:
               printf("\n\n\nInvalid Response\n\n");
               return bQuit;
         }
         check_status(naibrd_TC_SetCJCEnable(cardIndex, module, enable));
      }
      else
         printf("\n\n\nInvalid Response\n\n");
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Set_Thresh handles the user request to configure the threshold values for the given channel and
calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Set_Thresh(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   nai_tc_thresh_type_t type;
   float64_t value;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   /* get threshold type*/
   printf("Enter threshold type to set \n(0 - alert lo, 1 - alarm lo, 2 - alert hi, 3 - alarm hi):");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         int response = atoi((const char*)inputBuffer);
         switch (response)
         {
            case 0:
               type = NAI_TC_THRESH_ALERT_LO;
               break;
            case 1:
               type = NAI_TC_THRESH_ALARM_LO;
               break;
            case 2:
               type = NAI_TC_THRESH_ALERT_HI;
               break;
            case 3:
               type = NAI_TC_THRESH_ALARM_HI;
               break;
            default:
               printf("\n\n\nInvalid Threshold Type\n\n");
               return bQuit;
         }
      }
      else
      {
         printf("\n\n\nInvalid Threshold Type\n\n");
         return bQuit;
      }
   }
   else
      return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
 
   /* get threshold value*/
   printf("Enter threshold value:");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         value = atof((const char*)inputBuffer);
         check_status(naibrd_TC_SetThreshold(cardIndex, module, chan, type, value));
 
      }
      else
         printf("\n\n\nInvalid Threshold Value\n\n");
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_ClearStatus handles the user request to clear the status for the given status type and channel and
calls the relevant method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_ClearStatus(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   nai_tc_status_type_t type;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   /* get status type*/
   printf("Enter status type to clear\n");
   printf("(0 - bit, 1 - open, 2 - alert lo, 3 - alarm lo, 4 - alert hi, 5 - alarm hi, 6 - summary):");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         int response = atoi((const char*)inputBuffer);
         switch (response)
         {
            case 0:
               type = NAI_TC_STATUS_BIT_LATCHED;
               break;
            case 1:
               type = NAI_TC_STATUS_OPEN_LATCHED;
               break;
            case 2:
               type = NAI_TC_STATUS_ALERT_LO_LATCHED;
               break;
            case 3:
               type = NAI_TC_STATUS_ALARM_LO_LATCHED;
               break;
            case 4:
               type = NAI_TC_STATUS_ALERT_HI_LATCHED;
               break;
            case 5:
               type = NAI_TC_STATUS_ALARM_HI_LATCHED;
               break;
            case 6:
               type = NAI_TC_STATUS_SUMMARY_LATCHED;
               break;
            default:
               printf("\n\n\nInvalid Status Type\n\n");
               return bQuit;
         }
         check_status(naibrd_TC_ClearStatus(cardIndex, module, chan, type));
      }
      else
         printf("\n\n\nInvalid Status Type\n\n");
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_CheckPowerOnBIT handles the user request to check the power-on BIT completed state and
calls the relevant methods in the naibrd library. If the power-on BIT has completed,
the Latched BIT Status of each TC channel is checked.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_CheckPowerOnBIT(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   int32_t channelCount = 0;
   bool_t pBitComplete = FALSE;
   nai_status_bit_t bitStatus = 0u;
   char strBitStatus[12] = "";
   chan = 0;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   channelCount = naibrd_TC_GetChannelCount(g_TCModId);
 
   /* Check to see if PBIT ran for the module. */
   printf("Checking if the Power-On BIT test has run...\n");
   check_status(naibrd_TC_CheckPowerOnBITComplete(cardIndex, module, &pBitComplete));
   switch (pBitComplete)
   {
      case 0u:
         printf("\nPBIT Complete: NOT COMPLETED\n");
         break;
      case 1u:
         printf("\nPBIT Complete: COMPLETED\n");
         break;
      default:
         printf("\nPBIT Complete: UNKNOWN\n");
         break;
   }
 
   if (pBitComplete)
   {
      /* Read the BIT status */
      printf("Checking the result of the Power-on BIT test...\n");
      for (chan = 1; chan <= channelCount; chan++)
      {
         check_status(naibrd_TC_GetStatus(cardIndex, module, chan, NAI_TC_STATUS_BIT_LATCHED, &bitStatus));
         switch (bitStatus)
         {
            case 0:
               sprintf(strBitStatus, "BIT Passed");
               break;
            case 1:
               sprintf(strBitStatus, "BIT FAILED");
               break;
            default:
               sprintf(strBitStatus, "Unknown");
               break;
         }
         printf("Ch. %d: %s\n", chan, strBitStatus);
      }
   }
 
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Set_CJCType handles the user request to configure the cold junction compensation type for the TC module and
calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Set_CJCType(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   nai_tc_comp_type_t type;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Set CJC Type (1 - Manual, 0 - Auto): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         int response = atoi((const char*)inputBuffer);
         switch (response)
         {
            case 0:
               type = NAI_TC_COMP_TYPE_AUTO;
               break;
            case 1:
               type = NAI_TC_COMP_TYPE_MANUAL;
               break;
            default:
               printf("\n\n\nInvalid Response\n\n");
               return bQuit;
         }
         check_status(naibrd_TC_SetCompType(cardIndex, module, chan, type));
      }
      else
         printf("\n\n\nInvalid Response\n\n");
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Set_OffsetTemp handles the user request to configure the offset temperature for the given channel and
calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Set_OffsetTemp(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   float64_t temp = 0.0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Enter new offset temperature: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         temp = atof((const char*)inputBuffer);
         check_status(naibrd_TC_SetOffsetTemperature(cardIndex, module, chan, temp));
      }
      else
      {
         printf("\n\n\nInvalid Offset Temperature Entered\n\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Set_BackgroundOpSuspension handles the user request to suspend the BIT/Open-Line tests and
System Calibration for the given channel and calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Set_BackgroundOpSuspension(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   bool_t disable = FALSE;
   bool_t failed = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Suspend or enable BIT/Open-Line tests and System Calibration? (1 - Suspend, 0 - Enable): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         int response = atoi((const char*)inputBuffer);
         switch (response)
         {
            case 0:
               disable = FALSE;
               break;
            case 1:
               disable = TRUE;
               break;
            default:
               printf("\n\n\nInvalid Response\n\n");
               failed = TRUE;
               break;
         }
         if (failed == FALSE)
         {
            check_status(naibrd_TC_SetBackgroundOpSuspend(cardIndex, module, chan, disable));
         }
      }
      else
      {
         printf("\n\n\nInvalid Response\n\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Trigger_SystemCalibration handles the user request to trigger system calibration for the given channel and
calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Trigger_SystemCalibration(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Trigger System Calibration? (1 - Yes, 0 - No): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         int response = atoi((const char*)inputBuffer);
         switch (response)
         {
            case 0:
               break;
            case 1:
               check_status(naibrd_TC_TriggerBackgroundOperation(cardIndex, module, chan, NAI_TC_BACKGROUND_OP_SYSTEM_CAL));
               break;
            default:
               printf("\n\n\nInvalid Response\n\n");
               break;
         }
      }
      else
      {
         printf("\n\n\nInvalid Response\n\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Trigger_OpenCheck handles the user request to trigger an open-line check for the given channel and
calls the relevant setter method in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Trigger_OpenCheck(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Trigger Open-Line Check? (1 - Yes, 0 - No): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         int response = atoi((const char*)inputBuffer);
         switch (response)
         {
            case 0:
               break;
            case 1:
               check_status(naibrd_TC_TriggerBackgroundOperation(cardIndex, module, chan, NAI_TC_BACKGROUND_OP_OPEN));
               break;
            default:
               printf("\n\n\nInvalid Response\n\n");
               break;
         }
      }
      else
      {
         printf("\n\n\nInvalid Response\n\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
 
/**************************************************************************************************************/
/**
<summary>
TC_Trigger_BIT handles the user request to trigger BIT for the given channel and calls the relevant setter method
in the naibrd library.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t TC_Trigger_BIT(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_ad_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ad_params->cardIndex;
   int32_t module = p_ad_params->module;
   int32_t chan = p_ad_params->channel;
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
 
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
 
   printf("Trigger BIT? (1 - Yes, 0 - No): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (strlen((const char*)inputBuffer) > 0)
      {
         int response = atoi((const char*)inputBuffer);
         switch (response)
         {
            case 0:
               break;
            case 1:
               check_status(naibrd_TC_TriggerBackgroundOperation(cardIndex, module, chan, NAI_TC_BACKGROUND_OP_BIT));
               break;
            default:
               printf("\n\n\nInvalid Response\n\n");
               break;
         }
      }
      else
      {
         printf("\n\n\nInvalid Response\n\n");
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}