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

EtherScriptCommands

EtherScriptCommands

Explanation

*Explanation of the Sample C Code Application *

This C application is designed to interact with North Atlantic Industries (NAI) embedded function modules via Ethernet commands. Below is an explanation of the code with a focus on its structure, functions, and purpose.

Main Components:

  1. Header Files

    • Common Sample Program includes: These headers provide various functionalities such as menu display, querying, and access utilities for NAI boards.

    • NAI board includes: These headers define the interface with the embedded boards via Ethernet commands.

  2. Constants and Macros

    • CONFIG_FILE: The default script file for Ethernet configuration.

    • SCRIPT_TEST_REGISTER_COUNT, UNUSED_REG_ADDR_FOR_TEST, and TEST_REGISTER_STRIDE: Constants that define test register parameters.

  3. Enumerations and Command Tables

    • enum eth_script_commands: Enum defining various Ethernet script commands including write, read, clear, run, execute, etc.

    • ETH_ScriptcmdMenuCmds[]: Array of structs that map command names to their respective functions.

Functions:

Function Prototypes: - Script Command Functions: Different routines to handle Ethernet script commands like WriteEthScriptConfig, ReadEthScriptConfig, ClearEthScriptConfig, etc. - Helper Functions: Utility functions to initialize script commands, prompt user for input, display commands, etc.

Main Function: - Depending on the operating system, it defines the entry point of the program (main for general systems or EtherScriptCommands for VXWORKS). - Runs a loop to display the board menu and query the user to select a card index and run the script commands. - Handles exit commands and closes any open board cards.

Core Logic: - Run_EtherScriptCommands: This function handles executing the specific Ethernet script commands based on user input. - Command Execution Functions: Functions like WriteEthScriptConfig, ReadEthScriptConfig, and others execute Ethernet commands on the NAI boards. They query user for script IDs and register values, configure commands, and interact with the native NAI board functions. - Helper functions: - QueryEthScriptID, QueryEthTimeOut, QueryRegisterValue: Prompt user for input. - MakeWriteRegsCommandForScript: Format commands for writing to the script. - ParseScriptCommand, DisplayDecodedEthScriptCommand, DecodedScriptCmdEthFlags: Decode and display Ethernet commands.

Detailed Explanation of Key Functions:

Run_EtherScriptCommands: This is a looping function that repeatedly: - Displays the script command menu. - Queries the user for a command and executes the chosen command. - Each command is handled by corresponding functions from the ETH_ScriptcmdMenuCmds array.

WriteEthScriptConfig, ReadEthScriptConfig, ClearEthScriptConfig: These functions handle writing, reading, and clearing Ethernet script configurations: - WriteEthScriptConfig: Configures and sends a list of commands to the board for a specified Script ID. - ReadEthScriptConfig: Retrieves and displays the list of commands configured for a specified Script ID. - ClearEthScriptConfig: Clears the command list for a specified Script ID.

MakeWriteRegsCommandForScript: Formats the buffer for the Ethernet Write Registers command, based on parameters such as register address, data size, and count.

QueryEthScriptID, QueryEthTimeOut, QueryRegisterValue: Interactive functions that query the user for input related to script ID, Ethernet communication timeout, and register values.

DisplayDecodedEthScriptCommand: Decodes and displays the script commands stored in the buffer, providing insights into the command structure and parameters.

Summary: This application utilizes NAI libraries to interact with Ethernet-configured embedded modules. It offers a menu-driven interface for running various Ethernet script commands, facilitating configuration, execution, and management of scripts on NAI boards. Each function serves a specific purpose, ensuring modularity and clear workflow management within the code.

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

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

