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

REF BasicOps

REF BasicOps

Explanation

About the Sample Application Code:

This sample C application code is designed to demonstrate interaction with North Atlantic Industries (NAI) embedded function modules using their Software Support Kit (SSK). The application provides a menu-driven interface for setting various parameters and displaying measurements from the modules. The main functionalities include reading and setting frequencies, voltages, channel controls, and watchdog timer operations.

Key Elements and Structure:

  1. Header Inclusions:

    • The code includes standard C libraries for basic functionalities (<stdio.h>, <stdlib.h>, <string.h>, <time.h>, <math.h>).

    • Conditional inclusion is used to support multi-threading based on the operating system (LINUX, WIN32, VXWORKS).

    • NAI specific headers like naiapp_boardaccess_menu.h, naiapp_boardaccess_query.h, etc., are included for board access and display functionalities.

  2. Global Constants and Variables:

    • CONFIG_FILE: Specifies the configuration file used by the application (default_RefBasicOps.txt).

    • SAMPLE_WD_PGM_NAME: The name for the Watchdog operations menu ("REF Watchdog Operations").

    • terminateThread: A flag for controlling thread termination.

  3. Function Prototypes:

    • Functions are declared for various operations like setting frequencies, voltages, channel controls, output power, and watchdog timer settings.

  4. Enumerations:

    • Enumerates command indices for basic operations (ref_basicOpsMenu_commands) and watchdog commands (ref_watchdog_commands).

  5. Command Tables:

    • REF_BasicOpMenuCmds: Defines the command table for basic operations, associating command strings with their descriptions and corresponding functions.

    • REF_WatchdogOpMenuCmds: Defines the command table for watchdog operations.

  6. Main Function:

    • The entry point for the program (main on most platforms, REF_RunBasicOpsProgramSample for VxWorks).

    • Handles the overall application flow, including querying the user for cards and modules, running the selected menu operations, and handling user inputs for quitting or restarting.

  7. Menu and Handling Functions:

    • REFBasicMenu_Run: Entry function for running the basic operations menu. Handles user input for commands and executes the corresponding functions.

    • REFBasicMenu_DisplayMeasurements: Displays the current measurements like frequency, voltage, current, and channel status for each channel.

  8. Specific Operation Functions:

    • Functions like REFBasicMenu_SetFrequency, REFBasicMenu_SetVoltage, REFBasicMenu_SetChannelControl, REFBasicMenu_SetOutputPower, and REFBasicMenu_SetChannelReset handle the setting of respective parameters.

    • Watchdog Specific Functions:

    • Handle_REF_WatchdogShowMenu: Displays and handles the watchdog operations menu.

    • Handle_REF_WatchDogQuietTime and Handle_REF_WatchDogWindowTime: Set the quiet and window times for the watchdog timer.

    • Handle_REF_StrobeWatchdog: Starts a thread to continuously strobe the watchdog.

    • Handle_REF_kill_WDStrobe_Thread: Handles the stopping of the watchdog strobe thread.

  9. Thread Management Functions:

    • naiapp_kill_WDStrobe_Thread: Terminates the currently running watchdog strobe thread.

    • WD_Strobe_ThreadEntryPoint: The entry point for the strobing thread, which periodically sends strobe signals based on the defined quiet and window times.

Summary:

This sample application is a comprehensive demonstration of how to interface with NAI function modules using the SSK. It is designed to be platform-independent and uses multiple threads to handle asynchronous operations effectively. The menu-driven approach makes it interactive, allowing users to input various parameters and see real-time measurements and results.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#if defined (LINUX)
#include <pthread.h>
#endif

/* 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 "REF_Common.h"
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_ref.h"
#include "advanced/nai_ether_adv.h"

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

/* Function prototypes */
static bool_t REFBasicMenu_Run(int32_t cardIndex, int32_t module, uint32_t modid);
static bool_t REFBasicMenu_DisplayMeasurements(int32_t cardIndex, int32_t module, int32_t modid);

