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

EtherBlockCommands

EtherBlockCommands

Explanation

About This Code

This C program communicates with embedded function modules produced by North Atlantic Industries (NAI). The code illustrates the use of the NAI SSK library to handle Ethernet Block Commands. Below is a detailed walkthrough of the key components and functions used in the code:

Header Files

  • Standard Libraries:

  • <stdio.h>: Standard input and output functions.

  • <stdlib.h>: Standard library functions, including memory allocation, random numbers, and conversions.

  • <string.h>: String handling functions.

  • <time.h>: Time-related functions.

  • <ctype.h>: Character type functions.

  • NAI Sample Program Include Files:

  • naiapp_boardaccess_menu.h, naiapp_boardaccess_query.h, naiapp_boardaccess_access.h, naiapp_boardaccess_display.h, naiapp_boardaccess_utils.h: Specific headers for accessing NAI board functionalities and utilities.

  • NAI Board Include Files:

  • nai.h, naibrd.h, naibrd_ether.h: NAI board-specific headers.

  • advanced/nai_ether_adv.h: Advanced Ethernet functionalities.

Constants and Enumerations

  • CONFIG_FILE: Default Ethernet Block configuration file: "default_Ether_Block.txt".

  • Ethernet Block Commands Enumeration: Defines command types (ETH_BLOCK_CMD_SET, ETH_BLOCK_CMD_GET, ETH_BLOCK_CMD_CLEAR, ETH_BLOCK_CMD_READ, ETH_BLOCK_CMD_WRITE, ETH_BLOCK_CMD_COUNT).

Function Prototypes

  • Command Function Prototypes:

  • Run_EtherBlockCommands

  • QueryEthBlockID

  • InitBlockRegisters

  • InitBlockRegistersData

  • SetEthBlockConfig

  • GetEthBlockConfig

  • ClearEthBlockConfig

  • ReadEthBlockRegisters

  • WriteEthBlockRegisters

Command Table

Defined command table ETH_BlockcmdMenuCmds, which stores command names, descriptions, enums, and associated functions.

Default Register Constants

  • Default Register Count and Size:

  • DEF_REGISTER_COUNT: Number of registers for Block Configuration.

  • DEF_REGISTER_SIZE: Size of each register (32-bit).

Main Function

The main function starts execution and runs an application loop, querying the user for a card index and running the appropriate Ethernet block commands:

#if defined (__VXWORKS__)
int32_t EtherBlockCommands(void)  // For VXWORKS
#else
int32_t main(void)  // Main entry point
#endif
{
  // ...
}

It uses naiapp_RunBoardMenu to load the configuration file and system configuration routines. The application interacts with users to execute commands based on menu selections.

Helper Functions

  • Run_EtherBlockCommands: Main driver function that displays the Ethernet Block Command menu and executes selected commands.

  • QueryEthBlockID: Prompts the user to enter a block ID.

  • InitBlockRegisters & InitBlockRegistersData: Initialize registers and data for commands.

Ethernet Block Command Functions

Each of these functions handles specific Ethernet Block operations:

  • SetEthBlockConfig: Sets up register addresses and configures the block.

  • GetEthBlockConfig: Retrieves register addresses for the specified block.

  • ClearEthBlockConfig: Clears the block configuration.

  • ReadEthBlockRegisters: Reads data from registers for the specified block.

  • WriteEthBlockRegisters: Writes data to the registers for the specified block.

Each command function interacts with naibrd library functions such as naibrd_Ether_SetBlock, naibrd_Ether_GetBlock, naibrd_Ether_ClearBlock, etc., to perform the hardware interactions.

Board Query and Display Utilities

Utilities from the naiapp library are used for querying card indexes, displaying menus, and handling user input.

Summary

This code is a comprehensive example of using North Atlantic Industries' SSK to manage Ethernet block functionalities on their embedded systems. It allows you to set, get, clear, read, and write configurations and data to specified Ethernet blocks using a structured menu-driven command interface.

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

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

/* Function prototypes */
static bool_t Run_EtherBlockCommands(int32_t cardIndex);
static bool_t QueryEthBlockID(int32_t *blockid);
static void InitBlockRegisters(nai_intf_t *inf, uint32_t *count, uint32_t address[]);
static void InitBlockRegistersData(uint32_t count, uint32_t data[]);
static nai_status_t SetEthBlockConfig(int32_t paramCount, int32_t* p_params);
static nai_status_t GetEthBlockConfig(int32_t paramCount, int32_t* p_params);
static nai_status_t ClearEthBlockConfig(int32_t paramCount, int32_t* p_params);
static nai_status_t ReadEthBlockRegisters(int32_t paramCount, int32_t* p_params);
static nai_status_t WriteEthBlockRegisters(int32_t paramCount, int32_t* p_params);

static bool_t bGen4BlockCommands = FALSE;