/* Function prototypes */
static bool_t Run_EtherScriptCommands(int32_t cardIndex);
static bool_t QueryEthScriptID(int32_t *scriptid);
static void InitScriptCommands(int32_t scriptid, uint16_t *count, uint32_t *cmdlen, uint8_t command[]);
static void MakeWriteRegsCommandForScript(bool_t bGen4Ether, bool_t bOnboard, uint16_t startIndex, uint32_t regaddr, uint32_t count, uint32_t stride, uint32_t data[], uint8_t commands[], uint16_t *cmdlen);
static nai_status_t WriteEthScriptConfig(int32_t paramCount, int32_t* p_params);
static nai_status_t ReadEthScriptConfig(int32_t paramCount, int32_t* p_params);
static nai_status_t ClearEthScriptConfig(int32_t paramCount, int32_t* p_params);
static nai_status_t ExecuteEthScript(int32_t paramCount, int32_t* p_params);
static nai_status_t SetSafeStateScriptID(int32_t paramCount, int32_t* p_params);
static nai_status_t RunEthScript(int32_t paramCount, int32_t* p_params);
static nai_status_t GetSafeStateScriptID(int32_t paramCount, int32_t* p_params);
static bool_t QueryEthTimeOut(uint32_t *timeout);
static nai_status_t SetEtherCommTimeout(int32_t paramCount, int32_t* p_params);
static nai_status_t GetEtherCommTimeout(int32_t paramCount, int32_t* p_params);
static bool_t QueryRegisterValue(uint32_t regaddr, uint32_t *regval);
static nai_status_t UpdateTestRegister(int32_t paramCount, int32_t* p_params);
static bool_t ParseScriptCommand(int32_t startIndex, int32_t cmdarraysize, uint8_t command[], uint16_t *cmdlen, int32_t scriptcmdarraysize, uint8_t script_command[]);
static void DisplayDecodedEthScriptCommand(uint16_t cmdcount, uint16_t cmdlen, uint8_t script_command[]);
static void DecodedScriptCmdEthFlags(uint16_t flags, uint8_t *onoffbrd, uint8_t *regsize);

static bool_t bGen4ScriptCommands = FALSE;

#define SCRIPT_TEST_REGISTER_COUNT        2          /* Number of test registers that script will be writing to */
static uint32_t UNUSED_REG_ADDR_FOR_TEST = 0x0180;   /* 0x0180 is an unused register in the Motherboard Common area */
static uint32_t TEST_REGISTER_STRIDE = 0x08;         /* 0x0180 and 0x0190 is an unused register in the Motherboard Common area */

/****** Command Table *******/
enum eth_script_commands
{
   ETH_SCRIPT_CMD_WRITE,
   ETH_SCRIPT_CMD_READ,
   ETH_SCRIPT_CMD_CLEAR,
   ETH_SCRIPT_CMD_RUN,
   ETH_SCRIPT_CMD_EXECUTE,
   ETH_SCRIPT_CMD_SET_SAFE_ID,
   ETH_SCRIPT_CMD_GET_SAFE_ID,
   ETH_SCRIPT_CMD_SET_COMM_TIMEOUT,
   ETH_SCRIPT_CMD_GET_COMM_TIMEOUT,
   ETH_SCRIPT_CMD_UPDATE_TEST_REG,
   ETH_SCRIPT_CMD_COUNT
};

/****** Command Tables *******/
naiapp_cmdtbl_params_t ETH_ScriptcmdMenuCmds[] = {
   {"Write",      "Write Script Configuration",  ETH_SCRIPT_CMD_WRITE,             WriteEthScriptConfig},
   {"Read",       "Read Script Configuration",   ETH_SCRIPT_CMD_READ,              ReadEthScriptConfig},
   {"Clear",      "Clear Script Configuration",  ETH_SCRIPT_CMD_CLEAR,             ClearEthScriptConfig},
   {"Run",        "Run Script with Output",      ETH_SCRIPT_CMD_RUN,               RunEthScript},
   {"Execute",    "Execute Script",              ETH_SCRIPT_CMD_EXECUTE,           ExecuteEthScript},
   {"SetID",      "Set Safe State Script ID",    ETH_SCRIPT_CMD_SET_SAFE_ID,       SetSafeStateScriptID},
   {"GetID",      "Get Safe State Script ID",    ETH_SCRIPT_CMD_GET_SAFE_ID,       GetSafeStateScriptID},
   {"SetTimeout", "Set Ethernet Comm Timeout",   ETH_SCRIPT_CMD_SET_COMM_TIMEOUT,  SetEtherCommTimeout},
   {"GetTimeout", "Get Ethernet Comm Timeout",   ETH_SCRIPT_CMD_GET_COMM_TIMEOUT,  GetEtherCommTimeout},
   {"Update",     "Update Test Registers",       ETH_SCRIPT_CMD_UPDATE_TEST_REG,   UpdateTestRegister},
};

