Add breaktable support
This commit is contained in:
@@ -8,7 +8,7 @@ E3_MODULE_VERSION:=master
|
||||
# DEPENDENT MODULE VERSION
|
||||
# For Example,
|
||||
|
||||
ECMC_DEP_VERSION:=6.3.0
|
||||
ECMC_DEP_VERSION:=develop
|
||||
ASYN_DEP_VERSION:=4.37.0
|
||||
|
||||
#DEVLIB2_DEP_VERSION:=2.9.0
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
EPICS_BASE:=${HOME}/epics/base-7.0.4
|
||||
|
||||
E3_REQUIRE_NAME:=require
|
||||
E3_REQUIRE_VERSION:=3.3.0
|
||||
E3_REQUIRE_VERSION:=3.4.0
|
||||
|
||||
# The definitions shown below can also be placed in an untracked RELEASE.local
|
||||
-include $(TOP)/../../RELEASE.local
|
||||
|
||||
@@ -36,6 +36,17 @@
|
||||
#include "ecmcAsynPortDriverUtils.h"
|
||||
#include "epicsThread.h"
|
||||
|
||||
// Breaktable
|
||||
#include "ellLib.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "dbAccess.h"
|
||||
#include "epicsVersion.h"
|
||||
#include "cvtTable.h"
|
||||
#ifdef BASE_VERSION
|
||||
#define EPICS_3_13
|
||||
extern DBBASE *pdbbase;
|
||||
#endif
|
||||
|
||||
|
||||
// New data callback from ecmc
|
||||
static int printMissingObjError = 1;
|
||||
@@ -92,6 +103,7 @@ ecmcFFT::ecmcFFT(int fftIndex, // index of this object (if several is cr
|
||||
0) /* Default stack size */
|
||||
{
|
||||
cfgDataSourceStr_ = NULL;
|
||||
cfgBreakTableStr_ = NULL;
|
||||
rawDataBuffer_ = NULL;
|
||||
dataItem_ = NULL;
|
||||
dataItemInfo_ = NULL;
|
||||
@@ -107,6 +119,10 @@ ecmcFFT::ecmcFFT(int fftIndex, // index of this object (if several is cr
|
||||
cycleCounter_ = 0;
|
||||
ignoreCycles_ = 0;
|
||||
dataSourceLinked_ = 0;
|
||||
breakTableIndex_ = -1;
|
||||
breakTable_ = 0;
|
||||
lastBreakPoint_ = 0;
|
||||
breakInit_ = 1;
|
||||
|
||||
// Asyn
|
||||
asynEnableId_ = -1; // Enable/disable acq./calcs
|
||||
@@ -151,6 +167,11 @@ ecmcFFT::ecmcFFT(int fftIndex, // index of this object (if several is cr
|
||||
cfgFFTSampleRateHz_ = ecmcSampleRateHz_;
|
||||
}
|
||||
|
||||
// Check if breaktable
|
||||
if(cfgBreakTableStr_) {
|
||||
verifyBreakTable();
|
||||
}
|
||||
|
||||
// Se if any data update cycles should be ignored
|
||||
// example ecmc 1000Hz, fft 100Hz then ignore 9 cycles (could be strange if not multiples)
|
||||
ignoreCycles_ = ecmcSampleRateHz_ / cfgFFTSampleRateHz_ -1;
|
||||
@@ -199,6 +220,9 @@ ecmcFFT::~ecmcFFT() {
|
||||
if(cfgDataSourceStr_) {
|
||||
free(cfgDataSourceStr_);
|
||||
}
|
||||
if(cfgBreakTableStr_) {
|
||||
free(cfgBreakTableStr_);
|
||||
}
|
||||
if(fftDouble_) {
|
||||
delete fftDouble_;
|
||||
}
|
||||
@@ -234,6 +258,12 @@ void ecmcFFT::parseConfigStr(char *configStr) {
|
||||
cfgDataSourceStr_=strdup(pThisOption);
|
||||
}
|
||||
|
||||
// ECMC_PLUGIN_BREAKTABLE_OPTION_CMD (EPICS breaktable name)
|
||||
else if (!strncmp(pThisOption, ECMC_PLUGIN_BREAKTABLE_OPTION_CMD, strlen(ECMC_PLUGIN_BREAKTABLE_OPTION_CMD))) {
|
||||
pThisOption += strlen(ECMC_PLUGIN_BREAKTABLE_OPTION_CMD);
|
||||
cfgBreakTableStr_=strdup(pThisOption);
|
||||
}
|
||||
|
||||
// ECMC_PLUGIN_NFFT_OPTION_CMD (1/0)
|
||||
else if (!strncmp(pThisOption, ECMC_PLUGIN_NFFT_OPTION_CMD, strlen(ECMC_PLUGIN_NFFT_OPTION_CMD))) {
|
||||
pThisOption += strlen(ECMC_PLUGIN_NFFT_OPTION_CMD);
|
||||
@@ -424,9 +454,24 @@ void ecmcFFT::dataUpdatedCallback(uint8_t* data,
|
||||
}
|
||||
|
||||
void ecmcFFT::addDataToBuffer(double data) {
|
||||
|
||||
if(rawDataBuffer_ && (elementsInBuffer_ < cfgNfft_) ) {
|
||||
rawDataBuffer_[elementsInBuffer_] = data* cfgScale_;
|
||||
prepProcDataBuffer_[elementsInBuffer_] = data *cfgScale_;
|
||||
|
||||
if(breakTableIndex_>=0 && cfgBreakTableStr_ && interruptAccept) {
|
||||
double breakData = data;
|
||||
if (cvtRawToEngBpt(&breakData, breakTableIndex_, breakInit_, &breakTable_, &lastBreakPoint_)!=0) {
|
||||
//TODO: What does status here mean..
|
||||
//throw std::runtime_error("Breaktable conversion failed.\n");
|
||||
}
|
||||
breakInit_ = 0; // Breack pointer should now be assigned
|
||||
//printf("Index %d: Before %lf, after %lf\n",objectId_,data,breakData);
|
||||
data = breakData * cfgScale_;
|
||||
} else {
|
||||
data = data * cfgScale_;
|
||||
}
|
||||
|
||||
rawDataBuffer_[elementsInBuffer_] = data;
|
||||
prepProcDataBuffer_[elementsInBuffer_] = data;
|
||||
}
|
||||
elementsInBuffer_ ++;
|
||||
}
|
||||
@@ -1055,3 +1100,25 @@ int ecmcFFT::leastSquare(int n, const double y[], double* k, double* m){
|
||||
*m = (sumy * sumx2 - sumx * sumxy) / denom;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ecmcFFT::verifyBreakTable() {
|
||||
breakTableIndex_ = -1;
|
||||
dbMenu *menuConvert;
|
||||
ELLLIST missing;
|
||||
int i;
|
||||
|
||||
menuConvert = dbFindMenu(pdbbase,"menuConvert");
|
||||
ellInit(&missing);
|
||||
for(i=0; i<menuConvert->nChoice; i++)
|
||||
{
|
||||
// printf("menuConvertItem[%d] %s (looking for %s))\n",i,menuConvert->papChoiceValue[i], cfgBreakTableStr_);
|
||||
if (strcmp(menuConvert->papChoiceValue[i],cfgBreakTableStr_)==0)
|
||||
{
|
||||
breakTableIndex_ = i;
|
||||
printf("breakTable %s found as menuItem %d\n",cfgBreakTableStr_, breakTableIndex_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return breakTableIndex_>=0;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "inttypes.h"
|
||||
#include <string>
|
||||
#include "kissfft/kissfft.hh"
|
||||
#include "dbBase.h"
|
||||
|
||||
class ecmcFFT : public asynPortDriver {
|
||||
public:
|
||||
@@ -68,6 +69,7 @@ class ecmcFFT : public asynPortDriver {
|
||||
void initAsyn();
|
||||
void updateStatus(FFT_STATUS status); // Also updates asynparam
|
||||
static int dataTypeSupported(ecmcEcDataType dt);
|
||||
bool verifyBreakTable();
|
||||
|
||||
ecmcDataItem *dataItem_;
|
||||
ecmcDataItemInfo *dataItemInfo_;
|
||||
@@ -90,11 +92,16 @@ class ecmcFFT : public asynPortDriver {
|
||||
int triggOnce_;
|
||||
int cycleCounter_;
|
||||
int ignoreCycles_;
|
||||
int breakTableIndex_;
|
||||
void *breakTable_;
|
||||
short lastBreakPoint_;
|
||||
short breakInit_;
|
||||
double scale_; // Config: Data set size
|
||||
FFT_STATUS status_; // Status/state (NO_STAT, IDLE, ACQ, CALC)
|
||||
|
||||
// Config options
|
||||
char* cfgDataSourceStr_; // Config: data source string
|
||||
char* cfgBreakTableStr_; // Config: EPICS breaktable name
|
||||
int cfgDbgMode_; // Config: allow dbg printouts
|
||||
int cfgApplyScale_; // Config: apply scale 1/nfft
|
||||
int cfgDcRemove_; // Config: remove dc (average)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#define ECMC_PLUGIN_RATE_OPTION_CMD "RATE="
|
||||
#define ECMC_PLUGIN_RM_LIN_OPTION_CMD "RM_LIN="
|
||||
#define ECMC_PLUGIN_SCALE_OPTION_CMD "SCALE="
|
||||
|
||||
#define ECMC_PLUGIN_BREAKTABLE_OPTION_CMD "BREAKTABLE="
|
||||
|
||||
// CONT, TRIGG
|
||||
#define ECMC_PLUGIN_MODE_OPTION_CMD "MODE="
|
||||
|
||||
@@ -115,15 +115,16 @@ struct ecmcPluginData pluginDataDef = {
|
||||
// Description
|
||||
.desc = "FFT plugin for use with ecmc.",
|
||||
// Option description
|
||||
.optionDesc = "\n "ECMC_PLUGIN_DBG_PRINT_OPTION_CMD"<1/0> : Enables/disables printouts from plugin, default = disabled.\n"
|
||||
" "ECMC_PLUGIN_SOURCE_OPTION_CMD"<source> : Sets source variable for FFT (example: ec0.s1.AI_1).\n"
|
||||
" "ECMC_PLUGIN_NFFT_OPTION_CMD"<nfft> : Data points to collect, default = 4096.\n"
|
||||
" "ECMC_PLUGIN_SCALE_OPTION_CMD"scalefactor : Apply scale to source data, default = 1.0.\n"
|
||||
" "ECMC_PLUGIN_RM_DC_OPTION_CMD"<1/0> : Remove DC offset of input data (SOURCE), default = disabled.\n"
|
||||
" "ECMC_PLUGIN_RM_LIN_OPTION_CMD"<1/0> : Remove linear component in data (SOURCE) by least square, default = disabled.\n"
|
||||
" "ECMC_PLUGIN_ENABLE_OPTION_CMD"<1/0> : Enable data acq. and calcs (can be controlled over asyn), default = disabled.\n"
|
||||
" "ECMC_PLUGIN_MODE_OPTION_CMD"<CONT/TRIGG> : Continious or triggered mode, defaults to TRIGG\n"
|
||||
" "ECMC_PLUGIN_RATE_OPTION_CMD"<rate in hz> : fft data sample rate in hz (must be lower than ecmc rate and (ecmc_rate/fft_rate)=integer), default = ecmc rate."
|
||||
.optionDesc = "\n "ECMC_PLUGIN_DBG_PRINT_OPTION_CMD"<1/0> : Enables/disables printouts from plugin, default = disabled.\n"
|
||||
" "ECMC_PLUGIN_SOURCE_OPTION_CMD"<source> : Sets source variable for FFT (example: ec0.s1.AI_1).\n"
|
||||
" "ECMC_PLUGIN_NFFT_OPTION_CMD"<nfft> : Data points to collect, default = 4096.\n"
|
||||
" "ECMC_PLUGIN_SCALE_OPTION_CMD"scalefactor : Apply scale to source data, default = 1.0.\n"
|
||||
" "ECMC_PLUGIN_RM_DC_OPTION_CMD"<1/0> : Remove DC offset of input data (SOURCE), default = disabled.\n"
|
||||
" "ECMC_PLUGIN_RM_LIN_OPTION_CMD"<1/0> : Remove linear component in data (SOURCE) by least square, default = disabled.\n"
|
||||
" "ECMC_PLUGIN_ENABLE_OPTION_CMD"<1/0> : Enable data acq. and calcs (can be controlled over asyn), default = disabled.\n"
|
||||
" "ECMC_PLUGIN_MODE_OPTION_CMD"<CONT/TRIGG> : Continious or triggered mode, defaults to TRIGG\n"
|
||||
" "ECMC_PLUGIN_RATE_OPTION_CMD"<rate in hz> : fft data sample rate in hz (must be lower than ecmc rate and (ecmc_rate/fft_rate)=integer), default = ecmc rate."
|
||||
" "ECMC_PLUGIN_BREAKTABLE_OPTION_CMD"<brktab> : Use epics breaktable to convert raw values (applied before any other signal cond. alg.), default not used."
|
||||
,
|
||||
// Plugin version
|
||||
.version = ECMC_EXAMPLE_PLUGIN_VERSION,
|
||||
|
||||
Reference in New Issue
Block a user