static nai_status_t REFBasicMenu_SetFrequency(int32_t paramCount, int32_t* p_params);
static nai_status_t REFBasicMenu_SetVoltage(int32_t paramCount, int32_t* p_params);
static nai_status_t REFBasicMenu_SetChannelControl(int32_t paramCount, int32_t* p_params);
static nai_status_t REFBasicMenu_SetOutputPower(int32_t paramCount, int32_t* p_params);
static nai_status_t REFBasicMenu_SetChannelReset(int32_t paramCount, int32_t* p_params);

static nai_status_t Handle_REF_WatchdogShowMenu(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_REF_WatchDogQuietTime(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_REF_WatchDogWindowTime(int32_t paramCount, int32_t* p_params);
static bool_t Handle_REF_DisplayWatchdog(int32_t cardIndex, int32_t module, int32_t chan);
static nai_status_t Handle_REF_StrobeWatchdog(int32_t paramCount, int32_t* p_params);
static nai_status_t Handle_REF_kill_WDStrobe_Thread(int32_t paramCount, int32_t* p_params);
static void naiapp_kill_WDStrobe_Thread();

static const int8_t *SAMPLE_WD_PGM_NAME = (const int8_t*)"REF Watchdog Operations";
static bool_t terminateThread;

#if defined (WIN32)
DWORD WINAPI WD_Strobe_ThreadEntryPoint(LPVOID param);
#elif defined (LINUX)
void* WD_Strobe_ThreadEntryPoint(void* arg);
#elif defined (__VXWORKS__)
static int WD_Strobe_ThreadEntryPoint(int32_t nParam);
#else
#error Unsupported OS
#endif
/* TX Thread */
#if defined (WIN32)
static HANDLE thread = NULL;
#elif defined (LINUX)
static pthread_t thread;
#elif defined (__VXWORKS__)
static int thread;
#else
#error Unsupported OS
#endif

enum ref_basicOpsMenu_commands
{
   REF_BASICMENU_SET_FREQUENCY,
   REF_BASICMENU_SET_VOLTAGE,
   REF_BASICMENU_SET_CHANNEL_CONTROL,
   REF_BASICMENU_SET_OUTPUT_POWER,
   REF_BASICMENU_SET_CHANNEL_RESET,
   REF_BASICOP_CMD_WATCHDOG_MENU,
   REF_BASICMENU_CMD_COUNT
};

enum ref_watchdog_commands
{
   REF_WD_CMD_QUIETTIME,
   REF_WD_CMD_WINDOWTIME,
   REF_WD_CMD_STROBE,
   REF_WD_CMD_KILL,
   REF_WD_CMD_BACK,
   REF_WD_CMD_COUNT
};

naiapp_cmdtbl_params_t REF_BasicOpMenuCmds[] =
{
   { "FREQ",        "Set Frequency",                      REF_BASICMENU_SET_FREQUENCY,                REFBasicMenu_SetFrequency        },
   { "VOLT",       "Set Voltage",                         REF_BASICMENU_SET_VOLTAGE,                  REFBasicMenu_SetVoltage          },
   { "CHAN",       "Set Channel Control",                 REF_BASICMENU_SET_CHANNEL_CONTROL,          REFBasicMenu_SetChannelControl   },
   { "POWR",       "Set Output Power",                    REF_BASICMENU_SET_OUTPUT_POWER,             REFBasicMenu_SetOutputPower      },
   {"WDT",         "Show Watchdog Menu Options",               REF_BASICOP_CMD_WATCHDOG_MENU,               Handle_REF_WatchdogShowMenu},
   { "REST",       "ResetChannel",                        REF_BASICMENU_SET_CHANNEL_RESET,            REFBasicMenu_SetChannelReset     }
};

naiapp_cmdtbl_params_t REF_WatchdogOpMenuCmds[REF_WD_CMD_COUNT] =
{
   {"BACK",           "Back to Main Menu",                             REF_WD_CMD_BACK,          NULL},
   {"TIME QUIET",     "Set Watchdog Quiet Time",                       REF_WD_CMD_QUIETTIME,     Handle_REF_WatchDogQuietTime},
   {"WINDOW",         "Set Watchdog Window Time",                      REF_WD_CMD_WINDOWTIME,    Handle_REF_WatchDogWindowTime},
   {"STROBE",         "Start thread to continuously strobe watchdog",  REF_WD_CMD_STROBE,        Handle_REF_StrobeWatchdog},
   {"KILL",           "Kill Watchdog strobing thread",                 REF_WD_CMD_KILL,          Handle_REF_kill_WDStrobe_Thread}
};

#if defined (__VXWORKS__)
int32_t REF_RunBasicOpsProgramSample(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))
               {
                  REFBasicMenu_Run(cardIndex, module, moduleID);
               }
            }
         }

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

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

   return 0;
}