/**************************************************************************************************************/
/**
<summary>
The purpose of the EtherScriptCommands is to illustrate the methods to call in the naibrd library to handle the
Ethernet Script Commands.

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 Ethernet routines.
 - ConfigDevice
 - DisplayDeviceCfg
 - GetBoardSNModCfg
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t EtherScriptCommands(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   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)
         {
            Run_EtherScriptCommands(cardIndex);
         }
         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>
This function runs the Ethernet Z-Block Commands program.
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_EtherScriptCommands(int32_t cardIndex)
{
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   bool_t bCmdFound = FALSE;
   int32_t cmd;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   naiapp_AppParameters_t  ether_params;
   p_naiapp_AppParameters_t etherscript_params = &ether_params;
   etherscript_params->cardIndex = cardIndex;
   /* Determine if the board selected supports the Generation 4 Ethernet Commands */
   bGen4ScriptCommands = SupportsGen4Ether(cardIndex);

   while (bContinue)
   {
      naiapp_utils_LoadParamMenuCommands(ETH_SCRIPT_CMD_COUNT, ETH_ScriptcmdMenuCmds); /*reload main menu*/
      naiapp_display_ParamMenuCommands((int8_t *)"Ethernet Script Command Menu");
      printf("\nType Ethernet Script command or %c to quit : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
            if (bCmdFound)
            {
               switch (cmd)
               {
               case ETH_SCRIPT_CMD_WRITE:
               case ETH_SCRIPT_CMD_READ:
               case ETH_SCRIPT_CMD_CLEAR:
               case ETH_SCRIPT_CMD_EXECUTE:
               case ETH_SCRIPT_CMD_RUN:
               case ETH_SCRIPT_CMD_SET_SAFE_ID:
               case ETH_SCRIPT_CMD_GET_SAFE_ID:
               case ETH_SCRIPT_CMD_SET_COMM_TIMEOUT:
               case ETH_SCRIPT_CMD_GET_COMM_TIMEOUT:
               case ETH_SCRIPT_CMD_UPDATE_TEST_REG:
                  ETH_ScriptcmdMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)etherscript_params);
                  break;
               default:
                  printf("Invalid command entered\n");
                  break;
               }
            }
            else
               printf("Invalid command entered\n");
         }
      }
      else
         bContinue = FALSE;
   }
   return bQuit;
}

/**************************************************************************************************************/
/**
<summary>
This function queries the user to enter the script id to apply the Write, Read, Clear, Execute, Safe State
Script commands.
</summary>
*/
/**************************************************************************************************************/
static bool_t QueryEthScriptID(int32_t *scriptid)
{
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("Enter the Script ID: (default: 1) > ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt == 0)
         *scriptid = 1;
      else
      {
         *scriptid = atol((const char *)inputBuffer);
      }
   }
   return bQuit;
}

/**************************************************************************************************************/
/**
<summary>
This function sets up the commands, based on scriptid, for the Write Script command.
</summary>
*/
/**************************************************************************************************************/
static void InitScriptCommands(int32_t scriptid, uint16_t *count, uint32_t *cmdlen, uint8_t command[])
{
   uint16_t msgIndex = 0;
   uint16_t cmdcnt = 0;
   uint16_t ethcmdlen = 0;

   uint16_t scriptcmdlen = 0;
   uint32_t data[SCRIPT_TEST_REGISTER_COUNT];
   int i, boardIndex;

   switch (scriptid)
   {
   case 1:
      /* Set Command to perform a Reset command (i.e. Write 1 to Register Address: NAI_GEN5_REG_SOFT_RESET) */
      data[0] = 1;
      MakeWriteRegsCommandForScript(bGen4ScriptCommands, TRUE, msgIndex, NAI_GEN5_REG_SOFT_RESET, 1, 0, data, command, &ethcmdlen);
      msgIndex += ethcmdlen;
      scriptcmdlen += ethcmdlen;
      cmdcnt++;
      break;
   default:
      /* Example of script with multiple commands with "reset" command as one of the commands */
      /* Set Command to Write to "scriptid | 0xDEAD0000" to unused registers UNUSED_REG_ADDR_FOR_TEST and
                                 "scriptid | 0xBEEF0000" to unused registers UNUSED_REG_ADDR_FOR_TEST + TEST_REGISTER_STRIDE */
      for (boardIndex = 0; boardIndex < naiapp_GetBoardCnt(); boardIndex++)
      {
         for (i = 0; i < SCRIPT_TEST_REGISTER_COUNT; i++)
         {
            if (i == 0)
               data[i] = scriptid | 0xDEAD0000;
            else if (i == 1)
               data[i] = scriptid | 0xBEEF0000;
            else
               data[i] = scriptid | 0xABCD0000;
         }
         if (boardIndex == 0)
            MakeWriteRegsCommandForScript(bGen4ScriptCommands, TRUE, msgIndex, UNUSED_REG_ADDR_FOR_TEST, SCRIPT_TEST_REGISTER_COUNT, TEST_REGISTER_STRIDE, data, command, &ethcmdlen);
         else
         {
            if (g_NAISysCfgAccess[boardIndex].comm == NAIBRD_COMM_VME)
               MakeWriteRegsCommandForScript(bGen4ScriptCommands, FALSE, msgIndex, g_NAISysCfgAccess[boardIndex].vmeCfg.boardAddress + UNUSED_REG_ADDR_FOR_TEST, SCRIPT_TEST_REGISTER_COUNT, TEST_REGISTER_STRIDE, data, command, &ethcmdlen);
            else if (g_NAISysCfgAccess[boardIndex].comm == NAIBRD_COMM_PCI)
               MakeWriteRegsCommandForScript(bGen4ScriptCommands, FALSE, msgIndex, g_NAISysCfgAccess[boardIndex].pciCfg.boardAddress + UNUSED_REG_ADDR_FOR_TEST, SCRIPT_TEST_REGISTER_COUNT, TEST_REGISTER_STRIDE, data, command, &ethcmdlen);
         }
         msgIndex += ethcmdlen;
         scriptcmdlen += ethcmdlen;
         cmdcnt++;
      }
      break;
   }

   *count = cmdcnt;
   *cmdlen = scriptcmdlen;
}