/****** Command Table *******/
enum eth_block_commands
{
   ETH_BLOCK_CMD_SET,
   ETH_BLOCK_CMD_GET,
   ETH_BLOCK_CMD_CLEAR,
   ETH_BLOCK_CMD_READ,
   ETH_BLOCK_CMD_WRITE,
   ETH_BLOCK_CMD_COUNT
};

/****** Command Tables *******/
naiapp_cmdtbl_params_t ETH_BlockcmdMenuCmds[] = {
   {"Set",    "Set Block Configuration",    ETH_BLOCK_CMD_SET,    SetEthBlockConfig},
   {"Get",    "Get Block Configuration",    ETH_BLOCK_CMD_GET,    GetEthBlockConfig},
   {"Clear",  "Clear Block Configuration",  ETH_BLOCK_CMD_CLEAR,  ClearEthBlockConfig},
   {"Read",   "Read Block Registers",       ETH_BLOCK_CMD_READ,   ReadEthBlockRegisters},
   {"Write",  "Write to Block Registers",   ETH_BLOCK_CMD_WRITE,  WriteEthBlockRegisters},
};

/* Default Register Count and Register Size specified for the Block Commands.
   Change this to match the Register Count and Register Size for register specified in InitBlockRegisters() routine
*/
#define DEF_REGISTER_COUNT          18   /* Number of registers in Block Configuration */
#define DEF_REGISTER_SIZE           4    /* 32-bit Register Size */