static bool_t REFBasicMenu_Run(int32_t cardIndex, int32_t module, uint32_t modid)
{
   bool_t bQuit = FALSE, bCmdFound;
   int32_t cmd;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   naiapp_AppParameters_t  ref_basicops_params;
   p_naiapp_AppParameters_t ref_basicOps_params = &ref_basicops_params;
   ref_basicOps_params->cardIndex = cardIndex;
   ref_basicOps_params->module = module;
   ref_basicOps_params->modId = modid;
   ref_basicOps_params->maxChannels = naibrd_REF_GetChannelCount(modid);
   ref_basicOps_params->displayHex = FALSE;
   bQuit = naiapp_query_ChannelNumber(ref_basicOps_params->maxChannels, 1, &ref_basicOps_params->channel);

   naiapp_utils_LoadParamMenuCommands(REF_BASICMENU_CMD_COUNT, REF_BasicOpMenuCmds);
   do
   {
      REFBasicMenu_DisplayMeasurements(cardIndex, module, modid);
      naiapp_display_ParamMenuCommands((int8_t*)"MENU_TITLE");
      printf("\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)
      {
         bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
         if (bCmdFound)
         {
            switch (cmd)
            {
               case REF_BASICMENU_SET_FREQUENCY:
               case REF_BASICMENU_SET_VOLTAGE:
               case REF_BASICMENU_SET_CHANNEL_CONTROL:
               case REF_BASICMENU_SET_OUTPUT_POWER:
               case REF_BASICMENU_SET_CHANNEL_RESET:
               case REF_BASICOP_CMD_WATCHDOG_MENU:
                  //naiapp_query_ChannelNumber(ref_basicOps_params->maxChannels, 1, &ref_basicOps_params->channel);
                  //bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
                  REF_BasicOpMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)ref_basicOps_params);
                  break;
               default:
                  continue;
                  break;
            }
         }
         else printf("Invalid command entered\n");

      }
   } while (!bQuit);

   return TRUE;
}
static bool_t REFBasicMenu_DisplayMeasurements(int32_t cardIndex, int32_t module, int32_t modid)
{
   int32_t channel, MAX_CHANNEL = naibrd_REF_GetChannelCount((uint32_t)modid);
   float64_t frequencyOut = 0, voltageOut = 0, currentOut = 0;
   uint32_t powerControlOut = 0;
   bool_t overCurrent = FALSE;

   printf("\n\n ================================================== \n");
   printf("%7s%11s%9s%9s%8s%13s\n", "Chan", "Frequency", "Voltage", "Current", "Output", "OverCurrent");

   for (channel = 1; channel <= MAX_CHANNEL; channel++)
   {
      naibrd_REF_GetValueEx(cardIndex, module, channel, NAI_REF_FREQUENCY, &frequencyOut);
      naibrd_REF_GetMeasuredValueEx(cardIndex, module, channel, NAI_REF_MEASURED_VOLTAGE, &voltageOut);
      naibrd_REF_GetMeasuredValueEx(cardIndex, module, channel, NAI_REF_MEASURED_CURRENT, &currentOut);
      naibrd_REF_GetChannelEnable(cardIndex, module, channel, &powerControlOut);
      naibrd_REF_GetOverCurrentStatus(cardIndex, module, &overCurrent);

      printf("%4d%13.3f%10.3f%8.3f", channel, frequencyOut, voltageOut, currentOut);
      if (powerControlOut == TRUE)
         printf("%5s", "ON");
      else
         printf("%6s", "OFF");
      if (overCurrent == TRUE)
         printf("%10s\n", "TRUE");
      else
         printf("%11s\n", "FALSE");
   }

   return TRUE;
}