/**************************************************************************************************************/
/**
<summary>
This function formats the buffer for the Ethernet Write Registers command.
</summary>
*/
/**************************************************************************************************************/
static void MakeWriteRegsCommandForScript(bool_t bGen4Ether, bool_t bOnboard, uint16_t startIndex, uint32_t regaddr, uint32_t count, uint32_t stride, uint32_t data[], uint8_t commands[], uint16_t *cmdlen)
{
   uint16_t msgIndex = startIndex;
   uint16_t seqno;
   nai_intf_t intf;

   if (bGen4Ether)
   {
      /* Create a WriteRegs command */
      seqno = 0;
      if (bOnboard)
         intf = NAI_INTF_ONBOARD;
      else
         intf = 0;  /* Any value that is not NAI_INTF_ONBOARD */
      msgIndex = (uint16_t)nai_ether_BeginWriteMessage(&commands[startIndex],seqno,NAI_ETHER_GEN4,intf,regaddr,stride,count,NAI_REG32);
      if (msgIndex >= 0)
      {
         msgIndex = (uint16_t)nai_ether_WriteMessageData(&commands[startIndex],msgIndex,NAI_REG32,data,NAI_REG32,count);

         if (msgIndex >= 0)
         {
            msgIndex = (uint16_t)nai_ether_FinishMessage(&commands[startIndex],msgIndex,NAI_ETHER_GEN4);
         }
      }
      *cmdlen = msgIndex;
   }
}

