EtherBlockCommands
Edit this on GitLab
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 = ð_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,®count, &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, ®count));
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;
}