DS MSMB Ethernet
Edit this on GitLab
DS MSMB Ethernet
Explanation
About This Application Code
This sample application code from North Atlantic Industries (NAI) is used with their System Solution Kit (SSK) to interact with embedded function modules. The application enables the user to configure and control multi-speed settings across multiple boards via a command-line interface. Below is a brief explanation and walkthrough of the code.
File Inclusions
Standard Libraries - stdio.h: Standard input and output library. - stdlib.h: General utilities including memory management, program execution, and conversions. - string.h: Functions for manipulating strings. - time.h: Functions for manipulating and formatting time.
NAI Specific Libraries - nai: Core NAI definitions and functions. - naibrd: Board-specific definitions and functions. - nai_ar_utils.h: Utility functions for NAI applications. - naiapp_boardaccess_<…>: These include files provide functions for board access menu, querying, accessing, displaying, and utility operations. - functions/naibrd_ds.h: Definitions and functions for data streaming. - naibrd_ether.h: Functions related to Ethernet operations. - advanced/nai_ether_adv.h: Advanced Ethernet functions. - maps/nai_map_ds.h: Data streaming map definitions. - DS_MSMB_Ethernet.h: Definitions specific to multi-speed multi-board Ethernet operations.
Constants and Definitions
-
CONFIG_FILE: Path to the default configuration file.
-
Function prototypes for user prompts and setting functions.
-
MSMB_MenuCmds: Command table containing commands for multi-speed multi-board operations.
-
Data structure DsMultiSpdViaMultBoard: Stores multi-speed settings for different board pairs.
-
msvmbPairIdx: Default index for multi-speed via multi-board pairs.
-
gQuit: Flag to indicate if the application should quit.
-
Power states: DS_CHANNEL_POWER_ON and DS_CHANNEL_POWER_OFF.
Main Function
The main function serves as the application entry point. It initializes necessary variables and runs an interactive menu allowing the user to access, configure, and control multiple board settings.
-
naiapp_RunBoardMenu(CONFIG_FILE): Initializes board setting from the configuration file.
-
A loop allows continuous user interaction until a quit command is issued.
-
naiapp_query_CardIndex and naiapp_query_ModuleNumber: Interactively query the user for card index and module number.
-
Show_MSMBMenuFunc_Commands: Displays available commands.
-
naiapp_query_ForQuitResponse: Queries user input and checks for quit condition.
-
Command Execution: Based on user input, appropriate functions are executed.
Key Functions
Each function supports specific user interactions or configurations: - askForPairBoardIndex, askForCoarseCardNumber, askForCoarseModuleNumber, askForCoarseChannelNumber, askForFineCardNumber, askForFineModuleNumber, askForFineChannelNumber, askForTwoSpdRatio, and askForTwoSpdAngle: These functions ask the user to input configuration parameters for coarse and fine card indices, module numbers, channel numbers, speed ratios and angles. - Unified structure to prompt and collect user inputs. - Show_MSMBMenuFunc_Commands: Displays available commands for user interaction. - MSMB_SetPair: Sets the multi-speed via multi-board pair. - MSMB_SetPairProperty: Sets properties for the selected pair including card, module, channel numbers, speed ratios, and angles. - MSMB_SetNewAngle: Updates the speed angle for the selected pair. - MSMB_Write2Boards: Writes the new speed angle to the boards. - MSMB_PowerEnable: Toggles power state for the channels. - MSMB_Quit: Manages application quit command.
Application Flow
-
Initialization: The board configuration is loaded initially.
-
User Interaction: Through a loop, the user is prompted to input various settings.
-
Display Commands: Available commands are presented to the user.
-
Command Execution: Depending on the user’s input, respective configuration functions are called.
-
Continuous Interaction: The process repeats until the user decides to quit.
The comments in the provided code outline its workings and ensure smooth user interaction with the hardware modules. Additionally, each important segment is encapsulated in functions for modular design, making the code easy to maintain and extend.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.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"
#include "nai_ar_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_ds.h"
#include "naibrd_ether.h"
#include "advanced/nai_ether_adv.h"
#include "maps/nai_map_ds.h"
#include "DS_MSMB_Ethernet.h"
static const int8_t *CONFIG_FILE = (int8_t *)"default_DS_MSMB.txt";
/* Function prototypes */
static void askForPairBoardIndex(int32_t *pairIndex);
static void askForCoarseCardNumber(int32_t pairIndex);
static void askForCoarseModuleNumber(int32_t pairIndex);
static void askForCoarseChannelNumber(int32_t pairIndex);
static void askForFineCardNumber(int32_t pairIndex);
static void askForFineModuleNumber(int32_t pairIndex);
static void askForFineChannelNumber(int32_t pairIndex);
static void askForTwoSpdRatio(int32_t pairIndex);
static void askForTwoSpdAngle(int32_t pairIndex);
static void Show_MSMBMenuFunc_Commands();
static void MSMB_SetPair();
static void MSMB_SetPairProperty();
static void MSMB_SetNewAngle();
static void MSMB_Write2Boards();
static void MSMB_PowerEnable();
static void MSMB_Quit();
static struct msmbDemofunc_cmdtbl MSMB_MenuCmds[] = {
{"I", "Select MSMB Pair", MSMB_FUNC_SET_BOARD_PAIR, MSMB_SetPair},
{"P", "Select MSMB Property", MSMB_FUNC_SET_BOARD_PAIR_PROPERTY, MSMB_SetPairProperty},
{"A", "Set New Angle", MSMB_FUNC_SET_ANGLE, MSMB_SetNewAngle},
{"W", "Write New Angle to boards", MSMB_FUNC_WRITE_TO_BOARDS, MSMB_Write2Boards},
{"E", "Set D/S Power State", MSMB_FUNC_POWER_ENABLE, MSMB_PowerEnable},
{"Q", "Quit", MSMB_FUNC_QUIT, MSMB_Quit},
};
static nai_DsMSVMB DsMultiSpdViaMultBoard[MAX_MULTI_SPD_VIA_MULIT_BOARD_COUNT];
int32_t msvmbPairIdx = DEFAULT_MSVMB_PAIR_INDEX;
bool_t gQuit = FALSE;
#define DS_CHANNEL_POWER_ON 1
#define DS_CHANNEL_POWER_OFF 0
#if defined (__VXWORKS__)
int32_t DS_MSMB_Ethernet(void)
#else
int32_t main(void)
#endif
{
uint32_t cmdIdx=0;
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))
{
do
{
Show_MSMBMenuFunc_Commands();
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
for(cmdIdx = 0; cmdIdx < MSMB_FUNC_LAST; cmdIdx++)
{
if( 0 == naiapp_strnicmp( (const int8_t*)inputBuffer, (const int8_t*)MSMB_MenuCmds[cmdIdx].cmdstr, inputResponseCnt) )
break;
}
switch( cmdIdx )
{
case MSMB_FUNC_SET_BOARD_PAIR:
case MSMB_FUNC_SET_BOARD_PAIR_PROPERTY:
case MSMB_FUNC_SET_ANGLE:
case MSMB_FUNC_WRITE_TO_BOARDS:
case MSMB_FUNC_POWER_ENABLE:
case MSMB_FUNC_QUIT:
MSMB_MenuCmds[cmdIdx].func();
break;
default:
printf("Invalid command entered");
break;
}
}while(!gQuit);
}
}
}
}
}
return 0;
}
static void askForPairBoardIndex(int32_t *pairIndex)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPlease Enter Multi-Spd Via Multi-Board Pair Number: [default=%d]): ", DEFAULT_MSVMB_PAIR_INDEX);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
*pairIndex = (uint16_t)atol((const char *)inputBuffer);
}
else
*pairIndex = DEFAULT_MSVMB_PAIR_INDEX;
}
}
static void askForCoarseCardNumber(int32_t pairIndex)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPlease Enter Coarse Card Number for profile %d: [default=%d]): ",pairIndex, DEFAULT_COARSE_CARD_NUMBER);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
DsMultiSpdViaMultBoard[pairIndex].coarseCardidx = (uint16_t)atol((const char *)inputBuffer);
}
else
DsMultiSpdViaMultBoard[pairIndex].coarseCardidx = DEFAULT_COARSE_CARD_NUMBER;
}
}
static void askForCoarseModuleNumber(int32_t pairIndex)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPlease Enter Coarse Module Number for profile %d: [default=%d]): ", pairIndex, DEFAULT_COARSE_MODULE_NUMBER);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
DsMultiSpdViaMultBoard[pairIndex].coarseModuleNo = (uint16_t)atol((const char *)inputBuffer);
}
else
DsMultiSpdViaMultBoard[pairIndex].coarseModuleNo = DEFAULT_COARSE_MODULE_NUMBER;
}
}
static void askForCoarseChannelNumber(int32_t pairIndex)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPlease Enter Coarse Channel Number for profile %d: [default=%d]): ", pairIndex, DEFAULT_COARSE_CHAN_NUMBER);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
DsMultiSpdViaMultBoard[pairIndex].coarseChan = (uint16_t)atol((const char *)inputBuffer);
}
else
DsMultiSpdViaMultBoard[pairIndex].coarseChan = DEFAULT_COARSE_CHAN_NUMBER;
}
}
static void askForFineCardNumber(int32_t pairIndex)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPlease Enter Fine Card Number for profile %d: [default=%d]): ",pairIndex, DEFAULT_FINE_CARD_NUMBER);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
DsMultiSpdViaMultBoard[pairIndex].fineCardidx = (uint16_t)atol((const char *)inputBuffer);
}
else
DsMultiSpdViaMultBoard[pairIndex].fineCardidx = DEFAULT_FINE_CARD_NUMBER;
}
}
static void askForFineModuleNumber(int32_t pairIndex)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPlease Enter Fine Module Number for profile %d: [default=%d]): ", pairIndex, DEFAULT_FINE_MODULE_NUMBER);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
DsMultiSpdViaMultBoard[pairIndex].fineModuleNo = (uint16_t)atol((const char *)inputBuffer);
}
else
DsMultiSpdViaMultBoard[pairIndex].fineModuleNo = DEFAULT_FINE_MODULE_NUMBER;
}
}
static void askForFineChannelNumber(int32_t pairIndex)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPlease Enter Fine Channel Number for profile %d: [default=%d]): ", pairIndex, DEFAULT_FINE_CHAN_NUMBER);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
DsMultiSpdViaMultBoard[pairIndex].fineChan = (uint16_t)atol((const char *)inputBuffer);
}
else
DsMultiSpdViaMultBoard[pairIndex].fineChan = DEFAULT_FINE_CHAN_NUMBER;
}
}
static void askForTwoSpdRatio(int32_t pairIndex)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPlease Enter Two Speed Ratio for profile %d: [default=%d]): ",pairIndex, DEFAULT_TWO_SPEED_RATIO);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
DsMultiSpdViaMultBoard[pairIndex].multiSpdRatio = atol((const char *)inputBuffer);
}
else
DsMultiSpdViaMultBoard[pairIndex].multiSpdRatio = DEFAULT_TWO_SPEED_RATIO;
}
}
static void askForTwoSpdAngle(int32_t pairIndex)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPlease Enter Two Speed Angle for profile %d [default=%d]): ", pairIndex, DEFAULT_TWO_SPEED_ANGLE);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
DsMultiSpdViaMultBoard[pairIndex].multiSpdAngle = atof((const char *)inputBuffer);
}
else
DsMultiSpdViaMultBoard[pairIndex].multiSpdAngle = DEFAULT_TWO_SPEED_ANGLE;
}
}
static void Show_MSMBMenuFunc_Commands(void)
{
int i;
printf("\n\t\t MSMB User Menu.");
printf("\n=======================================\n");
printf("\n\nCommands");
printf( "\n--------");
for (i=0; i < MSMB_FUNC_LAST && MSMB_MenuCmds[i].cmdstr != NULL; i++)
printf ("\n%s\t%s", MSMB_MenuCmds[i].cmdstr, MSMB_MenuCmds[i].menustr);
printf("\n");
}
static void MSMB_SetPair()
{
askForPairBoardIndex(&msvmbPairIdx);
}
static void MSMB_SetPairProperty()
{
printf("\nCurrent MSMB Pair: %d",msvmbPairIdx);
askForCoarseCardNumber(msvmbPairIdx);
askForCoarseModuleNumber(msvmbPairIdx);
askForCoarseChannelNumber(msvmbPairIdx);
askForFineCardNumber(msvmbPairIdx);
askForFineModuleNumber(msvmbPairIdx);
askForFineChannelNumber(msvmbPairIdx);
askForTwoSpdRatio(msvmbPairIdx);
askForTwoSpdAngle(msvmbPairIdx);
/* Set the Card, Module and Channel information for Multi-Speed Configuration */
naibrd_DS_SetMultiSpeedViaMultiBoard( msvmbPairIdx,
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseCardidx,
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseModuleNo,
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseChan,
DsMultiSpdViaMultBoard[msvmbPairIdx].fineCardidx,
DsMultiSpdViaMultBoard[msvmbPairIdx].fineModuleNo,
DsMultiSpdViaMultBoard[msvmbPairIdx].fineChan,
NAI_DS_MSVMB_CONFIG,
DsMultiSpdViaMultBoard[msvmbPairIdx].multiSpdAngle
);
/* Set the Ratio for Multi_Speed Configuration */
naibrd_DS_SetMultiSpeedViaMultiBoard( msvmbPairIdx,
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseCardidx,
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseModuleNo,
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseChan,
DsMultiSpdViaMultBoard[msvmbPairIdx].fineCardidx,
DsMultiSpdViaMultBoard[msvmbPairIdx].fineModuleNo,
DsMultiSpdViaMultBoard[msvmbPairIdx].fineChan,
NAI_DS_MSVMB_RATIO,
DsMultiSpdViaMultBoard[msvmbPairIdx].multiSpdRatio
);
}
static void MSMB_SetNewAngle()
{
askForTwoSpdAngle(msvmbPairIdx);
}
static void MSMB_Write2Boards()
{
nai_status_t success;
/* Set the Angle for Multi_Speed Configuration */
success = naibrd_DS_SetMultiSpeedViaMultiBoard( msvmbPairIdx,
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseCardidx,
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseModuleNo,
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseChan,
DsMultiSpdViaMultBoard[msvmbPairIdx].fineCardidx,
DsMultiSpdViaMultBoard[msvmbPairIdx].fineModuleNo,
DsMultiSpdViaMultBoard[msvmbPairIdx].fineChan,
NAI_DS_MSVMB_ANGLE,
DsMultiSpdViaMultBoard[msvmbPairIdx].multiSpdAngle
);
if(success == NAI_SUCCESS)
printf("\nNew Angle:%f has been written to Board Pair:%d", DsMultiSpdViaMultBoard[msvmbPairIdx].multiSpdAngle, msvmbPairIdx);
else
printf("\nFailed to write New Angle:%f has been written to Board Pair:%d", DsMultiSpdViaMultBoard[msvmbPairIdx].multiSpdAngle, msvmbPairIdx);
}
static void MSMB_PowerEnable(void)
{
bool_t bPowerEnable = DS_CHANNEL_POWER_OFF;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPower setting 0(Off)/1(On) for pair index:%d (default: 0) : ", msvmbPairIdx);
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (inputResponseCnt == 0)
bPowerEnable = DS_CHANNEL_POWER_OFF;
else
{
if (inputBuffer[0] == '1')
bPowerEnable = DS_CHANNEL_POWER_ON;
else
bPowerEnable = DS_CHANNEL_POWER_OFF;
}
naibrd_DS_SetPowerEnable( DsMultiSpdViaMultBoard[msvmbPairIdx].coarseCardidx,\
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseModuleNo,\
DsMultiSpdViaMultBoard[msvmbPairIdx].coarseChan,\
bPowerEnable );
naibrd_DS_SetPowerEnable( DsMultiSpdViaMultBoard[msvmbPairIdx].fineCardidx,\
DsMultiSpdViaMultBoard[msvmbPairIdx].fineModuleNo,\
DsMultiSpdViaMultBoard[msvmbPairIdx].fineChan,\
bPowerEnable );
}
static void MSMB_Quit(void)
{
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nPress \'Q\' to quit ");
naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (inputResponseCnt > 0)
{
if( inputBuffer[0] == 'q' || inputBuffer[0] == 'Q')
gQuit = TRUE;
else
gQuit = FALSE;
}
}