diff --git a/configure/CONFIG_MODULE b/configure/CONFIG_MODULE index fbb6191..634e446 100644 --- a/configure/CONFIG_MODULE +++ b/configure/CONFIG_MODULE @@ -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 diff --git a/configure/RELEASE b/configure/RELEASE index f7dcbee..fecc7e2 100644 --- a/configure/RELEASE +++ b/configure/RELEASE @@ -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 diff --git a/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFT.cpp b/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFT.cpp index 7456600..aa3dc21 100644 --- a/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFT.cpp +++ b/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFT.cpp @@ -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; inChoice; 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; +} diff --git a/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFT.h b/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFT.h index 3f0783f..6f4e0d2 100644 --- a/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFT.h +++ b/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFT.h @@ -19,6 +19,7 @@ #include "inttypes.h" #include #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) diff --git a/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFTDefs.h b/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFTDefs.h index 8e6d4cd..f5caed7 100644 --- a/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFTDefs.h +++ b/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcFFTDefs.h @@ -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=" diff --git a/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcPluginFFT.c b/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcPluginFFT.c index f0efe90..0f7d4b8 100644 --- a/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcPluginFFT.c +++ b/ecmc_plugin_fft/ecmc_plugin_fftApp/src/ecmcPluginFFT.c @@ -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" : Sets source variable for FFT (example: ec0.s1.AI_1).\n" - " "ECMC_PLUGIN_NFFT_OPTION_CMD" : 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" : Continious or triggered mode, defaults to TRIGG\n" - " "ECMC_PLUGIN_RATE_OPTION_CMD" : 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" : Sets source variable for FFT (example: ec0.s1.AI_1).\n" + " "ECMC_PLUGIN_NFFT_OPTION_CMD" : 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" : Continious or triggered mode, defaults to TRIGG\n" + " "ECMC_PLUGIN_RATE_OPTION_CMD" : 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" : Use epics breaktable to convert raw values (applied before any other signal cond. alg.), default not used." , // Plugin version .version = ECMC_EXAMPLE_PLUGIN_VERSION,