Prevent link to datasource several times if several FFT objs.

This commit is contained in:
Anders Sandström
2020-04-08 19:53:15 +02:00
parent e7d149014e
commit c5ad807dad
3 changed files with 59 additions and 8 deletions

View File

@@ -23,6 +23,9 @@
#define ECMC_PLUGIN_ASYN_FFT_SOURCE "source"
#define ECMC_PLUGIN_ASYN_FFT_TRIGG "trigg"
#define ECMC_PLUGIN_ASYN_FFT_X_FREQS "fftxaxis"
#define ECMC_PLUGIN_ASYN_NFFT "nfft"
#define ECMC_PLUGIN_ASYN_RATE "samplerate"
#include <sstream>
#include "ecmcFFT.h"
@@ -100,6 +103,7 @@ ecmcFFT::ecmcFFT(int fftIndex, // index of this object (if several is cr
triggOnce_ = 0;
cycleCounter_ = 0;
ignoreCycles_ = 0;
dataSourceLinked_ = 0;
// Asyn
asynEnableId_ = -1; // Enable/disable acq./calcs
@@ -110,6 +114,8 @@ ecmcFFT::ecmcFFT(int fftIndex, // index of this object (if several is cr
asynSourceId_ = -1; // SOURCE
asynTriggId_ = -1; // Trigg new measurement
asynFFTXAxisId_ = -1; // FFT X-axis frequencies
asynNfftId_ = -1; // Nfft
asynSRateId_ = -1; // Sample rate Hz
ecmcSampleRateHz_ = getEcmcSampleRate();
cfgFFTSampleRateHz_ = ecmcSampleRateHz_;
@@ -267,6 +273,12 @@ void ecmcFFT::parseConfigStr(char *configStr) {
}
void ecmcFFT::connectToDataSource() {
/* Check if already linked (one call to enterRT per loaded FFT lib (FFT object))
But link should only happen once!!*/
if( dataSourceLinked_ ) {
return;
}
// Get dataItem
dataItem_ = (ecmcDataItem*) getEcmcDataItem(cfgDataSourceStr_);
if(!dataItem_) {
@@ -285,7 +297,7 @@ void ecmcFFT::connectToDataSource() {
if( !dataTypeSupported(dataItem_->getEcmcDataType()) ) {
throw std::invalid_argument( "Data type not supported." );
}
dataSourceLinked_ = 1;
updateStatus(IDLE);
}
@@ -716,7 +728,7 @@ void ecmcFFT::initAsyn() {
}
setIntegerParam(asynTriggId_, (epicsInt32)triggOnce_);
// Add fft mode "plugin.fft%d.xaxisfreqs"
// Add fft mode "plugin.fft%d.fftxaxis"
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
"." + ECMC_PLUGIN_ASYN_FFT_X_FREQS;
@@ -725,6 +737,24 @@ void ecmcFFT::initAsyn() {
}
doCallbacksFloat64Array(fftBufferXAxis_,cfgNfft_ / 2 + 1, asynFFTXAxisId_,0);
// Add fft mode "plugin.fft%d.nfft"
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
"." + ECMC_PLUGIN_ASYN_NFFT;
if( createParam(0, paramName.c_str(), asynParamInt32, &asynNfftId_ ) != asynSuccess ) {
throw std::runtime_error("Failed create asyn parameter trigg");
}
setIntegerParam(asynNfftId_, (epicsInt32)cfgNfft_);
// Add fft mode "plugin.fft%d.rate"
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
"." + ECMC_PLUGIN_ASYN_RATE;
if( createParam(0, paramName.c_str(), asynParamInt32, &asynSRateId_ ) != asynSuccess ) {
throw std::runtime_error("Failed create asyn parameter trigg");
}
setDoubleParam(asynSRateId_, cfgFFTSampleRateHz_);
// Update integers
callParamCallbacks();
}
@@ -738,11 +768,13 @@ std::string ecmcFFT::to_string(int value) {
void ecmcFFT::setEnable(int enable) {
cfgEnable_ = enable;
setIntegerParam(asynEnableId_, enable);
}
void ecmcFFT::triggFFT() {
clearBuffers();
triggOnce_ = 1;
setIntegerParam(asynTriggId_,0);
}
void ecmcFFT::setModeFFT(FFT_MODE mode) {
@@ -760,7 +792,7 @@ void ecmcFFT::updateStatus(FFT_STATUS status) {
callParamCallbacks();
}
// Called from worker thread. Makes the hard work
// Called from low prio worker thread. Makes the hard work
void ecmcFFT::doCalcWorker() {
while(true) {
@@ -775,7 +807,6 @@ void ecmcFFT::doCalcWorker() {
calcFFTAmp(); // Calculate amplitude from complex
calcFFTXAxis(); // Calculate x axis
setIntegerParam(asynTriggId_,triggOnce_);
doCallbacksFloat64Array(rawDataBuffer_, cfgNfft_, asynRawDataId_, 0);
doCallbacksFloat64Array(fftBufferResultAmp_,cfgNfft_/2+1, asynFFTAmpId_, 0);
doCallbacksFloat64Array(fftBufferXAxis_, cfgNfft_/2+1, asynFFTXAxisId_,0);
@@ -789,8 +820,10 @@ void ecmcFFT::doCalcWorker() {
ECMC_EC_F64,
objectId_);
}
triggOnce_ = 0; // Wait for next trigger if in trigg mode
clearBuffers();
triggOnce_ = 0; // Wait for next trigger if in trigg mode
setIntegerParam(asynTriggId_,triggOnce_);
fftWaitingForCalc_ = 0;
}
}
@@ -824,6 +857,9 @@ asynStatus ecmcFFT::readInt32(asynUser *pasynUser, epicsInt32 *value) {
}else if( function == asynFFTStatId_ ){
*value = (epicsInt32)status_;
return asynSuccess;
}else if( function == asynNfftId_ ){
*value = (epicsInt32)cfgNfft_;
return asynSuccess;
}
return asynError;
@@ -861,6 +897,7 @@ asynStatus ecmcFFT::readFloat64Array(asynUser *pasynUser, epicsFloat64 *value,
*nIn = 0;
return asynError;
}
asynStatus ecmcFFT::readInt8Array(asynUser *pasynUser, epicsInt8 *value,
size_t nElements, size_t *nIn) {
int function = pasynUser->reason;
@@ -877,3 +914,13 @@ asynStatus ecmcFFT::readInt8Array(asynUser *pasynUser, epicsInt8 *value,
*nIn = 0;
return asynError;
}
asynStatus ecmcFFT::readFloat64(asynUser *pasynUser, epicsFloat64 *value) {
int function = pasynUser->reason;
if( function == asynSRateId_ ) {
*value = cfgFFTSampleRateHz_;
return asynSuccess;
}
return asynError;
}

View File

@@ -51,8 +51,9 @@ class ecmcFFT : public asynPortDriver {
virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
virtual asynStatus readFloat64Array(asynUser *pasynUser, epicsFloat64 *value,
size_t nElements, size_t *nIn);
virtual asynStatus readInt8Array(asynUser *pasynUser, epicsInt8 *value,
size_t nElements, size_t *nIn);
virtual asynStatus readInt8Array(asynUser *pasynUser, epicsInt8 *value,
size_t nElements, size_t *nIn);
virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
private:
@@ -78,6 +79,7 @@ class ecmcFFT : public asynPortDriver {
double* fftBufferXAxis_; // FFT x axis with freqs
size_t elementsInBuffer_;
double ecmcSampleRateHz_;
int dataSourceLinked_; // To avoid link several times
// ecmc callback handle for use when deregister at unload
int callbackHandle_;
int fftWaitingForCalc_;
@@ -108,6 +110,8 @@ class ecmcFFT : public asynPortDriver {
int asynSourceId_; // SOURCE
int asynTriggId_; // Trigg new measurement
int asynFFTXAxisId_; // FFT X-axis frequencies
int asynNfftId_; // NFFT
int asynSRateId_; // Sample rate
// Thread related
epicsEvent doCalcEvent_;

View File

@@ -38,7 +38,7 @@ int createFFT(char* configStr) {
snprintf (portNameBuffer, ECMC_PLUGIN_MAX_PORTNAME_CHARS,
ECMC_PLUGIN_PORTNAME_PREFIX "%d", fftObjCounter);
try {
fft = new ecmcFFT(fftObjCounter, configStr,portNameBuffer);
fft = new ecmcFFT(fftObjCounter, configStr, portNameBuffer);
}
catch(std::exception& e) {
if(fft) {