static nai_status_t REFBasicMenu_SetFrequency(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t freq = 0;
   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 channel = p_ad_params->channel;

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

   printf("Enter a frequency: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      freq = atoi((const char *)inputBuffer);
      check_status(naibrd_REF_SetValueEx(cardIndex, module, channel, NAI_REF_FREQUENCY, freq));
   }

   return NAI_SUCCESS;
}
static nai_status_t REFBasicMenu_SetVoltage(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   float64_t volt = 0;
   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 channel = p_ad_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Enter a voltage: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      volt = atoi((const char *)inputBuffer);
      check_status(naibrd_REF_SetValueEx(cardIndex, module, channel, NAI_REF_VOLTAGE, volt));
   }
   return NAI_SUCCESS;
}
static nai_status_t REFBasicMenu_SetChannelControl(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   uint32_t channelControl = 0;
   p_naiapp_AppParameters_t p_ref_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ref_params->cardIndex;
   int32_t module = p_ref_params->module;
   int32_t channel = p_ref_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Enter Channel Control: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      channelControl = atoi((const char *)inputBuffer);
      check_status(naibrd_REF_SetChannelEnable(cardIndex, module, channel, channelControl));
   }
   return NAI_SUCCESS;
}
static nai_status_t REFBasicMenu_SetOutputPower(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   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 channel = p_ad_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("Enter a Output Power (0 Off 1 On): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputBuffer[0] == '0')
         check_status(naibrd_REF_SetChannelEnable(cardIndex, module, channel, 0));
      else if (inputBuffer[0] == '1')
         check_status(naibrd_REF_SetChannelEnable(cardIndex, module, channel, 1));
   }
   return NAI_SUCCESS;
}
static nai_status_t REFBasicMenu_SetChannelReset(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 channel = p_ad_params->channel;
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   check_status(naibrd_REF_SetReset(cardIndex, module, channel, NAI_REF_RESET_OVERCURRENT));
   check_status(naibrd_REF_SetReset(cardIndex, module, channel, NAI_REF_RESET_VOLTAGE));
   return NAI_SUCCESS;
}
static nai_status_t Handle_REF_WatchdogShowMenu(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   bool_t bCmdFound = FALSE;
   int32_t cmd = 0;
   int32_t numMenuCmds = 0;
   p_naiapp_AppParameters_t p_ref_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ref_params->cardIndex;
   int32_t module = p_ref_params->module;
   int32_t chan = p_ref_params->channel;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   numMenuCmds = REF_WD_CMD_COUNT;
   naiapp_utils_LoadParamMenuCommands(numMenuCmds, REF_WatchdogOpMenuCmds);
   while (bContinue)
   {
      Handle_REF_DisplayWatchdog(cardIndex, module, chan);
      naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_WD_PGM_NAME);
      printf("\nType REF Watchdog command or %c to quit : main > watchdog >", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            if ((inputBuffer[0] == 'B') || (inputBuffer[0] == 'b'))
            {
               bContinue = FALSE;
            }
            else
            {
               bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
               if (bCmdFound)
               {
                  REF_WatchdogOpMenuCmds[cmd].func(paramCount, p_params);
               }
               else
               {
                  printf("\nInvalid command entered\n");
               }
            }
         }
      }
      else
         bContinue = FALSE;
   }
   numMenuCmds = REF_BASICMENU_CMD_COUNT;
   naiapp_utils_LoadParamMenuCommands(numMenuCmds, REF_BasicOpMenuCmds);

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static nai_status_t Handle_REF_WatchDogQuietTime(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   uint32_t quietTime = 0u;
   p_naiapp_AppParameters_t p_ref_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ref_params->cardIndex;
   int32_t module = p_ref_params->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("\r\n*** To use this sample strobe it is recommended to set a quiet time > 500 ms **");
   printf("\r\nEnter the desired Watchdog Quiet Time (ms): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         if (inputBuffer[0] == '-')
         {
            printf("\nInvalid value entered\n");
         }
         else
         {
            quietTime = atoi((const char *)inputBuffer);
            if (quietTime == 0u)
            {
               if (inputBuffer[0] == '0')
               {
                  check_status(naibrd_REF_SetWatchdogQuietTime(cardIndex, module, quietTime * 1000));
               }
               else
               {
                  printf("\nInvalid value entered\n");
               }
            }
            else
            {
               check_status(naibrd_REF_SetWatchdogQuietTime(cardIndex, module, quietTime * 1000));
            }
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static nai_status_t Handle_REF_WatchDogWindowTime(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   uint32_t windowTime = 0u;
   p_naiapp_AppParameters_t p_ref_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ref_params->cardIndex;
   int32_t module = p_ref_params->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("\r\n*** To use this sample strobe it is recommended to set a window time > 500 ms **");
   printf("\r\nEnter the desired Watchdog Window Time (ms): ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         if (inputBuffer[0] == '-')
         {
            printf("\nInvalid value entered\n");
         }
         else
         {
            windowTime = atoi((const char *)inputBuffer);
            if (windowTime == 0u)
            {
               if (inputBuffer[0] == '0')
               {
                  check_status(naibrd_REF_SetWatchdogWindow(cardIndex, module, windowTime * 1000));
               }
               else
               {
                  printf("\nInvalid value entered\n");
               }
            }
            else
            {
               check_status(naibrd_REF_SetWatchdogWindow(cardIndex, module, windowTime * 1000));
            }
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
static bool_t Handle_REF_DisplayWatchdog(int32_t cardIndex, int32_t module, int32_t chan)
{
   uint32_t wdStatLatched = 0u;
   uint32_t wdStatRT = 0u;
   uint32_t windowTime = 0u;
   uint32_t quietTime = 0u;

   printf("\n\nREF Watchdog Data:\n");
   check_status(naibrd_REF_GetWatchdogQuietTime(cardIndex, module, &quietTime));
   quietTime = quietTime / 1000;
   printf("Quiet Time: %d mS\n", quietTime);
   check_status(naibrd_REF_GetWatchdogWindow(cardIndex, module, &windowTime));
   windowTime = windowTime / 1000;
   printf("Window Time: %d mS\n", windowTime);

   check_status(naibrd_REF_GetChannelStatus(cardIndex, module, chan, NAI_REF_STATUS_WATCHDOG_TIMER_FAULT, NAI_REF_STATUS_LATCHED, &wdStatLatched));
   check_status(naibrd_REF_GetChannelStatus(cardIndex, module, chan, NAI_REF_STATUS_WATCHDOG_TIMER_FAULT, NAI_REF_STATUS_REALTIME, &wdStatRT));
   printf("WatchDog Status (R/L):  (%d/%d)\n", wdStatRT, wdStatLatched);

   printf("\n");

   return TRUE;
}

static nai_status_t Handle_REF_StrobeWatchdog(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   int32_t* arg = (int32_t*)malloc(sizeof(int32_t) * 3);
   p_naiapp_AppParameters_t p_ref_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ref_params->cardIndex;
   int32_t module = p_ref_params->module;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

   printf("\r\n**NOTE: When this thread/application exits, the module will shut off all outputs and will need to be power cycled in order to be operational **");
   printf("\r\nEnter Y if you want to continue and N to go back: ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt > 0)
      {
         if ((inputBuffer[0] == 'Y') || (inputBuffer[0] == 'y'))
         {
            printf("\r\nStrobing Watchdog every (QuietTime) + (Window)/2...");
            printf("\r\nStarting thread...");
            /* Spawn thread here */

            arg[0] = cardIndex;
            arg[1] = module;

#if defined (__VXWORKS__)
            if (thread == 0)
#elif defined (LINUX)
            if (thread == (pthread_t)NULL)
#else
            if (thread == (int32_t*)NULL)
#endif
            {
#if defined (WIN32)
               LPDWORD threadID = 0;
               thread = CreateThread(NULL, 0, WD_Strobe_ThreadEntryPoint, arg, 0, threadID);
#elif defined (LINUX)
               pthread_create(&thread, NULL, WD_Strobe_ThreadEntryPoint, arg);
#elif defined (__VXWORKS__)
               thread = taskSpawn("WD_Strobe_Thread", 100, 0, 10000, (FUNCPTR)WD_Strobe_ThreadEntryPoint, (int32_t)arg, 0, 0, 0, 0, 0, 0, 0, 0, 0);
#else
#error Unsupported OS
#endif
               if (thread != 0) {
               }
               else
               {
                  free(arg);
                  printf("\nFailed to Create Thread");
               }
            }
            else
            {
#if defined (WIN32)
               LPDWORD threadID = 0;
#endif
               /* kill previous thread and create new one. Report this to them. */
               naiapp_kill_WDStrobe_Thread();
#if defined (WIN32)
               thread = CreateThread(NULL, 0, WD_Strobe_ThreadEntryPoint, arg, 0, threadID);
#elif defined (LINUX)
               pthread_create(&thread, NULL, WD_Strobe_ThreadEntryPoint, arg);
#elif defined (__VXWORKS__)
               thread = taskSpawn("WD_Strobe_Thread", 100, 0, 10000, (FUNCPTR)WD_Strobe_ThreadEntryPoint, (int32_t)arg, 0, 0, 0, 0, 0, 0, 0, 0, 0);
#else
#error Unsupported OS
#endif

#if defined (__VXWORKS__)
               if (thread != 0) {
               }
#elif defined (LINUX)
               if (thread != (pthread_t)NULL) {
               }
#else
               if (thread != (int32_t*)NULL) {
               }
#endif
               else
               {
                  free(arg);
                  printf("\nFailed to Create Thread");
               }
            }
         }
         else
         {
            printf("\r\nReturning to Menu...");
         }
      }
   }

   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
            }
static void naiapp_kill_WDStrobe_Thread()
{
#if defined (__VXWORKS__)
   if (thread != 0)
   {
      terminateThread = TRUE;
      thread = 0;
   }
#elif defined (LINUX)
   if (thread != ((pthread_t)NULL))
   {
      terminateThread = TRUE;
      thread = ((pthread_t)NULL);
   }
#elif defined (LINUX)
   if (thread != ((pthread_t)NULL))
   {
      terminateThread = TRUE;
      thread = ((pthread_t)NULL);
   }
#else
   if (thread != ((int32_t*)NULL))
   {
      terminateThread = TRUE;
      thread = ((int32_t*)NULL);
   }
#endif
}

#if defined (WIN32)
DWORD WINAPI WD_Strobe_ThreadEntryPoint(LPVOID param)
#elif defined (LINUX)
void* WD_Strobe_ThreadEntryPoint(void* param)
#elif defined (__VXWORKS__)
static int WD_Strobe_ThreadEntryPoint(int32_t param)
#else
#error Unsupported OS
#endif
{
   uint32_t windowTime = 0u;
   uint32_t quietTime = 0u;
   int32_t delayTime = 0;
   int32_t* modInfo = (int32_t*)param;
   int32_t cardIndex = modInfo[0];
   int32_t module = modInfo[1];
   terminateThread = FALSE;
   free(modInfo);

   check_status(naibrd_REF_GetWatchdogQuietTime(cardIndex, module, &quietTime));
   check_status(naibrd_REF_GetWatchdogWindow(cardIndex, module, &windowTime));
   quietTime = quietTime / 1000;
   windowTime = windowTime / 1000;
   delayTime = quietTime + (windowTime / 2);
   check_status(naibrd_REF_WatchdogStrobe(cardIndex, module));
   do
   {
      nai_msDelay(delayTime);
      check_status(naibrd_REF_WatchdogStrobe(cardIndex, module));
   } while (!terminateThread);
   return NAI_SUCCESS;
}
static nai_status_t Handle_REF_kill_WDStrobe_Thread(int32_t paramCount, int32_t* p_params)
{
#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
   UNREFERENCED_PARAMETER(p_params);
#endif

   naiapp_kill_WDStrobe_Thread();
   return NAI_SUCCESS;
}

Help Bot

X