/**************************************************************************************************************/
/**
<summary>
The purpose of the EtherBlockCommands is to illustrate the methods to call in the naibrd library to handle the
Ethernet Block 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 EtherBlockCommands(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_EtherBlockCommands(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 Block Commands program.
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_EtherBlockCommands(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  eth_params;
   p_naiapp_AppParameters_t etherblock_params = &eth_params;
   etherblock_params->cardIndex = cardIndex;

   /* Determine if the board selected supports the Generation 4 Ethernet Commands */
   /* TODO find 2.0 equiv for SupportsGen4Ether */
   bGen4BlockCommands = SupportsGen4Ether(cardIndex);

   while (bContinue)
   {
      naiapp_utils_LoadParamMenuCommands(ETH_BLOCK_CMD_COUNT, ETH_BlockcmdMenuCmds); /* reload main menu */
      naiapp_display_ParamMenuCommands((int8_t *)"Ethernet Block Command Menu");
      printf("\nType Ethernet Block 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_BLOCK_CMD_SET:
               case ETH_BLOCK_CMD_GET:
               case ETH_BLOCK_CMD_CLEAR:
               case ETH_BLOCK_CMD_READ:
               case ETH_BLOCK_CMD_WRITE:
                  ETH_BlockcmdMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)etherblock_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 block id to apply the Set, Get, Clear, Read and Write Block
commands.
</summary>
*/
/**************************************************************************************************************/
static bool_t QueryEthBlockID(int32_t *blockid)
{
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

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

/**************************************************************************************************************/
/**
<summary>
This function sets up the list of register addresses to included for the Set Block command.
</summary>
*/
/**************************************************************************************************************/
static void InitBlockRegisters(nai_intf_t *inf, uint32_t *count, uint32_t address[])
{
   int32_t index = 0;
   *inf = NAI_INTF_ONBOARD;
   *count = DEF_REGISTER_COUNT;
   /* Note, Change Default Register Size to match the register size for register specified below */
   if (bGen4BlockCommands)
   {
      /* Note: the address specified below for Motherboard and Module Common area are
               not currently not used by the system.
      */
      /* Motherboard Common area */
      address[index++] = 0x017C;       /*  1 */
      address[index++] = 0x0180;       /*  2 */
      address[index++] = 0x0190;       /*  3 */
      address[index++] = 0x0480;       /*  4 */
      address[index++] = 0x0494;       /*  5 */
      address[index++] = 0x04A0;       /*  6 */
      address[index++] = 0x04B8;       /*  7 */
      address[index++] = 0x04C4;       /*  8 */
      address[index++] = 0x04D0;       /*  9 */
      /* Module Common area - Writing to first available module on board */
      address[index++] = 0x40D0;       /* 10 */
      address[index++] = 0x40E0;       /* 11 */
      address[index++] = 0x40F0;       /* 12 */
      address[index++] = 0x4100;       /* 13 */
      address[index++] = 0x4104;       /* 14 */
      address[index++] = 0x4114;       /* 15 */
      address[index++] = 0x4128;       /* 16 */
      address[index++] = 0x4130;       /* 17 */
      address[index++] = 0x4134;       /* 18 */
   }
   else
   {
      printf("Ethernet Block Command Support Prior to Generation 4 Ethernet commands currently not supported\n");
   }
}

/**************************************************************************************************************/
/**
<summary>
This function sets up the data to write to list of register addresses for the Write Block command.
</summary>
*/
/**************************************************************************************************************/
static void InitBlockRegistersData(uint32_t count, uint32_t data[])
{
   uint32_t index = 0;
   for (index = 0; index < count; index++)
   {
      if (bGen4BlockCommands)
         data[index] = 0xABCD0000 + index + 1;  /* 32-bit register size */
      else
         data[index] = 0x1000 + index + 1;      /* 16 bit register size */
   }
}

/**************************************************************************************************************/
/**
<summary>
This function calls InitBlockRegisters() to sets up the list of register addresses for the Set Block command
and calls naibrd_Ether_SetBlock() to send the SetBlock command to the board for the Block ID specified.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t SetEthBlockConfig(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint32_t address[MAX_ETHER_BLOCK_REG_CNT];
   nai_intf_t inf;
   uint32_t regcount = 0;
   p_naiapp_AppParameters_t p_ethblock_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ethblock_params->cardIndex;
   int32_t blockid;

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

   bQuit = QueryEthBlockID(&blockid);
   if (!bQuit)
   {
      InitBlockRegisters(&inf,&regcount, &address[0]);
      status = check_status(naibrd_Ether_SetBlock(cardIndex,(uint16_t)blockid,inf,(uint32_t)DEF_REGISTER_SIZE,regcount,address));
      if (status == NAI_SUCCESS)
      {
         printf("Block ID = %d configured.\n", blockid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_GetBlock() to send the GetBlock command to the board to retrieve the list of
register addresses specified for the Block ID specified.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t GetEthBlockConfig(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint32_t arraysize = MAX_ETHER_BLOCK_REG_CNT;
   uint32_t address[MAX_ETHER_BLOCK_REG_CNT];
   uint32_t regcount;
   int32_t i;
   p_naiapp_AppParameters_t p_ethblock_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ethblock_params->cardIndex;
   int32_t blockid;

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

   bQuit = QueryEthBlockID(&blockid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_GetBlock(cardIndex, (uint16_t)blockid, arraysize, address, &regcount));

      if (status == NAI_SUCCESS)
      {
         if (regcount > 0)
         {
            printf("\n\nBlock ID = %d - %d Registers with Addresses:\n", blockid, regcount);
            for (i = 0; i < (int32_t)regcount; i++)
            {
               printf("%3d:  0x%08X\n", i+1, address[i]);
            }
         }
         else
            printf("\n\nNo Registers configured for Block ID = %d\n", blockid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_ClearBlock() to send the ClearBlock command to the board to remove the list of
register addresses specified for the Block ID specified.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t ClearEthBlockConfig(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   p_naiapp_AppParameters_t p_ethblock_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ethblock_params->cardIndex;
   int32_t blockid;

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

   bQuit = QueryEthBlockID(&blockid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_ClearBlock(cardIndex, (uint16_t)blockid));

      if (status == NAI_SUCCESS)
      {
         printf("Block ID = %d cleared\n", blockid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls naibrd_Ether_ReadBlock() to send the ReadBlock command to the board to retrieve the data
for the list of register addresses specified for the Block ID specified.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t ReadEthBlockRegisters(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint32_t arraysize = MAX_ETHER_BLOCK_REG_CNT;
   uint32_t data[MAX_ETHER_BLOCK_REG_CNT];
   uint32_t datacount = 0;
   int32_t i;
   p_naiapp_AppParameters_t p_ethblock_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ethblock_params->cardIndex;
   int32_t blockid;

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

   bQuit = QueryEthBlockID(&blockid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_ReadBlock(cardIndex, (uint16_t)blockid, (uint32_t)DEF_REGISTER_SIZE, arraysize, data, &datacount));

      if (status == NAI_SUCCESS)
      {
         if (datacount > 0)
         {
            printf("\n\nBlock ID = %d - %d Register Values:\n", blockid, datacount);
            for (i = 0; i < (int32_t)datacount; i++)
            {
               printf("%3d:  0x%08X\n", i+1, data[i]);
            }
         }
         else
            printf("\n\nNo Registers read for Block ID = %d\n", blockid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
/**
<summary>
This function calls InitBlockRegistersData() to set up the data to write to the list of registers and calls
naibrd_Ether_WriteBlock() to send the WriteBlock command to the board to write the data to the list of register
addresses specified for the Block ID specified.
</summary>
*/
/**************************************************************************************************************/
static nai_status_t WriteEthBlockRegisters(int32_t paramCount, int32_t* p_params)
{
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint32_t data[MAX_ETHER_BLOCK_REG_CNT];
   p_naiapp_AppParameters_t p_ethblock_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_ethblock_params->cardIndex;
   int32_t blockid;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif
   bQuit = QueryEthBlockID(&blockid);
   if (!bQuit)
   {
      InitBlockRegistersData(DEF_REGISTER_COUNT, &data[0]);
      status = check_status(naibrd_Ether_WriteBlock(cardIndex,(uint16_t)blockid,(uint32_t)DEF_REGISTER_SIZE,DEF_REGISTER_COUNT,data));
      if (status == NAI_SUCCESS)
      {
         printf("Block ID = %d Data written.\n", blockid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

Help Bot

X