Generation working and Compilation of MARTe components
This commit is contained in:
@@ -0,0 +1,639 @@
|
||||
/******************************************************************************
|
||||
* $HeadURL: https://svnpub.iter.org/codac/iter/codac/dev/units/m-codac-unit-templates/tags/CODAC-CORE-6.0.0/templates/cpp-sdn/main/c++/prog/prog.cpp.template $
|
||||
* $Id: prog.cpp.template 83098 2018-01-08 13:23:38Z cesnikt $
|
||||
*
|
||||
* Project : CODAC Core System
|
||||
*
|
||||
* Description : GyrotronDAN program
|
||||
*
|
||||
* Author : codac-dev
|
||||
*
|
||||
* Copyright (c) : 2010-2018 ITER Organization,
|
||||
* CS 90 046
|
||||
* 13067 St. Paul-lez-Durance Cedex
|
||||
* France
|
||||
*
|
||||
* This file is part of ITER CODAC software.
|
||||
* For the terms and conditions of redistribution or use of this software
|
||||
* refer to the file ITER-LICENSE.TXT located in the top level directory
|
||||
* of the distribution package.
|
||||
******************************************************************************/
|
||||
|
||||
/* header files */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
//#include <xseries-lib.h>
|
||||
#define float32_t float32_t1
|
||||
#include <xseries-lib.h>
|
||||
#undef float32_t
|
||||
|
||||
#include <iostream>
|
||||
#include <dan.h>
|
||||
#include <time.h>
|
||||
#include <ca-if.h>
|
||||
#include <math.h>
|
||||
#include <tcn.h>
|
||||
|
||||
#include <log.h>
|
||||
|
||||
// global variables
|
||||
static bool __terminate = false;
|
||||
char pxie6368_0_ai_fd[] = "/dev/pxie-6368.0.ai"; // ai segment
|
||||
char pxie6368_0_device[] = "/dev/pxie-6368.0"; // device descriptor
|
||||
|
||||
typedef struct {
|
||||
int daq_smpl_rate;
|
||||
int daq_mode;
|
||||
double daq_smpl_st_dly;
|
||||
double daq_len;
|
||||
double daq_pub_dly;
|
||||
} daq_parameters;
|
||||
|
||||
void signal_handler(int signal) {
|
||||
log_info("Received signal '%d' to terminate", signal);
|
||||
__terminate = true;
|
||||
};
|
||||
|
||||
// DAN parameter reload function ------------------------------------------------
|
||||
int reload_daq_conf(int *aifd, int *ai_chan_fd, daq_parameters *daq_p) {
|
||||
std::cout << "reload_daq_conf was called \n";
|
||||
|
||||
// Common variables
|
||||
int retval;
|
||||
unsigned long number_of_samples;
|
||||
int chan_num = 10; // Channel number to add.
|
||||
uint32_t sample_period_divisor;
|
||||
uint32_t base_clock = 100000000; // TB3:100MHz, TB2:100 kHz
|
||||
uint32_t pre_samples = 1000;
|
||||
uint32_t post_samples = 1000;
|
||||
char str[40];
|
||||
xseries_ai_conf_t conf; // ai segment configuraton data
|
||||
|
||||
// calculate sampling period divisor
|
||||
if (daq_p->daq_smpl_rate != 0) {
|
||||
sample_period_divisor = base_clock / daq_p->daq_smpl_rate;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Stop ai segment----------------------------------------------------------------------
|
||||
retval = xseries_stop_ai(*aifd);
|
||||
if (retval) {
|
||||
log_error("ai segment stop failed.\n");
|
||||
} else {
|
||||
log_info("ai segment stopped.\n");
|
||||
}
|
||||
|
||||
// reset ai segment---------------------------------------------------------------------
|
||||
retval = xseries_reset_ai(*aifd);
|
||||
if (retval) {
|
||||
log_error("ai segment reset failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Configure AI segment mode ------------------------------------------------------------
|
||||
switch (daq_p->daq_mode) {
|
||||
case 0:
|
||||
conf = xseries_software_timed_ai();
|
||||
log_info("software_timed mode.\n");
|
||||
break;
|
||||
case 1:
|
||||
conf = xseries_finite_ai(number_of_samples);
|
||||
log_info("finite mode.\n");
|
||||
break;
|
||||
case 2:
|
||||
conf = xseries_retriggerable_finite_ai(number_of_samples);
|
||||
log_info("retriggerable_finite mode.\n");
|
||||
break;
|
||||
case 3:
|
||||
conf = xseries_continuous_ai();
|
||||
log_info("continuous mode.\n");
|
||||
break;
|
||||
case 4:
|
||||
conf = xseries_reference_ai(pre_samples, post_samples);
|
||||
log_info("reference mode.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// disable external gate
|
||||
retval = xseries_set_ai_external_gate(&conf,
|
||||
XSERIES_AI_EXTERNAL_GATE_DISABLED, // No external pause signal
|
||||
XSERIES_AI_POLARITY_ACTIVE_LOW_OR_FALLING_EDGE); // Don't care
|
||||
if (retval) {
|
||||
log_error("Cannot set gate trigger.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// select start trigger (START1 signal)
|
||||
retval = xseries_set_ai_start_trigger(&conf,
|
||||
XSERIES_AI_START_TRIGGER_SW_PULSE, // Set the line to software-driven
|
||||
XSERIES_AI_POLARITY_ACTIVE_HIGH_OR_RISING_EDGE, // Make line active on rising...
|
||||
1); // ... edge (not high level)
|
||||
if (retval) {
|
||||
log_error("Cannot set start trigger.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set sampling clock source----------------------------------------------------------------------------------------
|
||||
retval = xseries_set_ai_sample_clock(&conf,
|
||||
XSERIES_AI_SAMPLE_CONVERT_CLOCK_INTERNALTIMING,
|
||||
XSERIES_AI_POLARITY_ACTIVE_HIGH_OR_RISING_EDGE, 1);
|
||||
if (retval) {
|
||||
log_error("Cannot configure sampling clock.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set scan interval -------------------------------------------------------------------------------------------------------------------------
|
||||
retval = xseries_set_ai_scan_interval_counter(&conf,
|
||||
XSERIES_SCAN_INTERVAL_COUNTER_TB3, // TB3 : 100MHz base clock, TB2 : 100kHz base clock
|
||||
XSERIES_SCAN_INTERVAL_COUNTER_POLARITY_RISING_EDGE,
|
||||
sample_period_divisor, 2); // Wait 2*100MHz sec after sampling trig.
|
||||
if (retval) {
|
||||
log_error("Cannot configure scan counter.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set DMA buffer size-----------------------------------------------------------------------------------------------------------------------
|
||||
retval = xseries_set_ai_attribute(&conf, XSERIES_AI_DMA_BUFFER_SIZE, 1000);
|
||||
if (retval) {
|
||||
log_error("DMA configuration was failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Add AI channels ---------------------------------------------------------------------------------------------------------------------------
|
||||
for (int i = 0; i < chan_num; i++) {
|
||||
retval = xseries_add_ai_channel(&conf, i, XSERIES_INPUT_RANGE_10V,
|
||||
XSERIES_AI_CHANNEL_TYPE_DIFFERENTIAL, 0);
|
||||
if (retval) {
|
||||
log_error("Add AI channel %d was failed.\n", i);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
sleep(3);
|
||||
|
||||
// Load configuration.-----------------------------------------------------------------------------------------------------------------------
|
||||
retval = xseries_load_ai_conf(*aifd, conf);
|
||||
if (retval) {
|
||||
log_error("xseries_load_ai_conf was failed. error code: %d \n", retval);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
sleep(3);
|
||||
|
||||
// Open channels--------------------------------------------------------------------------------------------------------------------------------
|
||||
for (int i = 0; i < chan_num; i++) {
|
||||
sprintf(str, "%s.ai.%u", pxie6368_0_device, i);
|
||||
//ai_chan_fd[i] = open(str, O_RDWR | O_NONBLOCK);
|
||||
ai_chan_fd[i] = open(str, O_RDWR);
|
||||
if (ai_chan_fd[i] < 0) {
|
||||
log_error("Cannot open ai channel %d .\n",i);
|
||||
sleep(1);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// start ai segment task-----------------------------------------------------------------------------------------------------------------------
|
||||
retval = xseries_start_ai(*aifd);
|
||||
if (retval) {
|
||||
log_error("ERROR, starting AI segment failed: %s\n", strerror(retval));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
log_info("PXIe-6368 configuration was finished.\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
using namespace std;
|
||||
unsigned long n_sample_quotient = 0;
|
||||
|
||||
log_initialize(NULL);
|
||||
|
||||
while (!__terminate) {
|
||||
// Install signal handler to support graceful termination
|
||||
sigset(SIGTERM, signal_handler);
|
||||
sigset(SIGINT, signal_handler);
|
||||
sigset(SIGHUP, signal_handler);
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
// Running parameter declaration
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
// pxie6368 hardware parameters
|
||||
int pxie6368_0_device_number = 0; // device discriptor number
|
||||
int aifd = 0; // ai segment file discriptor
|
||||
xseries_ai_conf_t conf; // ai segment config
|
||||
xseries_ai_attribute_t aiatrb; // ai segment attributes
|
||||
char str[40]; // fd tmp var
|
||||
int ai_chan_fd[16]; // ai channels file discriptor
|
||||
int pxie6368_sampling_rate = 1000; // sampling rate Hz
|
||||
uint32_t sample_period_divisor = 100000000 / pxie6368_sampling_rate; // TB3 100MHz, TB2:100kHz, TB1:20MHz
|
||||
int sampleSize = 2; // Sample size in bytes <---> uInt16
|
||||
int n_channels; // Number of opened channels
|
||||
struct xseries_dma *dma; // Ptr to dma struct
|
||||
int chan_num = 10; // Channel number to add.
|
||||
|
||||
// DAN parameters
|
||||
char dan_source_name[] = "GYADanSource"; // DAN data source (ds) name
|
||||
long offset_ai = 0; // offset size in published data
|
||||
int dma_mode = 1; // 0:All, 1:AI only, 2:AO only
|
||||
dan_DataCore dc = NULL; // Datacore reference declaration
|
||||
dan_Source ds = NULL; // DAN source declaration
|
||||
long samplesCounter = 0; // Total acquired sample size
|
||||
size_t n_samples; // prepared sample size to publish
|
||||
|
||||
// TCN parameters
|
||||
uint64_t tBase_old = 0;
|
||||
uint64_t tBase = 0; // TCN publishing base time
|
||||
uint64_t nanos; // time length for sampling
|
||||
hpn_timestamp_t delay = 1e7; // wait for publishing (10ms)
|
||||
char buf[ISO_8601_LEN];
|
||||
uint64_t tBase0 = 0;
|
||||
|
||||
// Operation tmp parameter
|
||||
int result; // For result values.
|
||||
int exValue;
|
||||
bool toterminate = false;
|
||||
int retval;
|
||||
bool daq_start = false;
|
||||
int testcounter = 10000;
|
||||
|
||||
// Connected EPCIS PV
|
||||
|
||||
// DAQ config PVs
|
||||
chid daq_smpl_rate_id;
|
||||
chtype daq_smpl_rate_type;
|
||||
int daq_smpl_rate;
|
||||
chid daq_smpl_rate_rb_id;
|
||||
chtype daq_smpl_rate_rb_type;
|
||||
int daq_smpl_rate_rb;
|
||||
chid daq_mode_id;
|
||||
chtype daq_mode_type;
|
||||
int daq_mode;
|
||||
chid daq_mode_rb_id;
|
||||
chtype daq_mode_rb_type;
|
||||
int daq_mode_rb;
|
||||
chid daq_sw_trig_id;
|
||||
chtype daq_sw_trig_type;
|
||||
int daq_sw_trig;
|
||||
chid daq_smpl_st_dly_id;
|
||||
chtype daq_smpl_st_dly_type;
|
||||
double daq_smpl_st_dly;
|
||||
chid daq_smpl_st_dly_rb_id;
|
||||
chtype daq_smpl_st_dly_rb_type;
|
||||
double daq_smpl_st_dly_rb;
|
||||
chid daq_len_id;
|
||||
chtype daq_len_type;
|
||||
double daq_len;
|
||||
chid daq_len_rb_id;
|
||||
chtype daq_len_rb_type;
|
||||
double daq_len_rb;
|
||||
chid daq_reconf_id;
|
||||
chtype daq_reconf_type;
|
||||
int daq_reconf;
|
||||
chid daq_pub_dly_id;
|
||||
chtype daq_pub_dly_type;
|
||||
double daq_pub_dly;
|
||||
chid daq_pub_dly_rb_id;
|
||||
chtype daq_pub_dly_rb_type;
|
||||
double daq_pub_dly_rb;
|
||||
|
||||
chid daq_stat_id;
|
||||
chtype daq_stat_type;
|
||||
int daq_stat;
|
||||
chid daq_conf_stat_id;
|
||||
chtype daq_conf_stat_type;
|
||||
int daq_conf_stat;
|
||||
|
||||
daq_parameters daq_p = { 0 }; // = {daq_smpl_rate, daq_smpl_rate_rb, daq_mode, daq_mode_rb};
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// EPICS PV connection
|
||||
// ----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//Initialize ChannelAccess interface
|
||||
CAInterface_Initialize();
|
||||
|
||||
// Connect to EPICS PVs
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-SMPL-RATE", daq_smpl_rate_id);
|
||||
daq_smpl_rate_type = DBR_LONG;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-SMPL-RATE-RB", daq_smpl_rate_rb_id);
|
||||
daq_smpl_rate_rb_type = DBR_LONG;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-MODE", daq_mode_id);
|
||||
daq_mode_type = DBR_ENUM;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-MODE-RB", daq_mode_rb_id);
|
||||
daq_mode_rb_type = DBR_ENUM;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-SW-TRIG", daq_sw_trig_id);
|
||||
daq_sw_trig_type = DBR_ENUM;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-SMPL-ST-DLY", daq_smpl_st_dly_id);
|
||||
daq_smpl_st_dly_type = DBR_DOUBLE;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-SMPL-ST-DLY-RB", daq_smpl_st_dly_rb_id);
|
||||
daq_smpl_st_dly_rb_type = DBR_DOUBLE;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-LEN", daq_len_id);
|
||||
daq_len_type = DBR_DOUBLE;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-LEN-RB", daq_len_rb_id);
|
||||
daq_len_rb_type = DBR_DOUBLE;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-RECONF", daq_reconf_id);
|
||||
daq_reconf_type = DBR_ENUM;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-PUB-DLY", daq_pub_dly_id);
|
||||
daq_pub_dly_type = DBR_DOUBLE;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-PUB-DLY-RB", daq_pub_dly_rb_id);
|
||||
daq_pub_dly_rb_type = DBR_DOUBLE;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-STAT", daq_stat_id);
|
||||
daq_stat_type = DBR_ENUM;
|
||||
|
||||
CAInterface_ConnectVariable("EC-GN-P01-GPF:STAT-DAQ-CONF-STAT", daq_conf_stat_id);
|
||||
daq_conf_stat_type = DBR_ENUM;
|
||||
|
||||
tcn_sleep(3e9);// Wait for a while.
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
// Initialize tcn library
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
int tcn_err;
|
||||
tcn_err = tcn_init();
|
||||
if (tcn_err != TCN_SUCCESS) {
|
||||
log_error("TCN Initialization failed.\n");
|
||||
exValue = 1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
// pxie-6368 settings
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
// Open ai segment----------------------------------------------------------------------
|
||||
aifd = open(pxie6368_0_ai_fd, O_RDWR);
|
||||
if (aifd <= 0) {
|
||||
log_error("Open PXIe6368 AI fd failed.\n");
|
||||
exValue = -1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
// wait ai segment setup start
|
||||
do {
|
||||
CAInterface_ReadVariable(daq_reconf_id, daq_reconf_type, (void*) &daq_reconf);
|
||||
} while (!daq_reconf and !__terminate);
|
||||
|
||||
// read parameter
|
||||
result = CAInterface_ReadVariable(daq_smpl_rate_id, daq_smpl_rate_type, (void *) &daq_p.daq_smpl_rate);
|
||||
if (!result) {
|
||||
log_error("CA_READ failed.\n");
|
||||
}
|
||||
// read parameter
|
||||
result = CAInterface_ReadVariable(daq_mode_id, daq_mode_type, (void *) &daq_p.daq_mode);
|
||||
if (!result) {
|
||||
log_error("CA_READ failed.\n");
|
||||
}
|
||||
// read parameter
|
||||
result = CAInterface_ReadVariable(daq_smpl_st_dly_id, daq_smpl_st_dly_type, (void *) &daq_p.daq_smpl_st_dly);
|
||||
if (!result) {
|
||||
log_error("CA_READ failed.\n");
|
||||
}
|
||||
// read parameter
|
||||
result = CAInterface_ReadVariable(daq_len_id, daq_len_type, (void *) &daq_p.daq_len);
|
||||
if (!result) {
|
||||
log_error("CA_READ failed.\n");
|
||||
}
|
||||
// read parameter
|
||||
result = CAInterface_ReadVariable(daq_pub_dly_id, daq_pub_dly_type, (void *) &daq_p.daq_pub_dly);
|
||||
if (!result) {
|
||||
log_error("CA_READ failed.\n");
|
||||
}
|
||||
|
||||
std::cout << "SAMPLE RATE:" << daq_p.daq_smpl_rate << endl;
|
||||
std::cout << "MODE :" << daq_p.daq_mode << endl;
|
||||
std::cout << "START DELAY:" <<daq_p.daq_smpl_st_dly << endl;
|
||||
std::cout << "DAQ LENGTH:" << daq_p.daq_len << endl;
|
||||
std::cout << "PUB DELAY :" << daq_p.daq_pub_dly << endl;
|
||||
|
||||
// Configure ai segment and dan parameter by using EPICS PV.
|
||||
result = reload_daq_conf(&aifd, ai_chan_fd, &daq_p);
|
||||
if (result < 0) {
|
||||
log_error("Load DAQ CONF failed.\n");
|
||||
daq_stat = 3; // 0:Not ready, 1:Waiting trigger, 2:Aquiring, 3:Error
|
||||
CAInterface_WriteVariable(daq_stat_id, daq_stat_type, &daq_stat);
|
||||
daq_conf_stat = 0; // 0:Not Ready, 1: Ready
|
||||
CAInterface_WriteVariable(daq_conf_stat_id, daq_conf_stat_type, &daq_conf_stat);
|
||||
goto END;
|
||||
} else {
|
||||
// All parameters were configured correctly, update readback PV
|
||||
CAInterface_WriteVariable(daq_smpl_rate_rb_id, daq_smpl_rate_rb_type, &daq_p.daq_smpl_rate);
|
||||
CAInterface_WriteVariable(daq_mode_rb_id, daq_mode_rb_type, &daq_p.daq_mode);
|
||||
CAInterface_WriteVariable(daq_smpl_st_dly_rb_id, daq_smpl_st_dly_rb_type, &daq_p.daq_smpl_st_dly);
|
||||
CAInterface_WriteVariable(daq_len_rb_id, daq_len_rb_type, &daq_p.daq_len);
|
||||
CAInterface_WriteVariable(daq_pub_dly_rb_id, daq_pub_dly_rb_type, &daq_p.daq_pub_dly);
|
||||
daq_conf_stat = 1;
|
||||
CAInterface_WriteVariable(daq_conf_stat_id, daq_conf_stat_type, &daq_conf_stat);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
// ----- DAN Publisher.
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
// Initialize DAN DataCore
|
||||
dc = dan_initLibrary();
|
||||
if (dc == NULL) {
|
||||
log_error("dan_init failed.\n");
|
||||
exValue = 1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
// ----- DMA initialization
|
||||
dma = xseries_dma_init(pxie6368_0_device_number, 1); // (devid, dma_mode) mode 0:mapping all dma mem, 1:AI only.
|
||||
if (dma == NULL) {
|
||||
cout << "Failed to connect to samples buffer.\n go to END.\n";
|
||||
exValue = -1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
// Push a new data block into source.
|
||||
ds = dan_publisher_publishSource(dc, dan_source_name, pxie6368_0_device,
|
||||
DAN_DAQ_MMAP, dma->ai.count * sampleSize, 4096);
|
||||
|
||||
//dan_DataCore, ds_name, devName, enum_daq_type refType, long refSize, long refOffset
|
||||
if (ds == NULL) {
|
||||
log_error("Error while publishing DAN source %s ", dan_source_name);
|
||||
exValue = 1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
n_channels = dan_publisher_getNumberOfChannels(ds);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
// ----- DAN Streamer.
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
// ----- Open a new stream ---------------------------------------------------------------------
|
||||
dan_publisher_openStream(ds, daq_p.daq_smpl_rate, 0);
|
||||
sleep(1);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
// ----- Main DAN Loop.
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
while (!__terminate) {
|
||||
// Wait for the master trigger.----------------------------------------------------------------------------
|
||||
daq_stat = 1; //0:Not Ready, 1: Waiting trigger, 2:Acquiring 3:Error
|
||||
CAInterface_WriteVariable(daq_stat_id, daq_stat_type, &daq_stat);
|
||||
daq_conf_stat = 1; //0:Not ready, 1: Ready
|
||||
CAInterface_WriteVariable(daq_conf_stat_id, daq_conf_stat_type, &daq_conf_stat);
|
||||
|
||||
// Wait DAQ Start Software Trigger.
|
||||
do {
|
||||
// check daq_sw_trigger to start DAQ sequence.
|
||||
CAInterface_ReadVariable(daq_sw_trig_id, daq_sw_trig_type, (void*) &daq_sw_trig);
|
||||
tcn_sleep(1e7); // wait 0.01 s
|
||||
if (daq_sw_trig) {
|
||||
daq_start = true;
|
||||
}
|
||||
} while (daq_start != true and !__terminate);
|
||||
|
||||
daq_start = false; //reset daq_start flag.
|
||||
delay = (long) (1e6 * daq_p.daq_pub_dly); //check publish period.
|
||||
|
||||
// Wait a time to start DAQ. ----------------------------------------------------------------------------------------------------------------------
|
||||
tcn_sleep(daq_p.daq_smpl_st_dly * 1e6); // in ms
|
||||
|
||||
// After the wating, trigger DAQ ------------------------------------------------------------------------------------------------------------------
|
||||
retval = xseries_pulse_ai(aifd, XSERIES_START_TRIGGER);
|
||||
daq_stat = 2;
|
||||
CAInterface_WriteVariable(daq_stat_id, daq_stat_type, &daq_stat);
|
||||
if (retval) {
|
||||
std::cout << "Cannot generate start trigger!\n";
|
||||
goto END;
|
||||
} else {
|
||||
tcn_get_time(&tBase); // get DAQ start time.
|
||||
tBase0 = tBase; // save DAQ start time to tBase0;
|
||||
tBase_old = tBase;
|
||||
}
|
||||
|
||||
// DAQ Publish Loop. ----------------------------------------------------------------------------------------------------------------------------
|
||||
// DAN data publish is executed every delay time interval.
|
||||
while (!__terminate && (tcn_wait_until_hr((tBase + delay), &tBase, 0) == TCN_SUCCESS)) {
|
||||
// Get the number of available samples in PXIe6368 buffer.
|
||||
n_samples = xsereis_ai_dma_samples_in_buffer(dma); // samples
|
||||
|
||||
if (n_samples > dma->ai.count) {
|
||||
//log_error("DMA Buffer overflow: Number of new samples in buffer = %ld, AI buffer size = %ld,\n", n_samples, dma->ai.count);
|
||||
} else if (n_samples > 0) {
|
||||
//log_info("Current Time:\n%s\n", tcn_strftime(tBase, buf, ISO_8601_LEN));
|
||||
if (tBase == 0) {
|
||||
// "tBase was reset.------------------------------------------------------\n";
|
||||
tcn_get_time(&tBase);
|
||||
tBase -= n_samples * 100000000 / pxie6368_sampling_rate;
|
||||
nanos = 0;
|
||||
} else {
|
||||
// update time offset value.
|
||||
nanos = n_samples * 100000000 / daq_p.daq_smpl_rate;
|
||||
}
|
||||
n_sample_quotient = floor(n_samples / chan_num);
|
||||
n_samples = n_sample_quotient * chan_num;
|
||||
|
||||
// Publish a new data block --------------------------------------------------------------------------------------------------------------------------
|
||||
result = dan_publisher_putBlockReference(ds,
|
||||
tBase_old + nanos, // timestamp in epoch nanoseconds
|
||||
n_samples * sampleSize, // datablock size in bytes
|
||||
offset_ai * sampleSize, // Offset in DAQ buffer
|
||||
NULL); // No datablock header....
|
||||
// Detected overflow in pass datablock reference queue
|
||||
if (result == -1) {
|
||||
log_info("%s, Queue overflow with policy %d\n", dan_source_name, dan_publisher_getCheckPolicy(ds));
|
||||
} else if (result == -2) {
|
||||
log_info("%s, DAQ buffer overflow with policy %d\n", dan_source_name, dan_publisher_getCheckPolicy(ds));
|
||||
}
|
||||
}
|
||||
|
||||
samplesCounter += n_samples; // Increment total of published sampes
|
||||
offset_ai = (offset_ai + n_samples) % dma->ai.count; // Update offset of memory
|
||||
dma->ai.last_transfer_count = samplesCounter; // Update dma last_transfer_count
|
||||
|
||||
// Check exit condition.
|
||||
if ((daq_p.daq_len * 1e6 <= (tBase - tBase0))) {
|
||||
retval = xseries_stop_ai(aifd);
|
||||
if (retval) {
|
||||
std::cout << "Stop AI segment failed.\n";
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//restart ai segment.
|
||||
tcn_sleep(1e9); // wait
|
||||
retval = xseries_start_ai(aifd);
|
||||
if (retval) {
|
||||
std::cout << "Start AI segment failed.\n";
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
//debug
|
||||
tcn_sleep(1e8);
|
||||
n_samples = xsereis_ai_dma_samples_in_buffer(dma);
|
||||
cout << "n_samples check : " << n_samples << endl;
|
||||
break;
|
||||
}
|
||||
tBase_old = tBase;
|
||||
} // End of DAQ publish loop.
|
||||
break;
|
||||
} // End of DAN main loop.
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
// ----- Closing program.
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
log_info("DAN end of acquisition, closing all resources");
|
||||
|
||||
//Closing stream
|
||||
dan_publisher_closeStream(ds);
|
||||
exValue = 0;
|
||||
|
||||
// Close all channels
|
||||
for (int channel = 0; channel < chan_num; channel++) {
|
||||
close(ai_chan_fd[channel]);
|
||||
}
|
||||
goto END;
|
||||
|
||||
END: daq_conf_stat = 0;
|
||||
CAInterface_WriteVariable(daq_conf_stat_id, daq_conf_stat_type, &daq_conf_stat);
|
||||
daq_stat = 0;
|
||||
CAInterface_WriteVariable(daq_stat_id, daq_stat_type, &daq_stat);
|
||||
// Destroy CA context
|
||||
CAInterface_Finalize();
|
||||
// Close pxie6368
|
||||
if (dma != NULL) {
|
||||
xseries_dma_close(dma);
|
||||
cout << "pxie-6368 dma was clesed.\n";
|
||||
}
|
||||
|
||||
close(aifd);
|
||||
|
||||
// Unpublishing source from DAN API
|
||||
if (ds != NULL) {
|
||||
dan_publisher_unpublishSource(dc, ds);
|
||||
}
|
||||
|
||||
// Closing DAN API library
|
||||
if (dc != NULL) {
|
||||
dan_closeLibrary(dc);
|
||||
}
|
||||
|
||||
// Closing TCN library
|
||||
result = tcn_finalize();
|
||||
if (result != TCN_SUCCESS) {
|
||||
//log_error("Error finalizing TCN lib.\n");
|
||||
}
|
||||
|
||||
} // loop end from initialization
|
||||
return (0);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user