/**************************************************************************************************************/
/**
<summary>
This function calls InitScriptCommands() to sets up the list of Ethernet cpmmands for the Write Script command
and calls naibrd_Ether_WriteScript() to send the WriteScript command to the board for the Script ID specified.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t WriteEthScriptConfig(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint8_t commands[MAX_ETHER_SCRIPT_CMD_CNT * MAX_ETHER_SCRIPT_CMD_LEN];
   uint16_t cmdcount = 0;
   uint32_t cmdlen = 0;
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;
   int32_t scriptid;

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

   bQuit = QueryEthScriptID(&scriptid);
   if (!bQuit)
   {
      InitScriptCommands(scriptid, &cmdcount, &cmdlen, commands);
      status = check_status(naibrd_Ether_WriteScript(cardIndex, (uint16_t)scriptid, cmdcount, cmdlen, commands));
      if (status == NAI_SUCCESS)
      {
         printf("Configured Script ID = %d.\n", scriptid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_ReadScript() to send the ReadScript command to the board to retrieve the list of
commands specified for the Script ID specified.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t ReadEthScriptConfig(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   int32_t scriptid;
   uint16_t cmdcount = 0;
   uint32_t arraysize = MAX_ETHER_SCRIPT_CMD_CNT * MAX_ETHER_SCRIPT_CMD_LEN;
   uint8_t commands[MAX_ETHER_SCRIPT_CMD_CNT * MAX_ETHER_SCRIPT_CMD_LEN];
   int32_t i, startIndex;
   uint16_t cmdlen;
   uint8_t script_command[MAX_ETHER_SCRIPT_CMD_LEN];
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;

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

   bQuit = QueryEthScriptID(&scriptid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_ReadScript(cardIndex, (uint16_t)scriptid, &cmdcount, arraysize, commands));
      if (status == NAI_SUCCESS)
      {
         if (cmdcount > 0)
         {
            startIndex = 0;
            for (i = 0; i < (int32_t)cmdcount; i++)
            {
               if (ParseScriptCommand(startIndex, arraysize, commands, &cmdlen, MAX_ETHER_SCRIPT_CMD_LEN, script_command))
               {
                  startIndex += cmdlen;
                  DisplayDecodedEthScriptCommand((uint16_t)i+1, cmdlen, script_command);
               }
            }
         }
         else
            printf("\n\nNo Commands configured for Script ID = %d\n", scriptid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_ClearScript() to send the ClearScript command to the board to remove the list of
commands specified for the Script ID specified.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t ClearEthScriptConfig(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;
   int32_t scriptid;

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

   bQuit = QueryEthScriptID(&scriptid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_ClearScript(cardIndex, (uint16_t)scriptid));

      if (status == NAI_SUCCESS)
      {
         printf("Cleared Script ID = %d.\n", scriptid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_RunScript() to send the ExecuteScript command to the board to execute the
commands specified for the Script ID specified. Run Script also returns the results of the run back to the caller.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t RunEthScript(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint8_t buffer[256];
   int i;
   int32_t recv_len = 0;
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;
   int32_t scriptid;

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

   bQuit = QueryEthScriptID(&scriptid);
   if (!bQuit)
   {

      /*
       * We make some assumptions in the test here.
       * Assumption 1: only one command being executed (because we only set a writeregs up top)
       * Assumption 2: buffer size 256 (because only one command being written -- This is overkill)
       */
      status = check_status(naibrd_Ether_RunScript(cardIndex, (uint16_t)scriptid, 1, 256, &recv_len, &buffer[0]));

      if (status == NAI_SUCCESS)
      {
         printf("Executed Script ID = %d.\n", scriptid);
         printf("Hex Dump of Output:\n");
         for (i = 0; i < recv_len; i++)
         {
            printf("%x", buffer[i]);
         }
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_ExecuteScript() to send the ExecuteScript command to the board to execute the
commands specified for the Script ID specified.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t ExecuteEthScript(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;
   int32_t scriptid;

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

   bQuit = QueryEthScriptID(&scriptid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_ExecuteScript(cardIndex, (uint16_t)scriptid));

      if (status == NAI_SUCCESS)
      {
         printf("Executed Script ID = %d.\n", scriptid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_SetSafeStateScriptId() to set the Script ID to use for Safe State mode, which
is triggered when the Ethernet communication between Ethernet Operation messages exceed the time specified
in the NoCommsWatchdogTimer register.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t SetSafeStateScriptID(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;
   int32_t scriptid;

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

   bQuit = QueryEthScriptID(&scriptid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_SetSafeStateScriptId(cardIndex, (uint16_t)scriptid));

      if (status == NAI_SUCCESS)
      {
         printf("Set Script ID = %d as Safe State Script\n", scriptid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_GetSafeStateScriptId() to retrieve the Script ID to use for Safe State mode, which
is triggered when the Ethernet communication between Ethernet Operation messages exceed the time specified
in the NoCommsWatchdogTimer register.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t GetSafeStateScriptID(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint16_t scriptid;
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;

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

   status = check_status(naibrd_Ether_GetSafeStateScriptId(cardIndex, &scriptid));
   if (status == NAI_SUCCESS)
   {
      printf("Set Script ID = %d as Safe State Script.\n", scriptid);
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function queries the user to enter the timeout value to set for NoCommsWatchdogTimer register.
</summary>
*/
/**************************************************************************************************************/
static bool_t QueryEthTimeOut(uint32_t *timeout)
{
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("Enter the Ethernet Comm Timeout: (default: 0) > ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt == 0)
         *timeout = 0;
      else
      {
         *timeout = (uint32_t)atol((const char *)inputBuffer);
      }
   }
   return bQuit;
}

/**************************************************************************************************************/
/**
<summary>
This function calls QueryEthTimeOut to prompt the user for the timeout value and calls
naibrd_Ether_SetNoCommsWatchdogTimer to set the value in the NoCommsWatchdogTimer register.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t SetEtherCommTimeout(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint32_t timeout;
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;

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

   bQuit = QueryEthTimeOut(&timeout);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_SetNoCommsWatchdogTimer(cardIndex, timeout));

      if (status == NAI_SUCCESS)
      {
         printf("Set Timeout = %d sec.\n", timeout);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_GetNoCommsWatchdogTimer() to retrieve the timeout value specified
in the NoCommsWatchdogTimer register.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t GetEtherCommTimeout(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint32_t timeout = 0;
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;

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

   status = check_status(naibrd_Ether_GetNoCommsWatchdogTimer(cardIndex, &timeout));

   if (status == NAI_SUCCESS)
   {
      printf("Timeout = %d sec.\n", timeout);
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function queries the user to enter the value to set for test registers that will be set in the Scripts.
</summary>
*/
/**************************************************************************************************************/
static bool_t QueryRegisterValue(uint32_t regaddr, uint32_t *regval)
{
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("Enter the Value (in hex) to set for Reg Addr: 0x%08X: (default: 0) > ", regaddr);
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt == 0)
         *regval = 0;
      else
      {
         *regval = naiapp_utils_HexStrToDecUInt32(inputBuffer);
      }
   }
   return bQuit;
}

/**************************************************************************************************************/
/**
<summary>
This function calls QueryRegisterValue to prompt the user for the register value and calls
naibrd_WriteReg32 to set the value in the test registers.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t UpdateTestRegister(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint32_t regAddr = UNUSED_REG_ADDR_FOR_TEST;
   uint32_t regVal = 0;
   int i;
   p_naiapp_AppParameters_t etherscript_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = etherscript_params->cardIndex;

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

   for (i = 0; i < SCRIPT_TEST_REGISTER_COUNT; i++)
   {
      bQuit = QueryRegisterValue(regAddr, &regVal);
      if (!bQuit)
      {
         status = check_status(naibrd_WriteReg32(cardIndex, 0, regAddr, regVal));
         if (status == NAI_SUCCESS)
         {
            printf("Set RegAddr = 0x%08X to 0x%08X\n", regAddr, regVal);
         }
         regAddr += TEST_REGISTER_STRIDE;
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function handles parsing the list of Ethernet commands for the next Ethenet command.
</summary>
*/
/**************************************************************************************************************/
static bool_t ParseScriptCommand(int32_t startIndex, int32_t cmdarraysize, uint8_t command[], uint16_t *cmdlen, int32_t scriptcmdarraysize, uint8_t script_command[])
{
   bool_t bParsed = FALSE;
   bool_t bContinueCopy = TRUE;
   uint16_t preamble, postamble;
   int32_t cmdIndex = startIndex;
   int32_t scriptIndex = 0;

   preamble = (command[startIndex] << 8) | command[startIndex+1];
   if (bGen4ScriptCommands)
   {
      if (preamble == ETHER_GEN4_PREAMBLE)
      {
         while ((bContinueCopy) && (scriptIndex < scriptcmdarraysize) && (cmdIndex < cmdarraysize-1))
         {
            postamble = (command[cmdIndex] << 8) | command[cmdIndex+1];
            if (postamble == ETHER_GEN4_POSTAMBLE)
            {
               script_command[scriptIndex++] = command[cmdIndex++];
               script_command[scriptIndex++] = command[cmdIndex++];
               bContinueCopy = FALSE;
            }
            else
            {
               script_command[scriptIndex++] = command[cmdIndex++];
            }
         }
         bParsed = TRUE;
         *cmdlen = (uint16_t)scriptIndex;
      }
   }
   else
   {
      printf("Ethernet Script Command Support Prior to Generation 4 Ethernet commands currently not supported\n");
   }
   return bParsed;
}

/**************************************************************************************************************/
/**
<summary>
This function handles decoding the Ethernet command and calling DecodedEthFlags() to decode the flags in the
command.
</summary>
*/
/**************************************************************************************************************/
static void DisplayDecodedEthScriptCommand(uint16_t cmdcount, uint16_t cmdlen, uint8_t script_command[])
{
   uint16_t typecode = 0;
   uint16_t msglen = 0;
   uint16_t flags = 0;
   uint32_t regaddr = 0, fifocntregaddr = 0;
   uint16_t regcount = 0;
   uint16_t regstride = 0;
   uint32_t maxfiforeads = 0;
   uint16_t maskop = 0;
   uint16_t mask_16 = 0, mask_val_16 = 0;
   uint32_t mask_32 = 0, mask_val_32 = 0;
   uint8_t  masktext[10];
   uint8_t  onoffbrd = 0;
   uint8_t  regsize = 0;
   int32_t  i, j;
   int32_t  cmdIndex, valuelen;

   if (bGen4ScriptCommands)
   {
      /* The Command must have at least 8 bytes in order to retrieve the TypeCode and MsgLen */
      if (cmdlen < 8)
         return;

      printf("Script Command %d:\n", cmdcount);
      /* Get the TypeCode */
      typecode = (script_command[4] << 8) | script_command[5];

      /* Get the Message Length */
      msglen =  (script_command[6] << 8) | script_command[7];
      msglen = msglen;

      switch(typecode)
      {
      case NAI_ETHER_TYPECODE_OP_NOP_4:
         break;
      case NAI_ETHER_TYPECODE_OP_READ_4:
      case NAI_ETHER_TYPECODE_OP_WRITE_4:
         /* Read/Write Reg Command must have at least 20 bytes */
         if (cmdlen < 20)
            return;
         flags = (script_command[8] << 8) | script_command[9];
         regaddr = (script_command[10] << 24) | (script_command[11] << 16) | (script_command[12] << 8) | script_command[13];
         regcount = (script_command[14] << 8) | script_command[15];
         regstride = (script_command[16] << 8) | script_command[17];
         break;
      case NAI_ETHER_TYPECODE_OP_READ_FIFO_4:
         /* Read FIFO Command must have at least 22 bytes */
         if (cmdlen < 22)
            return;
         flags = (script_command[8] << 8) | script_command[9];
         regaddr = (script_command[10] << 24) | (script_command[11] << 16) | (script_command[12] << 8) | script_command[13];
         fifocntregaddr = (script_command[14] << 24) | (script_command[15] << 16) | (script_command[16] << 8) | script_command[17];
         maxfiforeads = (script_command[18] << 8) | script_command[19];
         break;
      case NAI_ETHER_TYPECODE_OP_MASK_REG_4:
         /* Mask Reg Command must have at least 20 bytes */
         if (cmdlen < 20)
            return;
         flags = (script_command[8] << 8) | script_command[9];
         regaddr = (script_command[10] << 24) | (script_command[11] << 16) | (script_command[12] << 8) | script_command[13];
         maskop = (script_command[14] << 8) | script_command[15];
         break;
      case NAI_ETHER_TYPECODE_OP_MASK_VALUE_REG_4:
         /* Mask Reg Command must have at least 20 bytes */
         if (cmdlen < 20)
            return;
         flags = (script_command[8] << 8) | script_command[9];
         regaddr = (script_command[10] << 24) | (script_command[11] << 16) | (script_command[12] << 8) | script_command[13];
         break;
      }

      switch(typecode)
      {
      case NAI_ETHER_TYPECODE_OP_NOP_4:
         printf("   Typecode (0x%04X) :  NOP\n", typecode);
         break;
      case NAI_ETHER_TYPECODE_OP_READ_4:
         printf("   Typecode (0x%04X) :  Read Registers\n", typecode);
         DecodedScriptCmdEthFlags(flags, &onoffbrd, &regsize);
         if (onoffbrd == ETHER_GEN4_ONBOARD)
            printf("      Onboard,");
         else
            printf("      Offboard,");
         if (regsize == ETHER_GEN4_32_BIT_REG_SIZE)
            printf(" Reg Size: 32-bit,");
         else
            printf(" Reg Size: 16-bit,");
         printf(" Addr: 0x%08X, Count: %d, Stride: %d\n", regaddr, regcount, regstride);
         break;
      case NAI_ETHER_TYPECODE_OP_WRITE_4:
         printf("   Typecode (0x%04X) :  Write Registers\n", typecode);
         DecodedScriptCmdEthFlags(flags, &onoffbrd, &regsize);
         if (onoffbrd == ETHER_GEN4_ONBOARD)
            printf("      Onboard,");
         else
            printf("      Offboard,");
         if (regsize == ETHER_GEN4_32_BIT_REG_SIZE)
            printf(" Reg Size: 32-bit,");
         else
            printf(" Reg Size: 16-bit,");
         printf(" Addr: 0x%08X, Count: %d, Stride: %d\n", regaddr, regcount, regstride);
         if (regsize == ETHER_GEN4_32_BIT_REG_SIZE)
            valuelen = 4;
         else
            valuelen = 2;
         printf("         Data to write: ");
         cmdIndex = 18;
         for (i = 0; i < regcount; i++)
         {
            if (i != 0)
            {
               printf(",");
               if (i%10 == 0)
               {
                  printf("\n");
                  printf("                        ");
               }
            }
            printf("0x");
            for (j = 0; j < valuelen; j++)
               printf("%02X", script_command[cmdIndex++]);
         }
         printf("\n");
         break;
      case NAI_ETHER_TYPECODE_OP_READ_FIFO_4:
         printf("   Typecode (0x%04X) :  Read FIFO\n", typecode);
         DecodedScriptCmdEthFlags(flags, &onoffbrd, &regsize);
         if (onoffbrd == ETHER_GEN4_ONBOARD)
            printf("      Onboard,");
         else
            printf("      Offboard,");
         if (regsize == ETHER_GEN4_32_BIT_REG_SIZE)
            printf(" Reg Size: 32-bit,");
         else
            printf(" Reg Size: 16-bit,");
         printf(" FIFOAddr: 0x%08X, FIFOCntAddr: 0x%08X, MaxFIFORead: %d\n", regaddr, fifocntregaddr, maxfiforeads);
         break;
      case NAI_ETHER_TYPECODE_OP_MASK_REG_4:
         printf("   Typecode (0x%04X) :  Mask Reg\n", typecode);
         DecodedScriptCmdEthFlags(flags, &onoffbrd, &regsize);
         if (onoffbrd == ETHER_GEN4_ONBOARD)
            printf("      Onboard,");
         else
            printf("      Offboard,");
         switch (maskop)
         {
         case 0x0000:
            strcpy((char *)masktext, "Clear");
            break;
         case 0x0001:
            strcpy((char *)masktext, "Set");
            break;
         case 0x0002:
            strcpy((char *)masktext, "Toggle");
            break;
         default:
            strcpy((char *)masktext, "Unknown");
            break;
         }
         if (regsize == ETHER_GEN4_32_BIT_REG_SIZE)
         {
            /* Mask Reg Command with 32-bit mask must have at least 22 bytes */
            if (cmdlen < 22)
               printf(" Invalid 32-bit Mask Reg Command Len=%d\n", cmdlen);
            else
            {
               mask_32 = (script_command[16] << 24) | (script_command[17] << 16) | (script_command[18] << 8) | script_command[19];
               printf(" Reg Size: 32-bit,");
               printf(" Addr: 0x%08X %s 0x%08X\n", regaddr, masktext, mask_32);
            }
         }
         else
         {
            /* Mask Reg Command with 16-bit mask must have at least 20 bytes */
            if (cmdlen < 20)
               printf(" Invalid 16-bit Mask Reg Command Len=%d\n", cmdlen);
            else
            {
               mask_16 = (script_command[16] << 8) | script_command[17];
               printf(" Reg Size: 16-bit,");
               printf(" Addr: 0x%08X %s 0x%04X\n", regaddr, masktext, mask_16);
            }
         }
         break;
      case NAI_ETHER_TYPECODE_OP_MASK_VALUE_REG_4:
         printf("   Typecode (0x%04X) :  Mask Value Reg\n", typecode);
         DecodedScriptCmdEthFlags(flags, &onoffbrd, &regsize);
         if (onoffbrd == ETHER_GEN4_ONBOARD)
            printf("      Onboard,");
         else
            printf("      Offboard,");
         if (regsize == ETHER_GEN4_32_BIT_REG_SIZE)
         {
            /* Mask Value Reg Command with 32-bit mask must have at least 24 bytes */
            if (cmdlen < 24)
               printf(" Invalid 32-bit Mask Value Reg Command Len=%d\n", cmdlen);
            else
            {
               mask_val_32 = (script_command[14] << 24) | (script_command[15] << 16) | (script_command[16] << 8) | script_command[17];
               mask_32 = (script_command[18] << 24) | (script_command[19] << 16) | (script_command[20] << 8) | script_command[21];
               printf(" Reg Size: 32-bit,");
               printf(" Addr: 0x%08X 0x%08X 0x%08X\n", regaddr, mask_val_32, mask_32);
            }
         }
         else
         {
            /* Mask Value Reg Command with 16-bit mask must have at least 20 bytes */
            if (cmdlen < 20)
               printf(" Invalid 16-bit Mask Value Reg Command Len=%d\n", cmdlen);
            else
            {
               mask_val_16 = (script_command[14] << 8) | script_command[15];
               mask_16 = (script_command[16] << 8) | script_command[17];
               printf(" Reg Size: 16-bit,");
               printf(" Addr: 0x%08X 0x%04X 0x%04X\n", regaddr, mask_val_16, mask_16);
            }
         }
         break;
      }
   }
   else
   {
      printf("Ethernet Script Command Support Prior to Generation 4 Ethernet commands currently not supported\n");
   }
}

/**************************************************************************************************************/
/**
<summary>
This function handles decoding the flags in the Ethernet command.
</summary>
*/
/**************************************************************************************************************/
static void DecodedScriptCmdEthFlags(uint16_t flags, uint8_t *onoffbrd, uint8_t *regsize)
{
   if ((flags & ETHER_GEN4_ONOFFBOARD_MASK) > 0)
      *onoffbrd = ETHER_GEN4_OFFBOARD;
   else
      *onoffbrd = ETHER_GEN4_ONBOARD;

   if ((flags & ETHER_GEN4_16_32_REG_SIZE_MASK) > 0)
      *regsize = ETHER_GEN4_16_BIT_REG_SIZE;
   else
      *regsize = ETHER_GEN4_32_BIT_REG_SIZE;
}

Help Bot

X