Sync BasicOps
Edit this on GitLab
Sync BasicOps
Explanation
About the Sample Application Code
This C code is an application designed to interact with embedded function modules using North Atlantic Industries' (NAI) software support kit (SSK). It facilitates synchronization operations for Analog-to-Digital (AD) and Digital-to-Analog (DA) modules on NAI hardware. Below is an in-depth explanation and walkthrough of the code:
Header Inclusions
-
Standard Libraries: The application includes standard C libraries (
stdint.h
,stdio.h
,stdlib.h
,string.h
,time.h
,ctype.h
). -
NAI Common Sample Program Includes: These includes define functions, utilities, and menu interfaces needed to interact with the NAI hardware.
-
naiapp_boardaccess_menu.h
-
naiapp_boardaccess_query.h
-
naiapp_boardaccess_access.h
-
naiapp_boardaccess_display.h
-
naiapp_boardaccess_utils.h
-
nai_ad_utils.h
-
NAI Board/Core Includes: These includes provide definitions and functions specific to NAI boards and various modules.
-
nai.h
-
naibrd.h
-
naibrd_ad.h
-
naibrd_da.h
-
nai_ether_adv.h
-
naibrd_gen5.h
Constants and Type Definitions
-
File and Program Descriptions: These constants define the name of the sample program and configuration files.
c static const int8_t SAMPLE_PGM_NAME = (const int8_t *)"Synchronization Basic Operation Program"; static const int8_t *CONFIG_FILE = (const int8_t *)"default_Sync_BasicOps.txt"; static const char *DATA_FILE = (const char)"sync_data.txt";
-
Module Type Definitions: These definitions determine the module types (AD, DA, CM) based on masked module IDs.
c #define MOD_TYPE_MASK 0xFFFF0000u typedef uint32_t sync_module_type_t; #define MOD_TYPE_UNKNOWN (sync_module_type_t)0u; #define MOD_TYPE_AD (sync_module_type_t)(NAI_MODULE_ID_AD1 & MOD_TYPE_MASK) #define MOD_TYPE_DA (sync_module_type_t)(NAI_MODULE_ID_DA1 & MOD_TYPE_MASK) #define MOD_TYPE_CM (sync_module_type_t)(NAI_MODULE_ID_CME & MOD_TYPE_MASK)
-
Sync Information Structure: This structure stores synchronization details for different modules.
c typedef struct naiapp_syncInfo { int32_t cardIndex; int32_t moduleCount; int32_t modId[NAI_MAX_MODULES]; sync_module_type_t moduleType[NAI_MAX_MODULES]; int32_t triggerMasterModNum; int32_t channel[NAI_MAX_MODULES]; } naiapp_syncInfo_t;
Function Prototypes
-
Application Functions: Prototypes for various supporting functions.
c static bool_t SyncBasicOps_run(int32_t cardIndex, int32_t moduleCount); static void SyncBasicOps_displayConfigurations(int32_t paramCount, naiapp_syncInfo_t *p_syncInfo);
-
AD Basic Ops Command Functions: Functions to handle AD module operations.
c static nai_status_t SyncBasicOps_configClockSync(int32_t paramCount, int32_t* p_params); static nai_status_t SyncBasicOps_configFifo(int32_t paramCount, int32_t* p_params); static nai_status_t SyncBasicOps_clearFifo(int32_t paramCount, int32_t* p_params); static nai_status_t SyncBasicOps_triggerMaster(int32_t paramCount, int32_t* p_params); static nai_status_t SyncBasicOps_collectData(int32_t paramCount, int32_t* p_params);
-
Utilities and Sync Functions: Additional supporting functions.
c static bool_t SyncSupported(uint32_t modID); static const char* SyncModeString(naibrd_module_sync_mode_type_t mode); static bool_t GetMasterModule(naiapp_syncInfo_t *p_syncInfo, int32_t *p_masterModNum); static sync_module_type_t GetModuleType(uint32_t modID); static nai_status_t ConfigFifoSync(naiapp_syncInfo_t *p_syncInfo, int32_t modNum, naibrd_module_sync_mode_type_t mode, uint32_t trigCtrl); static nai_status_t SetFifoTriggers(naiapp_syncInfo_t *p_syncInfo, bool_t trigEnable); static nai_status_t GetModuleSyncMode(naiapp_syncInfo_t syncInfo, int32_t modNum, naibrd_module_sync_config_type_t config, naibrd_module_sync_mode_type_t *p_mode, int32_t *p_masterModNum); static nai_status_t ReadFIFO32(naiapp_syncInfo_t syncInfo, int32_t modNum, uint32_t *p_outRead);
Main Function
-
Entry Point: Depending on the system, it defines the
main()
function for standard systems orSync_BasicOps()
for VXWorks systems.c #if defined (VXWORKS) int32_t Sync_BasicOps(void) #else int32_t main(void) #endif
-
Execution Flow: The main function handles user interaction to process synchronization operations until the user chooses to quit.
c if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE) { while (!bQuit) { naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex); naibrd_GetModuleCount(cardIndex, &moduleCount); bQuit = SyncBasicOps_run(cardIndex, moduleCount); } printf("Type the Enter key to exit the program: "); bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt); }
-
Clean-Up: Closes all open cards before exiting.
c naiapp_access_CloseAllOpenCards();
SyncBasicOps_run Function
This function coordinates the synchronization of AD and DA modules. It displays configurations and processes user commands from a predefined command table.
Command Table
Defines a list of commands the user can issue to control synchronization operations:
enum sync_basicOps_commands {
SYNC_BASICOPS_CMD_CONFIG_CLOCK_SYNC,
SYNC_BASICOPS_CMD_CONFIG_FIFO,
SYNC_BASICOPS_CMD_CLEAR_FIFO,
SYNC_BASICOPS_CMD_SEND_FIFO_TRIGGER,
SYNC_BASICOPS_CMD_COLLECT_FIFO_DATA,
SYNC_BASICOPS_CMD_COUNT
};
naiapp_cmdtbl_params_t Sync_BasicOpsCmds[] = {
{"CS", "Configure Clock Sync", SYNC_BASICOPS_CMD_CONFIG_CLOCK_SYNC, SyncBasicOps_configClockSync },
{"CF", "Configure FIFO", SYNC_BASICOPS_CMD_CONFIG_FIFO, SyncBasicOps_configFifo },
{"CLF", "Clear FIFO contents", SYNC_BASICOPS_CMD_CLEAR_FIFO, SyncBasicOps_clearFifo },
{"TRIG", "Trigger Master to collect data on the Master and Slave.", SYNC_BASICOPS_CMD_SEND_FIFO_TRIGGER, SyncBasicOps_triggerMaster },
{"COLLECT", "Read the FIFO's and store the data to a file.", SYNC_BASICOPS_CMD_COLLECT_FIFO_DATA, SyncBasicOps_collectData }
};
Each command is associated with a function to handle specific tasks related to synchronization operations.
Additional Functions
Multiple functions are provided to configure and manage the synchronization process, handle FIFO settings, and collect data from the system.
Conclusion
This sample application code serves as a foundational tool for performing basic synchronization operations with the AD and DA modules on NAI hardware. It includes comprehensive functions to query, configure, and manage synchronization states, providing a robust interface to interact with the system effectively.
#include <stdint.h>
#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"
#include "nai_ad_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_ad.h"
#include "functions/naibrd_da.h"
#include "advanced/nai_ether_adv.h"
#include "boards/naibrd_gen5.h"
static const int8_t *SAMPLE_PGM_NAME = (const int8_t *)"Synchronization Basic Operation Program";
static const int8_t *CONFIG_FILE = (const int8_t *)"default_Sync_BasicOps.txt";
static const char *DATA_FILE = (const char*)"sync_data.txt";
/* Module Type definitions. The Module type is the 16 msb of the module ID. So module ID's like AD1, AD2, AD3, etc are
all AD module types. The module ID of ANY AD module can give us the module type by masking out the
lower 16 bits and retaining the upper 16 bits. This is true for all NAI modules (AD, DA, CM, etc).
*/
#define MOD_TYPE_MASK 0xFFFF0000u
typedef uint32_t sync_module_type_t;
#define MOD_TYPE_UNKNOWN (sync_module_type_t)0u;
#define MOD_TYPE_AD (sync_module_type_t)(NAI_MODULE_ID_AD1 & MOD_TYPE_MASK)
#define MOD_TYPE_DA (sync_module_type_t)(NAI_MODULE_ID_DA1 & MOD_TYPE_MASK)
#define MOD_TYPE_CM (sync_module_type_t)(NAI_MODULE_ID_CME & MOD_TYPE_MASK)
/* Structure to hold sync info. */
typedef struct naiapp_syncInfo
{
int32_t cardIndex;
int32_t moduleCount;
int32_t modId[NAI_MAX_MODULES];
sync_module_type_t moduleType[NAI_MAX_MODULES];
int32_t triggerMasterModNum;
int32_t channel[NAI_MAX_MODULES]; /*1 channel per module. */
} naiapp_syncInfo_t;
#define SYNC_PARAM_COUNT 6
/* Function prototypes */
static bool_t SyncBasicOps_run(int32_t cardIndex, int32_t moduleCount);
static void SyncBasicOps_displayConfigurations(int32_t paramCount, naiapp_syncInfo_t *p_syncInfo);
/* AD Basic Ops Command Functions */
static nai_status_t SyncBasicOps_configClockSync(int32_t paramCount, int32_t* p_params);
static nai_status_t SyncBasicOps_configFifo(int32_t paramCount, int32_t* p_params);
static nai_status_t SyncBasicOps_clearFifo(int32_t paramCount, int32_t* p_params);
static nai_status_t SyncBasicOps_triggerMaster(int32_t paramCount, int32_t* p_params);
static nai_status_t SyncBasicOps_collectData(int32_t paramCount, int32_t* p_params);
/* Application Functions */
static bool_t SyncSupported(uint32_t modID);
static const char* SyncModeString(naibrd_module_sync_mode_type_t mode);
static bool_t GetMasterModule(naiapp_syncInfo_t *p_syncInfo, int32_t *p_masterModNum);
static sync_module_type_t GetModuleType(uint32_t modID);
static nai_status_t ConfigFifoSync(naiapp_syncInfo_t *p_syncInfo, int32_t modNum, naibrd_module_sync_mode_type_t mode, uint32_t trigCtrl);
static nai_status_t SetFifoTriggers(naiapp_syncInfo_t *p_syncInfo, bool_t trigEnable);
static nai_status_t GetModuleSyncMode(naiapp_syncInfo_t syncInfo, int32_t modNum, naibrd_module_sync_config_type_t config,
naibrd_module_sync_mode_type_t *p_mode, int32_t *p_masterModNum);
static nai_status_t ReadFIFO32(naiapp_syncInfo_t syncInfo, int32_t modNum, uint32_t *p_outRead);
#define DEFAULT_CHANNEL 1
#define DEFAULT_NUM_FIFO_SAMPLES 100u
static float32_t fifoData[NAI_MAX_MODULES][DEFAULT_NUM_FIFO_SAMPLES];
/****** Command Table *******/
/* Invariant: enumeration of cmd table starts from 0 and increments by 1 */
enum sync_basicOps_commands
{
SYNC_BASICOPS_CMD_CONFIG_CLOCK_SYNC, /* Configure Clock Sync */
SYNC_BASICOPS_CMD_CONFIG_FIFO, /* Configure FIFO */
SYNC_BASICOPS_CMD_CLEAR_FIFO, /* Clear FIFO */
SYNC_BASICOPS_CMD_SEND_FIFO_TRIGGER, /* Trigger Master to collect data on the Master and Slave. */
SYNC_BASICOPS_CMD_COLLECT_FIFO_DATA, /* Read the FIFO's and stro the data to a file. */
SYNC_BASICOPS_CMD_COUNT
};
naiapp_cmdtbl_params_t Sync_BasicOpsCmds[] =
{
{"CS", "Configure Clock Sync", SYNC_BASICOPS_CMD_CONFIG_CLOCK_SYNC, SyncBasicOps_configClockSync },
{"CF", "Configure FIFO", SYNC_BASICOPS_CMD_CONFIG_FIFO, SyncBasicOps_configFifo },
{"CLF", "Clear FIFO contents", SYNC_BASICOPS_CMD_CLEAR_FIFO, SyncBasicOps_clearFifo },
{"TRIG", "Trigger Master to collect data on the Master and Slave.", SYNC_BASICOPS_CMD_SEND_FIFO_TRIGGER, SyncBasicOps_triggerMaster },
{"COLLECT", "Read the FIFO's and store the data to a file. ", SYNC_BASICOPS_CMD_COLLECT_FIFO_DATA, SyncBasicOps_collectData }
};
/*****************************************************************************/
/**
* <summary>
* The purpose of the AD_BasicOps is to illustrate the methods to call in the
* naibrd library to perform basic operations with the AD modules for
* configuration setup and reading the channels.
*
* 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 AD routines.
* - ConfigDevice
* - DisplayDeviceCfg
* - GetBoardSNModCfg
* - CheckModule
* </summary>
*/
/*****************************************************************************/
#if defined (__VXWORKS__)
int32_t Sync_BasicOps(void)
#else
int32_t main(void)
#endif
{
bool_t bQuit = FALSE;
int32_t cardIndex = -1;
int32_t moduleCount;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
while (!bQuit)
{
naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
naibrd_GetModuleCount(cardIndex, &moduleCount);
bQuit = SyncBasicOps_run(cardIndex, moduleCount);
}
printf("Type the Enter key to exit the program: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
naiapp_access_CloseAllOpenCards();
return 0;
}
/*****************************************************************************/
/**
* <summary>
* SyncBasicOps_run illustrates the channel configuration and prepares the menu
* which will handle user command requests. Returns TRUE if the user enters
* the Quit Command at any point within its scope.
* </summary>
*/
/*****************************************************************************/
static bool_t SyncBasicOps_run(int32_t cardIndex, int32_t moduleCount)
{
bool_t bQuit = FALSE;
bool_t bCmdFound = FALSE;
int32_t cmd;
naiapp_syncInfo_t syncInfo;
int32_t moduleIndex = 0;
naibrd_module_sync_mode_type_t syncMode;
int32_t triggerMasterModNum = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
syncInfo.cardIndex = cardIndex;
syncInfo.moduleCount = moduleCount;
syncInfo.triggerMasterModNum = 0;
for(moduleIndex = 0; moduleIndex < moduleCount; moduleIndex++)
{
syncInfo.channel[moduleIndex] = DEFAULT_CHANNEL;
syncInfo.modId[moduleIndex] = naibrd_GetModuleID(cardIndex, moduleIndex + 1);
syncInfo.moduleType[moduleIndex] = GetModuleType(syncInfo.modId[moduleIndex]);
if (FALSE != SyncSupported(syncInfo.modId[moduleIndex]))
{
switch(syncInfo.moduleType[moduleIndex])
{
case MOD_TYPE_AD:
check_status(naibrd_AD_SetFIFOSize(syncInfo.cardIndex, moduleIndex + 1, syncInfo.channel[moduleIndex],
DEFAULT_NUM_FIFO_SAMPLES));
check_status(naibrd_AD_GetModuleSyncMode(cardIndex, moduleIndex + 1, NAIBRD_SYNC_CONFIG_TRIGGER, &syncMode, &triggerMasterModNum));
if (NAIBRD_MODULE_SYNC_MODE_MASTER == syncMode)
{
syncInfo.triggerMasterModNum = triggerMasterModNum;
}
break;
case MOD_TYPE_DA:
check_status(naibrd_DA_SetFIFOSize(syncInfo.cardIndex, moduleIndex + 1, syncInfo.channel[moduleIndex],
DEFAULT_NUM_FIFO_SAMPLES));
break;
default:
printf("SyncBasicOps_run-> ERROR! Unsupported Module Type %u\n", syncInfo.moduleType[moduleIndex]);
break;
}
}
}
do
{
naiapp_utils_LoadParamMenuCommands(SYNC_BASICOPS_CMD_COUNT, Sync_BasicOpsCmds);
SyncBasicOps_displayConfigurations(SYNC_PARAM_COUNT, &syncInfo);
naiapp_display_ParamMenuCommands((int8_t*)SAMPLE_PGM_NAME);
printf("\n\nPlease enter a command or 'q' to quit:");
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)
{
Sync_BasicOpsCmds[cmd].func(SYNC_PARAM_COUNT, (int32_t*)&syncInfo);
}
else
{
printf("Invalid command entered\n");
}
}
}
} while (!bQuit);
return bQuit;
}
/*****************************************************************************/
/**
* <summary>
* ADBasicOps_displayConfigurations illustrates the methods to call in the naibrd library
* to retrieve the basic operation configuration states and status states
* as well as the current voltage reading for all channels.
* </summary>
*/
/*****************************************************************************/
static void SyncBasicOps_displayConfigurations(int32_t paramCount, naiapp_syncInfo_t* p_syncInfo)
{
int32_t modNum = 0;
naibrd_module_sync_mode_type_t clockMode = NAIBRD_MODULE_SYNC_MODE_DISABLED;
int32_t clockMasterModNum = 0;
naibrd_module_sync_mode_type_t triggerMode = NAIBRD_MODULE_SYNC_MODE_DISABLED;
int32_t triggerMasterModNum = 0;
uint32_t numSamplesPerTrigger = 0u;
uint32_t fifoCount = 0;
char szModID[] = "/0/0/0/0";
if (SYNC_PARAM_COUNT == paramCount)
{
printf("\n\n\n");
printf("------Module Info------ --------SyncClockConfig--------- --------SyncTriggerConfig------- -----------FIFO Setup----------\n");
printf(" ModNum ID SyncSupport Mode MasterModNum Mode MasterModNum Channel NumSamples FifoCount\n");
printf("----------------------------------------------------------------------------------------------------------------------------------\n");
for (modNum = 1; modNum <= p_syncInfo->moduleCount; modNum++)
{
naiapp_utils_ConvertModIdToAscii(p_syncInfo->modId[modNum-1], szModID);
if (FALSE != SyncSupported(p_syncInfo->modId[modNum-1]))
{
switch(p_syncInfo->moduleType[modNum-1])
{
case MOD_TYPE_AD:
check_status(naibrd_AD_GetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_CLOCK, &clockMode,
&clockMasterModNum));
check_status(naibrd_AD_GetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_TRIGGER, &triggerMode,
&triggerMasterModNum));
check_status(naibrd_AD_GetFIFOSize(p_syncInfo->cardIndex, modNum, p_syncInfo->channel[modNum-1], &numSamplesPerTrigger));
check_status(naibrd_AD_GetFIFOCount(p_syncInfo->cardIndex, modNum, p_syncInfo->channel[modNum-1], &fifoCount));
break;
case MOD_TYPE_DA:
/*
check_status(naibrd_DA_GetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_CLOCK, &clockMode,
&clockMasterModNum));
check_status(naibrd_DA_GetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_TRIGGER, &triggerMode,
&triggerMasterModNum));
*/
check_status(naibrd_DA_GetFIFOSize(p_syncInfo->cardIndex, modNum, p_syncInfo->channel[modNum-1], &numSamplesPerTrigger));
check_status(naibrd_DA_GetFIFOCount(p_syncInfo->cardIndex, modNum, p_syncInfo->channel[modNum-1], &fifoCount));
break;
default:
numSamplesPerTrigger = 0;
fifoCount = 0;
printf("SyncBasicOps_displayConfigurations-> ERROR! Unsupported Module Type %u\n", p_syncInfo->moduleType[modNum-1]);
break;
}
printf(" %d %s YES %-20s %d %-20s %d %-2d %u %u\n", modNum, szModID,
SyncModeString(clockMode), clockMasterModNum, SyncModeString(triggerMode), triggerMasterModNum, p_syncInfo->channel[modNum-1],
numSamplesPerTrigger, fifoCount);
}
else
{
printf(" %d %s NO --- --- --- --- --- --- ---\n",
modNum, szModID);
}
}
}
}
/*****************************************************************************/
/**
* <summary>
* ADBasicOps_setRangePolarity handles the user request to set the configuration states
* of Range and Polarity for the selected channel.
* </summary>
*/
/*****************************************************************************/
nai_status_t SyncBasicOps_configClockSync(int32_t paramCount, int32_t* p_params)
{
nai_status_t status = NAI_ERROR_UNKNOWN;
naiapp_syncInfo_t* p_syncInfo = (naiapp_syncInfo_t*)p_params;
int32_t modNum = 0;
int32_t masterModNum = 0;
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
int32_t modeSelect = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (SYNC_PARAM_COUNT == paramCount)
{
while (bContinue)
{
printf("Select module to configure (1-%d): ", p_syncInfo->moduleCount);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt >= 0)
{
modNum = (int32_t)atol((const char*)inputBuffer);
}
if ((modNum <= 0) || (modNum > p_syncInfo->moduleCount))
{
printf("ERROR: Invalid module value.\r\n\r\n");
}
else
{
bContinue = FALSE;
}
}
else
{
bContinue = FALSE;
}
}
if (!bQuit)
{
bContinue = TRUE;
while(bContinue)
{
printf("\n\nPlease select Clock Sync Mode for this module:\n");
printf(" 0) DISABLED: This module uses its internal clock and does not sync with other modules.\n");
printf(" 1) MASTER: This module supplies the clock to other slave modules.\n");
printf(" 2) SLAVE- USER CLOCK: This module syncs with a user supplied clock and supplies it to other slave modules.\n");
printf(" 3) SLAVE- INTERNAL CLOCK: This module receives the clock from a MASTER/USER CLOCK module.\n");
printf(" 4) SLAVE- EXTERNAL BOARD CLOCK: This module receives the clock that is supplied by an off-board master.\n");
printf("\n\nPlease enter your selection: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
modeSelect = (int32_t)atol((const char*)inputBuffer);
bContinue = FALSE;
switch (modeSelect)
{
case 0:
masterModNum = 0; /* 0 disables. */
status = check_status(naibrd_AD_SetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_CLOCK,
NAIBRD_MODULE_SYNC_MODE_DISABLED, masterModNum));
break;
case 1:
masterModNum = modNum; /* Master gets the clock from itself. */
status = check_status(naibrd_AD_SetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_CLOCK,
NAIBRD_MODULE_SYNC_MODE_MASTER, masterModNum));
break;
case 2:
bQuit = GetMasterModule(p_syncInfo, &masterModNum);
status = check_status(naibrd_AD_SetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_CLOCK,
NAIBRD_MODULE_SYNC_MODE_SLAVE_USER_CLOCK, masterModNum));
break;
case 3:
bQuit = GetMasterModule(p_syncInfo, &masterModNum);
status = check_status(naibrd_AD_SetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_CLOCK,
NAIBRD_MODULE_SYNC_MODE_SLAVE_INTERNAL, masterModNum));
break;
case 4:
bQuit = GetMasterModule(p_syncInfo, &masterModNum);
status = check_status(naibrd_AD_SetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_CLOCK,
NAIBRD_MODULE_SYNC_MODE_SLAVE_BOARD_CLOCK, masterModNum));
break;
default:
printf("ERROR: Invalid module value.\r\n\r\n");
bContinue = TRUE;
break;
}
}
else
{
printf("ERROR: Invalid module value.\r\n\r\n");
bContinue = TRUE;
}
}
else
{
bContinue = FALSE;
}
}
}
}
return status;
}
nai_status_t SyncBasicOps_configFifo(int32_t paramCount, int32_t* p_params)
{
nai_status_t status = NAI_ERROR_UNKNOWN;
naiapp_syncInfo_t* p_syncInfo = (naiapp_syncInfo_t*)p_params;
int32_t modNum = 0;
bool_t bContinue = TRUE;
bool_t bQuit = FALSE;
int32_t modeSelect = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (SYNC_PARAM_COUNT == paramCount)
{
while (bContinue)
{
printf("Select module to configure (1-%d): ", p_syncInfo->moduleCount);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt >= 0)
{
modNum = (int32_t)atol((const char*)inputBuffer);
}
if ((modNum <= 0) || (modNum > p_syncInfo->moduleCount))
{
printf("ERROR: Invalid module value.\r\n\r\n");
}
else
{
bContinue = FALSE;
}
}
else
{
bContinue = FALSE;
}
}
if (!bQuit)
{
bContinue = TRUE;
while(bContinue)
{
printf("\n\nPlease select FIFO Trigger Sync Mode for this module:\n");
printf(" 0) DISABLED: This module uses its internal FIFO Trigger and does not sync with other modules.\n");
printf(" 1) MASTER: This module supplies the FIFO Trigger to other slave modules.\n");
printf(" 2) SLAVE- USER TRIGGER: This module's FIFO is triggered externally and triggers the FIFOs on slave modules.\n");
printf(" 3) SLAVE- INTERNAL TRIGGER: This module's FIFO is triggered from a MASTER/USER TRIGGER module.\n");
printf(" 4) SLAVE- EXTERNAL BOARD TRIGGER: This module's FIFO is triggered by an off-board master.\n");
printf("\n\nPlease enter your selection: ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
modeSelect = (int32_t)atol((const char*)inputBuffer);
bContinue = FALSE;
switch (modeSelect)
{
case 0:
p_syncInfo->triggerMasterModNum = 0; /* 0 disables. */
status = ConfigFifoSync(p_syncInfo, modNum, NAIBRD_MODULE_SYNC_MODE_DISABLED, (uint32_t)NAI_AD_GEN5_FIFO_TRIG_STOP);
break;
case 1:
p_syncInfo->triggerMasterModNum = modNum; /* Master gets the clock from itself. */
status = ConfigFifoSync(p_syncInfo, modNum, NAIBRD_MODULE_SYNC_MODE_MASTER,
(uint32_t)(NAI_AD_GEN5_FIFO_TRIG_SOFT | NAI_AD_GEN5_FIFO_TRIG_CONTINUOUS));
break;
case 2:
bQuit = GetMasterModule(p_syncInfo, &(p_syncInfo->triggerMasterModNum));
status = ConfigFifoSync(p_syncInfo, modNum, NAIBRD_MODULE_SYNC_MODE_SLAVE_USER_CLOCK,
(uint32_t)(NAI_AD_GEN5_FIFO_TRIG_POS_EDGE | NAI_AD_GEN5_FIFO_TRIG_CONTINUOUS));
break;
case 3:
bQuit = GetMasterModule(p_syncInfo, &(p_syncInfo->triggerMasterModNum));
status = ConfigFifoSync(p_syncInfo, modNum, NAIBRD_MODULE_SYNC_MODE_SLAVE_INTERNAL,
(uint32_t)(NAI_AD_GEN5_FIFO_TRIG_POS_EDGE | NAI_AD_GEN5_FIFO_TRIG_CONTINUOUS));
break;
case 4:
bQuit = GetMasterModule(p_syncInfo, &(p_syncInfo->triggerMasterModNum));
status = ConfigFifoSync(p_syncInfo, modNum, NAIBRD_MODULE_SYNC_MODE_SLAVE_BOARD_CLOCK,
(uint32_t)(NAI_AD_GEN5_FIFO_TRIG_POS_EDGE | NAI_AD_GEN5_FIFO_TRIG_CONTINUOUS));
break;
default:
printf("ERROR: Invalid module value.\r\n\r\n");
bContinue = TRUE;
break;
}
naiapp_query_ChannelNumber(p_syncInfo->moduleCount, DEFAULT_CHANNEL, &(p_syncInfo->channel[modNum-1]));
}
else
{
printf("ERROR: Invalid module value.\r\n\r\n");
bContinue = TRUE;
}
}
else
{
bContinue = FALSE;
}
}
}
}
return status;
}
static nai_status_t SyncBasicOps_clearFifo(int32_t paramCount, int32_t* p_params)
{
naiapp_syncInfo_t *p_syncInfo = (naiapp_syncInfo_t*)p_params;
nai_status_t status = NAI_ERROR_UNKNOWN;
bool_t bQuit = FALSE;
int32_t startMod = 0;
int32_t endMod = 0;
int32_t modNum = 0;
bool_t bContinue = TRUE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (SYNC_PARAM_COUNT == paramCount)
{
while(bContinue)
{
printf("Please enter the module number of the FIFO to clear, or 'A' to clear all FIFOs [1-%d,A]:", p_syncInfo->moduleCount);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
if (inputBuffer[0] == 'A' || inputBuffer[0] == 'a')
{
startMod = 1;
endMod = p_syncInfo->moduleCount;
bContinue = FALSE;
}
else
{
startMod = endMod = (int32_t)atol((const char*)inputBuffer);
if ((endMod <= 0) || (endMod > p_syncInfo->moduleCount)
|| !SyncSupported(naibrd_GetModuleID(p_syncInfo->cardIndex, endMod)))
{
printf("ERROR: Invalid module value.\r\n\r\n");
}
else
{
bContinue = FALSE;
}
}
}
else
{
printf("ERROR: Invalid module value.\r\n\r\n");
}
}
}
if (!bQuit)
{
for(modNum = startMod; modNum <= endMod; modNum++)
{
switch(p_syncInfo->moduleType[modNum-1])
{
case MOD_TYPE_AD:
status = check_status(naibrd_AD_ClearFIFO(p_syncInfo->cardIndex, modNum, p_syncInfo->channel[modNum-1]));
break;
case MOD_TYPE_DA:
status = check_status(naibrd_DA_ClearFIFO(p_syncInfo->cardIndex, modNum, p_syncInfo->channel[modNum-1]));
break;
default:
break;
}
}
}
}
return status;
}
nai_status_t SyncBasicOps_triggerMaster(int32_t paramCount, int32_t* p_params)
{
naiapp_syncInfo_t *p_syncInfo = (naiapp_syncInfo_t*)p_params;
nai_status_t status = NAI_ERROR_UNKNOWN;
uint32_t fifoCount = 0u;
uint32_t samplesToCollect = 0u;
if (SYNC_PARAM_COUNT == paramCount)
{
if ((0 != p_syncInfo->triggerMasterModNum) && SyncSupported(p_syncInfo->modId[p_syncInfo->triggerMasterModNum-1]))
{
switch(p_syncInfo->moduleType[p_syncInfo->triggerMasterModNum])
{
case MOD_TYPE_AD:
/* Enable the fifo's to collect data. Once enabled, fifo's will continue to collect until they reach FIFOSize. If data is
removed from the fifo while it's enabled, the fifo will begin collecting again until it reaches FIFOSize. The fifo needs
to be disabled after the collection in order to access the data without collecting more. */
SetFifoTriggers(p_syncInfo, TRUE);
printf("Triggering FIFO on AD module %d (all slaves will trigger as well)...", p_syncInfo->triggerMasterModNum);
status = check_status(naibrd_AD_SoftwareTrigger(p_syncInfo->cardIndex, p_syncInfo->triggerMasterModNum));
printf("Trigger Complete. FIFO is collecting data.\n");
printf("Waiting for data collection to complete...");
check_status(naibrd_AD_GetFIFOSize(p_syncInfo->cardIndex, p_syncInfo->triggerMasterModNum,
p_syncInfo->channel[p_syncInfo->triggerMasterModNum - 1], &samplesToCollect));
/* Keep checking the fifo count of the master until it is equal to FifoSize(numSamplesPerTrigger). All slave fifos will collect
data at the same rate, so only check one module (in this case the master) to see when data collection is complete. */
do
{
check_status(naibrd_AD_GetFIFOCount(p_syncInfo->cardIndex, p_syncInfo->triggerMasterModNum,
p_syncInfo->channel[p_syncInfo->triggerMasterModNum - 1], &fifoCount));
} while (fifoCount < samplesToCollect);
printf("DONE.\n");
/* Disable the fifos to stop them from collecting data when we go to removed it (or clear it) from the fifo. */
SetFifoTriggers(p_syncInfo, FALSE);
break;
case MOD_TYPE_DA:
printf("Triggering FIFO on DA module %d.\n", p_syncInfo->triggerMasterModNum);
status = check_status(naibrd_DA_SoftwareTrigger(p_syncInfo->cardIndex, p_syncInfo->triggerMasterModNum));
break;
default:
status = NAI_ERROR_INVALID_MODULE;
break;
}
}
else
{
printf("Module %d does not support sync.\n", p_syncInfo->triggerMasterModNum);
status = NAI_ERROR_INVALID_MODULE;
}
}
return status;
}
nai_status_t SyncBasicOps_collectData(int32_t paramCount, int32_t* p_params)
{
naiapp_syncInfo_t *p_syncInfo = (naiapp_syncInfo_t*)p_params;
int32_t modNum = 0;
naibrd_module_sync_mode_type_t mode;
int32_t masterModNum = 0;
nai_status_t status = NAI_ERROR_UNKNOWN;
int32_t dataIndex = 0;
char line[500];
char tmpString[50];
uint32_t read[NAI_MAX_MODULES];
FILE *dataFile = fopen(DATA_FILE, "w");
if (SYNC_PARAM_COUNT == paramCount)
{
if (NULL == dataFile)
{
printf("Can not open file %s\n", DATA_FILE);
}
else
{
memset(read, 0, sizeof(read));
/* loop through all modules and save the fifo data on the modules that are not disabled (some mode of sync enabled). */
sprintf(line, "%s", "Index ");
for (modNum = 1; modNum <= p_syncInfo->moduleCount; modNum++)
{
status = GetModuleSyncMode(*p_syncInfo, modNum, NAIBRD_SYNC_CONFIG_TRIGGER, &mode, &masterModNum);
if (NAIBRD_MODULE_SYNC_MODE_DISABLED != mode)
{
status = ReadFIFO32(*p_syncInfo, modNum, &(read[modNum-1]));
if (NAI_SUCCESS == status)
{
/*sprintf(line, "%s Module%d", line, modNum);*/
sprintf(tmpString, " Module%d", modNum);
strcat(line, tmpString);
}
}
}
fprintf(dataFile, "%s\n", line);
for(dataIndex = 0; dataIndex < DEFAULT_NUM_FIFO_SAMPLES; dataIndex++)
{
sprintf(line, "%3u ", dataIndex);
for (modNum = 1; modNum < NAI_MAX_MODULES; modNum++)
{
if (read[modNum-1] > 0)
{
/*sprintf(line, "%s %3.3f", line, fifoData[modNum-1][dataIndex]);*/
sprintf(tmpString, " %3.3f", fifoData[modNum-1][dataIndex]);
strcat(line, tmpString);
}
}
fprintf(dataFile, "%s\n", line);
line[0] = '\0';
}
fclose(dataFile);
printf("Data saved to %s\n", DATA_FILE);
}
}
return status;
}
const char* SyncModeString(naibrd_module_sync_mode_type_t mode)
{
const char* retVal = NULL;
switch(mode)
{
case NAIBRD_MODULE_SYNC_MODE_DISABLED:
retVal = "DISABLED";
break;
case NAIBRD_MODULE_SYNC_MODE_SLAVE_INTERNAL:
retVal = "SLAVE_INTERNAL";
break;
case NAIBRD_MODULE_SYNC_MODE_SLAVE_BOARD_CLOCK:
retVal = "SLAVE_BOARD_SOURCE";
break;
case NAIBRD_MODULE_SYNC_MODE_SLAVE_USER_CLOCK:
retVal = "SLAVE_I/O_SOURCE";
break;
case NAIBRD_MODULE_SYNC_MODE_MASTER:
retVal = "MASTER";
break;
default:
retVal = "ERROR!";
break;
}
return retVal;
}
static bool_t SyncSupported(uint32_t modID)
{
bool_t retVal = FALSE;
switch(modID)
{
case NAI_MODULE_ID_AD1:
case NAI_MODULE_ID_AD2:
case NAI_MODULE_ID_AD3:
case NAI_MODULE_ID_AD4:
case NAI_MODULE_ID_AD5:
case NAI_MODULE_ID_AD6:
case NAI_MODULE_ID_ADE:
case NAI_MODULE_ID_ADF:
case NAI_MODULE_ID_ADG:
case NAI_MODULE_ID_CME:
case NAI_MODULE_ID_CMF:
case NAI_MODULE_ID_CMG:
case NAI_MODULE_ID_DA1:
case NAI_MODULE_ID_DA2:
case NAI_MODULE_ID_DA3:
case NAI_MODULE_ID_DA4:
case NAI_MODULE_ID_DA5:
retVal = TRUE;
break;
default:
retVal = FALSE;
break;
}
return retVal;
}
static sync_module_type_t GetModuleType(uint32_t modID)
{
return (sync_module_type_t)(modID & MOD_TYPE_MASK);
}
static bool_t GetMasterModule(naiapp_syncInfo_t *p_syncInfo, int32_t *p_masterModNum)
{
bool_t bQuit = FALSE;
bool_t bContinue = TRUE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
while(bContinue)
{
printf("Enter the module to sync to (master module) [1-%d]\n", p_syncInfo->moduleCount);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
*p_masterModNum = (int32_t)atol((const char*)inputBuffer);
if ((*p_masterModNum <= 0) || (*p_masterModNum > p_syncInfo->moduleCount)
|| !SyncSupported(naibrd_GetModuleID(p_syncInfo->cardIndex, *p_masterModNum)))
{
printf("ERROR: Invalid module value.\r\n\r\n");
}
else
bContinue = FALSE;
}
else
{
printf("ERROR: Invalid module value.\r\n\r\n");
}
}
}
return bQuit;
}
static nai_status_t ConfigFifoSync(naiapp_syncInfo_t *p_syncInfo, int32_t modNum, naibrd_module_sync_mode_type_t mode, uint32_t trigCtrl)
{
nai_status_t status = NAI_ERROR_UNKNOWN;
switch(p_syncInfo->moduleType[modNum-1])
{
case MOD_TYPE_AD:
status = check_status(naibrd_AD_SetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_TRIGGER,
mode, p_syncInfo->triggerMasterModNum));
status = check_status(naibrd_AD_SetFIFOTrigCtrl(p_syncInfo->cardIndex, modNum, p_syncInfo->channel[modNum-1],
(nai_ad_fifo_trig_t)trigCtrl));
break;
case MOD_TYPE_DA:
/* DA sync is not supported yet. */
/*status = check_status(naibrd_DA_SetModuleSyncMode(p_syncInfo->cardIndex, modNum, NAIBRD_SYNC_CONFIG_TRIGGER,
mode, p_syncInfo->triggerMasterModNum)); */
break;
default:
status = NAI_ERROR_INVALID_MODULE;
break;
}
return status;
}
static nai_status_t SetFifoTriggers(naiapp_syncInfo_t *p_syncInfo, bool_t trigEnable)
{
int32_t modIndex = 0;
nai_status_t status = NAI_ERROR_UNKNOWN;
uint32_t trigCtrl = 0u;
for(modIndex = 0; modIndex < p_syncInfo->moduleCount; modIndex++)
{
switch(p_syncInfo->moduleType[modIndex])
{
case MOD_TYPE_AD:
status = check_status(naibrd_AD_GetFIFOTrigCtrl(p_syncInfo->cardIndex, modIndex + 1, p_syncInfo->channel[modIndex],
(nai_ad_fifo_trig_t*)(&trigCtrl)));
if (FALSE != trigEnable)
{
trigCtrl |= (uint32_t)NAI_AD_GEN5_FIFO_TRIG_ENABLE;
}
else
{
trigCtrl &= (uint32_t)~NAI_AD_GEN5_FIFO_TRIG_ENABLE;
}
status = check_status(naibrd_AD_SetFIFOTrigCtrl(p_syncInfo->cardIndex, modIndex + 1, p_syncInfo->channel[modIndex],
(nai_ad_fifo_trig_t)(trigCtrl)));
break;
case MOD_TYPE_DA:
status = check_status(naibrd_DA_GetFIFOTrigCtrl(p_syncInfo->cardIndex, modIndex + 1, p_syncInfo->channel[modIndex],
(nai_da_fifo_trig_t*)(&trigCtrl)));
if (FALSE != trigEnable)
{
trigCtrl |= (uint32_t)NAI_DA_GEN5_FIFO_TRIG_ENABLE;
}
else
{
trigCtrl &= (uint32_t)~NAI_DA_GEN5_FIFO_TRIG_ENABLE;
}
status = check_status(naibrd_DA_SetFIFOTrigCtrl(p_syncInfo->cardIndex, modIndex + 1, p_syncInfo->channel[modIndex],
(nai_da_fifo_trig_t)(trigCtrl)));
break;
default:
break;
}
}
return status;
}
static nai_status_t GetModuleSyncMode(naiapp_syncInfo_t syncInfo, int32_t modNum, naibrd_module_sync_config_type_t config,
naibrd_module_sync_mode_type_t *p_mode, int32_t *p_masterModNum)
{
nai_status_t status = NAI_ERROR_UNKNOWN;
switch(syncInfo.moduleType[modNum-1])
{
case MOD_TYPE_AD:
status = check_status(naibrd_AD_GetModuleSyncMode(syncInfo.cardIndex, modNum, config, p_mode, p_masterModNum));
break;
case MOD_TYPE_DA:
/*status = check_status(naibrd_DA_GetModuleSyncMode(syncInfo.cardIndex, modNum, config, p_mode, p_masterModNum));*/
break;
default:
status = NAI_ERROR_NOT_SUPPORTED;
break;
}
return status;
}
static nai_status_t ReadFIFO32(naiapp_syncInfo_t syncInfo, int32_t modNum, uint32_t *p_outRead)
{
nai_status_t status = NAI_ERROR_UNKNOWN;
switch(syncInfo.moduleType[modNum-1])
{
case MOD_TYPE_AD:
status = check_status(naibrd_AD_ReadFIFO32(syncInfo.cardIndex, modNum, syncInfo.channel[modNum-1], DEFAULT_NUM_FIFO_SAMPLES,
fifoData[modNum-1], p_outRead));
break;
default:
status = NAI_ERROR_INVALID_MODULE;
p_outRead = 0;
break;
}
return status;
}