Use dedicated asynport for each fft object (to not disturb ecmc).
This commit is contained in:
@@ -3,9 +3,9 @@ record(longin,"$(P)Plugin-FFT${INDEX}-stat"){
|
||||
field(DESC, "Status")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt32")
|
||||
field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt32/plugin.fft${INDEX}.status?")
|
||||
field(INP, "@asyn(PLUGIN.FFT${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.fft${INDEX}.status")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "$(TSE=-2)")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Data source
|
||||
@@ -13,11 +13,11 @@ record(waveform,"$(P)Plugin-FFT${INDEX}-Source"){
|
||||
field(DESC, "Data source name")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt8ArrayIn/plugin.fft${INDEX}.source?")
|
||||
field(INP, "@asyn(PLUGIN.FFT${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.fft${INDEX}.source")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "1024")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "$(TSE=-2)")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Rawdata
|
||||
@@ -26,11 +26,11 @@ record(waveform,"$(P)Plugin-FFT${INDEX}-Raw-Data-Act"){
|
||||
field(DESC, "Raw data")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynFloat64ArrayIn")
|
||||
field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynFloat64ArrayIn/plugin.fft${INDEX}.rawdata?")
|
||||
field(INP, "@asyn(PLUGIN.FFT${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.fft${INDEX}.rawdata")
|
||||
field(FTVL, "DOUBLE")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "$(TSE=-2)")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# FFT amplitude result
|
||||
@@ -39,11 +39,11 @@ record(waveform,"$(P)Plugin-FFT${INDEX}-Spectrum-Amp-Act"){
|
||||
field(DESC, "FFT spectrum amplitude result")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynFloat64ArrayIn")
|
||||
field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynFloat64ArrayIn/plugin.fft${INDEX}.fftamplitude?")
|
||||
field(INP, "@asyn(PLUGIN.FFT${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.fft${INDEX}.fftamplitude")
|
||||
field(FTVL, "DOUBLE")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "$(TSE=-2)")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# FFT xaxis
|
||||
@@ -52,17 +52,17 @@ record(waveform,"$(P)Plugin-FFT${INDEX}-Spectrum-X-Axis-Act"){
|
||||
field(DESC, "Raw data")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynFloat64ArrayIn")
|
||||
field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynFloat64ArrayIn/plugin.fft${INDEX}.fftxaxis?")
|
||||
field(INP, "@asyn(PLUGIN.FFT${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.fft${INDEX}.fftxaxis")
|
||||
field(FTVL, "DOUBLE")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "$(TSE=-2)")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
record(bo,"$(P)Plugin-FFT${INDEX}-Enable"){
|
||||
field(DESC, "FFT Enable")
|
||||
field(DTYP,"asynInt32")
|
||||
field(OUT, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt32/plugin.fft${INDEX}.enable=")
|
||||
field(OUT, "@asyn(PLUGIN.FFT${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.fft${INDEX}.enable")
|
||||
field(ZNAM,"FALSE")
|
||||
field(ONAM,"TRUE")
|
||||
field(DOL, "0")
|
||||
@@ -72,7 +72,7 @@ record(bo,"$(P)Plugin-FFT${INDEX}-Enable"){
|
||||
record(bo,"$(P)Plugin-FFT${INDEX}-Trigg"){
|
||||
field(DESC, "FFT Trigg measurement")
|
||||
field(DTYP,"asynInt32")
|
||||
field(OUT, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt32/plugin.fft${INDEX}.trigg=")
|
||||
field(OUT, "@asyn(PLUGIN.FFT${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.fft${INDEX}.trigg")
|
||||
field(ZNAM,"FALSE")
|
||||
field(ONAM,"TRUE")
|
||||
field(DOL, "0")
|
||||
@@ -82,9 +82,8 @@ record(bo,"$(P)Plugin-FFT${INDEX}-Trigg"){
|
||||
record(longout,"$(P)Plugin-FFT${INDEX}-Mode-RB"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(PINI, "1")
|
||||
field(TSE, -2)
|
||||
field(TSE, "0")
|
||||
field(DTYP, "asynInt32")
|
||||
field(OUT, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt32/plugin.fft${INDEX}.mode=")
|
||||
field(OUT, "@asyn(PLUGIN.FFT${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.fft${INDEX}.mode")
|
||||
field(SCAN, "Passive")
|
||||
field(TSE, "$(TSE=0)")
|
||||
}
|
||||
|
||||
@@ -68,21 +68,37 @@ void f_worker(void *obj) {
|
||||
* - runtime_error
|
||||
*/
|
||||
ecmcFFT::ecmcFFT(int fftIndex, // index of this object (if several is created)
|
||||
char* configStr) {
|
||||
char* configStr,
|
||||
char* portName)
|
||||
: asynPortDriver(portName,
|
||||
1, /* maxAddr */
|
||||
asynInt32Mask | asynFloat64Mask | asynFloat32ArrayMask |
|
||||
asynFloat64ArrayMask | asynEnumMask | asynDrvUserMask |
|
||||
asynOctetMask | asynInt8ArrayMask | asynInt16ArrayMask |
|
||||
asynInt32ArrayMask | asynUInt32DigitalMask, /* Interface mask */
|
||||
asynInt32Mask | asynFloat64Mask | asynFloat32ArrayMask |
|
||||
asynFloat64ArrayMask | asynEnumMask | asynDrvUserMask |
|
||||
asynOctetMask | asynInt8ArrayMask | asynInt16ArrayMask |
|
||||
asynInt32ArrayMask | asynUInt32DigitalMask, /* Interrupt mask */
|
||||
ASYN_CANBLOCK , /*NOT ASYN_MULTI_DEVICE*/
|
||||
1, /* Autoconnect */
|
||||
0, /* Default priority */
|
||||
0) /* Default stack size */
|
||||
{
|
||||
cfgDataSourceStr_ = NULL;
|
||||
rawDataBuffer_ = NULL;
|
||||
dataItem_ = NULL;
|
||||
dataItemInfo_ = NULL;
|
||||
fftDouble_ = NULL;
|
||||
asynPort_ = NULL;
|
||||
asynEnable_ = NULL; // Enable
|
||||
asynRawData_ = NULL; // Input data
|
||||
asynFFTAmp_ = NULL; // Result
|
||||
asynFFTMode_ = NULL; // Mode
|
||||
asynFFTStat_ = NULL; // Status
|
||||
asynSource_ = NULL; // Source
|
||||
asynTrigg_ = NULL; // Trigg new measurement
|
||||
asynFFTXAxis_ = NULL; // Result x axis
|
||||
// asynPort_ = NULL;
|
||||
// asynEnable_ = NULL; // Enable
|
||||
// asynRawData_ = NULL; // Input data
|
||||
// asynFFTAmp_ = NULL; // Result
|
||||
// asynFFTMode_ = NULL; // Mode
|
||||
// asynFFTStat_ = NULL; // Status
|
||||
// asynSource_ = NULL; // Source
|
||||
// asynTrigg_ = NULL; // Trigg new measurement
|
||||
// asynFFTXAxis_ = NULL; // Result x axis
|
||||
status_ = NO_STAT;
|
||||
elementsInBuffer_ = 0;
|
||||
fftWaitingForCalc_= 0;
|
||||
@@ -94,6 +110,16 @@ ecmcFFT::ecmcFFT(int fftIndex, // index of this object (if several is cr
|
||||
cycleCounter_ = 0;
|
||||
ignoreCycles_ = 0;
|
||||
|
||||
// New asyn
|
||||
asynEnableId_ = -1; // Enable/disable acq./calcs
|
||||
asynRawDataId_ = -1; // Raw data (input) array (double)
|
||||
asynFFTAmpId_ = -1; // FFT amplitude array (double)
|
||||
asynFFTModeId_ = -1; // FFT mode (cont/trigg)
|
||||
asynFFTStatId_ = -1; // FFT status (no_stat/idle/acq/calc)
|
||||
asynSourceId_ = -1; // SOURCE
|
||||
asynTriggId_ = -1; // Trigg new measurement
|
||||
asynFFTXAxisId_ = -1; // FFT X-axis frequencies
|
||||
|
||||
ecmcSampleRateHz_ = getEcmcSampleRate();
|
||||
cfgFFTSampleRateHz_ = ecmcSampleRateHz_;
|
||||
|
||||
@@ -105,10 +131,10 @@ ecmcFFT::ecmcFFT(int fftIndex, // index of this object (if several is cr
|
||||
cfgEnable_ = 0; // start disabled (enable over asyn)
|
||||
cfgMode_ = TRIGG;
|
||||
|
||||
asynPort_ = (ecmcAsynPortDriver*) getEcmcAsynPortDriver();
|
||||
if(!asynPort_) {
|
||||
throw std::runtime_error("Asyn port NULL");
|
||||
}
|
||||
// asynPort_ = (ecmcAsynPortDriver*) getEcmcAsynPortDriver();
|
||||
// if(!asynPort_) {
|
||||
// throw std::runtime_error("Asyn port NULL");
|
||||
// }
|
||||
|
||||
parseConfigStr(configStr); // Assigns all configs
|
||||
// Check valid nfft
|
||||
@@ -326,30 +352,6 @@ void ecmcFFT::dataUpdatedCallback(uint8_t* data,
|
||||
updateStatus(CALC);
|
||||
fftWaitingForCalc_ = 1;
|
||||
doCalcEvent_.signal(); // let worker start
|
||||
|
||||
// // **** Breakout to sperate low prio work thread below
|
||||
// removeDCOffset(); // Remove dc on rawdata
|
||||
// calcFFT(); // FFT cacluation
|
||||
// scaleFFT(); // Scale FFT
|
||||
// calcFFTAmp(); // Calculate amplitude from complex
|
||||
// // **** Breakout to thread above
|
||||
|
||||
// triggOnce_ = 0; // Wait for nex trigger if in trigg mode
|
||||
|
||||
// // Update asyn with both input and result
|
||||
// asynRawData_->refreshParamRT(1); // Forced update (do not consider record rate)
|
||||
// asynFFTAmp_->refreshParamRT(1); // Forced update (do not consider record rate)
|
||||
// //asynFFTXAxis_->refreshParamRT(1); // Forced update (do not consider record rate)
|
||||
|
||||
// if(cfgDbgMode_){
|
||||
// printComplexArray(fftBufferResult_,
|
||||
// cfgNfft_,
|
||||
// objectId_);
|
||||
// printEcDataArray((uint8_t*)rawDataBuffer_,
|
||||
// cfgNfft_*sizeof(double),
|
||||
// ECMC_EC_F64,
|
||||
// objectId_);
|
||||
//}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -660,155 +662,232 @@ size_t ecmcFFT::getEcDataTypeByteSize(ecmcEcDataType dt){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// register a dummy asyn parameter "plugin.adv.counter"
|
||||
void ecmcFFT::initAsyn() {
|
||||
|
||||
if(!asynPort_) {
|
||||
throw std::runtime_error("Asyn port NULL");
|
||||
}
|
||||
|
||||
|
||||
// Add enable "plugin.fft%d.enable"
|
||||
std::string paramName =ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
"." + ECMC_PLUGIN_ASYN_ENABLE;
|
||||
asynEnable_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
asynParamInt32, // asyn type
|
||||
(uint8_t *)&(cfgEnable_), // pointer to data
|
||||
sizeof(cfgEnable_), // size of data
|
||||
ECMC_EC_S32, // ecmc data type
|
||||
0); // die if fail
|
||||
|
||||
if(!asynEnable_) {
|
||||
throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
|
||||
if( createParam(0, paramName.c_str(), asynParamInt32, &asynEnableId_) != asynSuccess ) {
|
||||
throw std::runtime_error("Failed create asyn parameter enable");
|
||||
}
|
||||
asynEnable_->setAllowWriteToEcmc(true);
|
||||
asynEnable_->refreshParam(1); // read once into asyn param lib
|
||||
setIntegerParam(asynEnableId_, cfgEnable_);
|
||||
|
||||
// Add rawdata "plugin.fft%d.rawdata"
|
||||
paramName =ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
"." + ECMC_PLUGIN_ASYN_RAWDATA;
|
||||
|
||||
asynRawData_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
asynParamFloat64Array, // asyn type
|
||||
(uint8_t *)rawDataBuffer_, // pointer to data
|
||||
cfgNfft_*sizeof(double), // size of data
|
||||
ECMC_EC_F64, // ecmc data type
|
||||
0); // die if fail
|
||||
|
||||
if(!asynRawData_) {
|
||||
throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
if( createParam(0, paramName.c_str(), asynParamFloat64Array, &asynRawDataId_ ) != asynSuccess ) {
|
||||
throw std::runtime_error("Failed create asyn parameter rawdata");
|
||||
}
|
||||
asynRawData_->setAllowWriteToEcmc(false);
|
||||
asynRawData_->refreshParam(1); // read once into asyn param lib
|
||||
|
||||
doCallbacksFloat64Array(rawDataBuffer_, cfgNfft_, asynRawDataId_,0);
|
||||
|
||||
// Add fft amplitude "plugin.fft%d.fftamplitude"
|
||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
"." + ECMC_PLUGIN_ASYN_FFT_AMP;
|
||||
|
||||
asynFFTAmp_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
asynParamFloat64Array, // asyn type
|
||||
(uint8_t *)fftBufferResultAmp_, // pointer to data
|
||||
(cfgNfft_ / 2 + 1)*sizeof(double), // size of data
|
||||
ECMC_EC_F64, // ecmc data type
|
||||
0); // die if fail
|
||||
|
||||
if(!asynFFTAmp_) {
|
||||
throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
if( createParam(0, paramName.c_str(), asynParamFloat64Array, &asynFFTAmpId_ ) != asynSuccess ) {
|
||||
throw std::runtime_error("Failed create asyn parameter fftamplitude");
|
||||
}
|
||||
|
||||
asynFFTAmp_->setAllowWriteToEcmc(false);
|
||||
asynFFTAmp_->refreshParam(1); // read once into asyn param lib
|
||||
doCallbacksFloat64Array(fftBufferResultAmp_, cfgNfft_/2+1, asynFFTXAxisId_,0);
|
||||
|
||||
// Add fft mode "plugin.fft%d.mode"
|
||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
"." + ECMC_PLUGIN_ASYN_FFT_MODE;
|
||||
|
||||
asynFFTMode_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
asynParamInt32, // asyn type
|
||||
(uint8_t *)(&cfgMode_), // pointer to data
|
||||
sizeof(cfgMode_), // size of data
|
||||
ECMC_EC_S32, // ecmc data type
|
||||
0); // die if fail
|
||||
|
||||
if(!asynFFTMode_) {
|
||||
throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
if( createParam(0, paramName.c_str(), asynParamInt32, &asynFFTModeId_ ) != asynSuccess ) {
|
||||
throw std::runtime_error("Failed create asyn parameter mode");
|
||||
}
|
||||
|
||||
asynFFTMode_->setAllowWriteToEcmc(true);
|
||||
asynFFTMode_->refreshParam(1); // read once into asyn param lib
|
||||
setIntegerParam(asynFFTModeId_, (epicsInt32)cfgMode_);
|
||||
|
||||
// Add fft mode "plugin.fft%d.status"
|
||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
"." + ECMC_PLUGIN_ASYN_FFT_STAT;
|
||||
|
||||
asynFFTStat_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
asynParamInt32, // asyn type
|
||||
(uint8_t *)(&status_), // pointer to data
|
||||
sizeof(status_), // size of data
|
||||
ECMC_EC_S32, // ecmc data type
|
||||
0); // die if fail
|
||||
|
||||
if(!asynFFTStat_) {
|
||||
throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
if( createParam(0, paramName.c_str(), asynParamInt32, &asynFFTStatId_ ) != asynSuccess ) {
|
||||
throw std::runtime_error("Failed create asyn parameter status");
|
||||
}
|
||||
setIntegerParam(asynFFTStatId_, (epicsInt32)status_);
|
||||
|
||||
asynFFTStat_->setAllowWriteToEcmc(false);
|
||||
asynFFTStat_->refreshParam(1); // read once into asyn param lib
|
||||
|
||||
// Add fft mode "plugin.fft%d.status"
|
||||
// Add fft mode "plugin.fft%d.source"
|
||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
"." + ECMC_PLUGIN_ASYN_FFT_SOURCE;
|
||||
|
||||
asynSource_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
asynParamInt8Array, // asyn type
|
||||
(uint8_t *)cfgDataSourceStr_, // pointer to data
|
||||
strlen(cfgDataSourceStr_), // size of data
|
||||
ECMC_EC_U8, // ecmc data type
|
||||
0); // die if fail
|
||||
|
||||
if(!asynSource_) {
|
||||
throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
if( createParam(0, paramName.c_str(), asynParamInt8Array, &asynSourceId_ ) != asynSuccess ) {
|
||||
throw std::runtime_error("Failed create asyn parameter source");
|
||||
}
|
||||
|
||||
asynSource_->setAllowWriteToEcmc(false);
|
||||
asynSource_->refreshParam(1); // read once into asyn param lib
|
||||
doCallbacksInt8Array(cfgDataSourceStr_, strlen(cfgDataSourceStr_), asynSourceId_,0);
|
||||
|
||||
// Add fft mode "plugin.fft%d.trigg"
|
||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
"." + ECMC_PLUGIN_ASYN_FFT_TRIGG;
|
||||
|
||||
asynTrigg_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
asynParamInt32, // asyn type
|
||||
(uint8_t *)(&triggOnce_), // pointer to data
|
||||
sizeof(triggOnce_), // size of data
|
||||
ECMC_EC_S32, // ecmc data type
|
||||
0); // die if fail
|
||||
|
||||
if(!asynTrigg_) {
|
||||
throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
if( createParam(0, paramName.c_str(), asynParamInt32, &asynTriggId_ ) != asynSuccess ) {
|
||||
throw std::runtime_error("Failed create asyn parameter trigg");
|
||||
}
|
||||
|
||||
asynTrigg_->setAllowWriteToEcmc(true);
|
||||
asynTrigg_->refreshParam(1); // read once into asyn param lib
|
||||
setIntegerParam(asynTriggId_, (epicsInt32)triggOnce_);
|
||||
|
||||
// Add fft mode "plugin.fft%d.xaxisfreqs"
|
||||
paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
"." + ECMC_PLUGIN_ASYN_FFT_X_FREQS;
|
||||
|
||||
asynFFTXAxis_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
asynParamFloat64Array, // asyn type
|
||||
(uint8_t *)fftBufferXAxis_, // pointer to data
|
||||
(cfgNfft_ / 2 + 1) * sizeof(double), // size of data
|
||||
ECMC_EC_F64, // ecmc data type
|
||||
0); // die if fail
|
||||
|
||||
if(!asynFFTXAxis_) {
|
||||
throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
if( createParam(0, paramName.c_str(), asynParamFloat64Array, &asynFFTXAxisId_ ) != asynSuccess ) {
|
||||
throw std::runtime_error("Failed create asyn parameter xaxisfreqs");
|
||||
}
|
||||
doCallbacksFloat64Array(fftBufferXAxis_,cfgNfft_/2+1, asynFFTXAxisId_,0);
|
||||
|
||||
asynFFTXAxis_->setAllowWriteToEcmc(false);
|
||||
asynFFTXAxis_->refreshParam(1); // read once into asyn param lib
|
||||
// Update integers
|
||||
callParamCallbacks();
|
||||
}
|
||||
|
||||
// void ecmcFFT::initAsyn() {
|
||||
|
||||
// if(!asynPort_) {
|
||||
// throw std::runtime_error("Asyn port NULL");
|
||||
// }
|
||||
|
||||
// // Add enable "plugin.fft%d.enable"
|
||||
// std::string paramName =ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
// "." + ECMC_PLUGIN_ASYN_ENABLE;
|
||||
// asynEnable_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
// asynParamInt32, // asyn type
|
||||
// (uint8_t *)&(cfgEnable_), // pointer to data
|
||||
// sizeof(cfgEnable_), // size of data
|
||||
// ECMC_EC_S32, // ecmc data type
|
||||
// 0); // die if fail
|
||||
|
||||
// if(!asynEnable_) {
|
||||
// throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
// }
|
||||
// asynEnable_->setAllowWriteToEcmc(true);
|
||||
// asynEnable_->refreshParam(1); // read once into asyn param lib
|
||||
|
||||
// // Add rawdata "plugin.fft%d.rawdata"
|
||||
// paramName =ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
// "." + ECMC_PLUGIN_ASYN_RAWDATA;
|
||||
|
||||
// asynRawData_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
// asynParamFloat64Array, // asyn type
|
||||
// (uint8_t *)rawDataBuffer_, // pointer to data
|
||||
// cfgNfft_*sizeof(double), // size of data
|
||||
// ECMC_EC_F64, // ecmc data type
|
||||
// 0); // die if fail
|
||||
|
||||
// if(!asynRawData_) {
|
||||
// throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
// }
|
||||
// asynRawData_->setAllowWriteToEcmc(false);
|
||||
// asynRawData_->refreshParam(1); // read once into asyn param lib
|
||||
|
||||
// // Add fft amplitude "plugin.fft%d.fftamplitude"
|
||||
// paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
// "." + ECMC_PLUGIN_ASYN_FFT_AMP;
|
||||
|
||||
// asynFFTAmp_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
// asynParamFloat64Array, // asyn type
|
||||
// (uint8_t *)fftBufferResultAmp_, // pointer to data
|
||||
// (cfgNfft_ / 2 + 1)*sizeof(double), // size of data
|
||||
// ECMC_EC_F64, // ecmc data type
|
||||
// 0); // die if fail
|
||||
|
||||
// if(!asynFFTAmp_) {
|
||||
// throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
// }
|
||||
|
||||
// asynFFTAmp_->setAllowWriteToEcmc(false);
|
||||
// asynFFTAmp_->refreshParam(1); // read once into asyn param lib
|
||||
|
||||
// // Add fft mode "plugin.fft%d.mode"
|
||||
// paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
// "." + ECMC_PLUGIN_ASYN_FFT_MODE;
|
||||
|
||||
// asynFFTMode_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
// asynParamInt32, // asyn type
|
||||
// (uint8_t *)(&cfgMode_), // pointer to data
|
||||
// sizeof(cfgMode_), // size of data
|
||||
// ECMC_EC_S32, // ecmc data type
|
||||
// 0); // die if fail
|
||||
|
||||
// if(!asynFFTMode_) {
|
||||
// throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
// }
|
||||
|
||||
// asynFFTMode_->setAllowWriteToEcmc(true);
|
||||
// asynFFTMode_->refreshParam(1); // read once into asyn param lib
|
||||
|
||||
// // Add fft mode "plugin.fft%d.status"
|
||||
// paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
// "." + ECMC_PLUGIN_ASYN_FFT_STAT;
|
||||
|
||||
// asynFFTStat_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
// asynParamInt32, // asyn type
|
||||
// (uint8_t *)(&status_), // pointer to data
|
||||
// sizeof(status_), // size of data
|
||||
// ECMC_EC_S32, // ecmc data type
|
||||
// 0); // die if fail
|
||||
|
||||
// if(!asynFFTStat_) {
|
||||
// throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
// }
|
||||
|
||||
// asynFFTStat_->setAllowWriteToEcmc(false);
|
||||
// asynFFTStat_->refreshParam(1); // read once into asyn param lib
|
||||
|
||||
// // Add fft mode "plugin.fft%d.status"
|
||||
// paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
// "." + ECMC_PLUGIN_ASYN_FFT_SOURCE;
|
||||
|
||||
// asynSource_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
// asynParamInt8Array, // asyn type
|
||||
// (uint8_t *)cfgDataSourceStr_, // pointer to data
|
||||
// strlen(cfgDataSourceStr_), // size of data
|
||||
// ECMC_EC_U8, // ecmc data type
|
||||
// 0); // die if fail
|
||||
|
||||
// if(!asynSource_) {
|
||||
// throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
// }doCallbacksFloat64Array(rawDataBuffer_,cfgNfft_, asynRawDataId_,0);
|
||||
|
||||
// asynSource_->setAllowWriteToEcmc(false);
|
||||
// asynSource_->refreshParam(1); // read once into asyn param lib
|
||||
|
||||
// // Add fft mode "plugin.fft%d.trigg"
|
||||
// paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
// "." + ECMC_PLUGIN_ASYN_FFT_TRIGG;
|
||||
|
||||
// asynTrigg_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
// asynParamInt32, // asyn type
|
||||
// (uint8_t *)(&triggOnce_), // pointer to data
|
||||
// sizeof(triggOnce_), // size of data
|
||||
// ECMC_EC_S32, // ecmc data type
|
||||
// 0); // die if fail
|
||||
|
||||
// if(!asynTrigg_) {
|
||||
// throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
// }
|
||||
|
||||
// asynTrigg_->setAllowWriteToEcmc(true);
|
||||
// asynTrigg_->refreshParam(1); // read once into asyn param lib
|
||||
|
||||
// // Add fft mode "plugin.fft%d.xaxisfreqs"
|
||||
// paramName = ECMC_PLUGIN_ASYN_PREFIX + to_string(objectId_) +
|
||||
// "." + ECMC_PLUGIN_ASYN_FFT_X_FREQS;
|
||||
|
||||
// asynFFTXAxis_ = asynPort_->addNewAvailParam(paramName.c_str(), // name
|
||||
// asynParamFloat64Array, // asyn type
|
||||
// (uint8_t *)fftBufferXAxis_, // pointer to data
|
||||
// (cfgNfft_ / 2 + 1) * sizeof(double), // size of data
|
||||
// ECMC_EC_F64, // ecmc data type
|
||||
// 0); // die if fail
|
||||
|
||||
// if(!asynFFTXAxis_) {
|
||||
// throw std::runtime_error("Failed to create asyn parameter \"" + paramName +"\".\n");
|
||||
// }
|
||||
|
||||
// asynFFTXAxis_->setAllowWriteToEcmc(false);
|
||||
// asynFFTXAxis_->refreshParam(1); // read once into asyn param lib
|
||||
// }
|
||||
|
||||
// Avoid issues with std:to_string()
|
||||
std::string ecmcFFT::to_string(int value) {
|
||||
std::ostringstream os;
|
||||
@@ -827,6 +906,7 @@ void ecmcFFT::triggFFT() {
|
||||
|
||||
void ecmcFFT::setModeFFT(FFT_MODE mode) {
|
||||
cfgMode_ = mode;
|
||||
setIntegerParam(asynFFTModeId_,(epicsInt32)mode);
|
||||
}
|
||||
|
||||
FFT_STATUS ecmcFFT::getStatusFFT() {
|
||||
@@ -835,7 +915,8 @@ FFT_STATUS ecmcFFT::getStatusFFT() {
|
||||
|
||||
void ecmcFFT::updateStatus(FFT_STATUS status) {
|
||||
status_ = status;
|
||||
asynFFTStat_->refreshParamRT(1);
|
||||
setIntegerParam(asynFFTStatId_,(epicsInt32) status);
|
||||
callParamCallbacks();
|
||||
}
|
||||
|
||||
// Do nut use this as same time as callback!
|
||||
@@ -864,9 +945,10 @@ void ecmcFFT::doCalcWorker() {
|
||||
// NOTE these calls should not be here.. since they belong to other thread
|
||||
// Update asyn with both input and result
|
||||
triggOnce_ = 0; // Wait for next trigger if in trigg mode
|
||||
asynRawData_->refreshParamRT(1); // Forced update (do not consider record rate)
|
||||
asynFFTAmp_->refreshParamRT(1); // Forced update (do not consider record rate)
|
||||
//asynFFTXAxis_->refreshParamRT(1); // Forced update (do not consider record rate)
|
||||
|
||||
doCallbacksFloat64Array(rawDataBuffer_,cfgNfft_, asynRawDataId_,0);
|
||||
doCallbacksFloat64Array(fftBufferResultAmp_,cfgNfft_/2+1, asynFFTAmpId_,0);
|
||||
|
||||
printf("END CALC in worker for object %d###############################\n",objectId_);
|
||||
|
||||
if(cfgDbgMode_){
|
||||
@@ -882,4 +964,87 @@ void ecmcFFT::doCalcWorker() {
|
||||
clearBuffers();
|
||||
fftWaitingForCalc_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asynStatus ecmcFFT::writeInt32(asynUser *pasynUser, epicsInt32 value) {
|
||||
int function = pasynUser->reason;
|
||||
if( function == asynEnableId_ ) {
|
||||
cfgEnable_ = value;
|
||||
return asynSuccess;
|
||||
} else if( function == asynFFTModeId_){
|
||||
cfgMode_ = (FFT_MODE)value;
|
||||
return asynSuccess;
|
||||
} else if( function == asynTriggId_){
|
||||
triggOnce_ = value > 0;
|
||||
return asynSuccess;
|
||||
}
|
||||
return asynError;
|
||||
}
|
||||
|
||||
asynStatus ecmcFFT::readInt32(asynUser *pasynUser, epicsInt32 *value) {
|
||||
int function = pasynUser->reason;
|
||||
if( function == asynEnableId_ ) {
|
||||
*value = cfgEnable_;
|
||||
return asynSuccess;
|
||||
} else if( function == asynFFTModeId_ ){
|
||||
*value = cfgMode_;
|
||||
return asynSuccess;
|
||||
} else if( function == asynTriggId_ ){
|
||||
*value = triggOnce_;
|
||||
return asynSuccess;
|
||||
}else if( function == asynFFTStatId_ ){
|
||||
*value = (epicsInt32)status_;
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
return asynError;
|
||||
}
|
||||
|
||||
asynStatus ecmcFFT::readFloat64Array(asynUser *pasynUser, epicsFloat64 *value,
|
||||
size_t nElements, size_t *nIn) {
|
||||
int function = pasynUser->reason;
|
||||
if( function == asynRawDataId_ ) {
|
||||
unsigned int ncopy = cfgNfft_;
|
||||
if(nElements < ncopy) {
|
||||
ncopy = nElements;
|
||||
}
|
||||
memcpy (value, rawDataBuffer_, ncopy);
|
||||
*nIn = ncopy;
|
||||
return asynSuccess;
|
||||
} else if( function == asynFFTXAxisId_ ) {
|
||||
unsigned int ncopy = cfgNfft_/ 2 + 1;
|
||||
if(nElements < ncopy) {
|
||||
ncopy = nElements;
|
||||
}
|
||||
memcpy (value, fftBufferXAxis_, ncopy);
|
||||
*nIn = ncopy;
|
||||
return asynSuccess;
|
||||
} if( function == asynFFTAmpId_ ) {
|
||||
unsigned int ncopy = cfgNfft_/ 2 + 1;
|
||||
if(nElements < ncopy) {
|
||||
ncopy = nElements;
|
||||
}
|
||||
memcpy (value, fftBufferResultAmp_, ncopy);
|
||||
*nIn = ncopy;
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
*nIn = 0;
|
||||
return asynError;
|
||||
}
|
||||
asynStatus ecmcFFT::readInt8Array(asynUser *pasynUser, epicsInt8 *value,
|
||||
size_t nElements, size_t *nIn) {
|
||||
int function = pasynUser->reason;
|
||||
if( function == asynSourceId_ ) {
|
||||
unsigned int ncopy = strlen(cfgDataSourceStr_);
|
||||
if(nElements < ncopy) {
|
||||
ncopy = nElements;
|
||||
}
|
||||
memcpy (value, cfgDataSourceStr_, ncopy);
|
||||
*nIn = ncopy;
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
*nIn = 0;
|
||||
return asynError;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <string>
|
||||
#include "kissfft/kissfft.hh"
|
||||
|
||||
class ecmcFFT {
|
||||
class ecmcFFT : public asynPortDriver {
|
||||
public:
|
||||
|
||||
/** ecmc FFT class
|
||||
@@ -31,7 +31,8 @@ class ecmcFFT {
|
||||
* - out_of_range
|
||||
*/
|
||||
ecmcFFT(int fftIndex, // index of this object
|
||||
char* configStr);
|
||||
char* configStr,
|
||||
char* portName);
|
||||
~ecmcFFT();
|
||||
|
||||
// Add data to buffer (called from "external" callback)
|
||||
@@ -49,6 +50,13 @@ class ecmcFFT {
|
||||
/** Do not use this as same time as callback!
|
||||
* if used it should be called from ecmc realtime callback*/
|
||||
void sampleData();
|
||||
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
||||
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);
|
||||
|
||||
|
||||
private:
|
||||
void parseConfigStr(char *configStr);
|
||||
@@ -94,14 +102,24 @@ class ecmcFFT {
|
||||
double cfgFFTSampleRateHz_; // Config: Sample rate (defaukts to ecmc rate)
|
||||
|
||||
// Asyn
|
||||
ecmcAsynDataItem* asynEnable_; // Enable/disable acq./calcs
|
||||
ecmcAsynDataItem* asynRawData_; // Raw data (input) array (double)
|
||||
ecmcAsynDataItem* asynFFTAmp_; // FFT amplitude array (double)
|
||||
ecmcAsynDataItem* asynFFTMode_; // FFT mode (cont/trigg)
|
||||
ecmcAsynDataItem* asynFFTStat_; // FFT status (no_stat/idle/acq/calc)
|
||||
ecmcAsynDataItem* asynSource_; // SOURCE
|
||||
ecmcAsynDataItem* asynTrigg_; // Trigg new measurement
|
||||
ecmcAsynDataItem* asynFFTXAxis_; // FFT X-axis frequencies
|
||||
// ecmcAsynDataItem* asynEnable_; // Enable/disable acq./calcs
|
||||
// ecmcAsynDataItem* asynRawData_; // Raw data (input) array (double)
|
||||
// ecmcAsynDataItem* asynFFTAmp_; // FFT amplitude array (double)
|
||||
// ecmcAsynDataItem* asynFFTMode_; // FFT mode (cont/trigg)
|
||||
// ecmcAsynDataItem* asynFFTStat_; // FFT status (no_stat/idle/acq/calc)
|
||||
// ecmcAsynDataItem* asynSource_; // SOURCE
|
||||
// ecmcAsynDataItem* asynTrigg_; // Trigg new measurement
|
||||
// ecmcAsynDataItem* asynFFTXAxis_; // FFT X-axis frequencies
|
||||
|
||||
// New Asyn
|
||||
int asynEnableId_; // Enable/disable acq./calcs
|
||||
int asynRawDataId_; // Raw data (input) array (double)
|
||||
int asynFFTAmpId_; // FFT amplitude array (double)
|
||||
int asynFFTModeId_; // FFT mode (cont/trigg)
|
||||
int asynFFTStatId_; // FFT status (no_stat/idle/acq/calc)
|
||||
int asynSourceId_; // SOURCE
|
||||
int asynTriggId_; // Trigg new measurement
|
||||
int asynFFTXAxisId_; // FFT X-axis frequencies
|
||||
|
||||
// Thread related
|
||||
epicsEvent doCalcEvent_;
|
||||
|
||||
@@ -16,19 +16,29 @@
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include "ecmcFFTWrap.h"
|
||||
#include "ecmcFFT.h"
|
||||
#include "ecmcFFTDefs.h"
|
||||
|
||||
#define ECMC_PLUGIN_MAX_PORTNAME_CHARS 64
|
||||
#define ECMC_PLUGIN_PORTNAME_PREFIX "PLUGIN.FFT"
|
||||
|
||||
static std::vector<ecmcFFT*> ffts;
|
||||
static int fftObjCounter = 0;
|
||||
static char portNameBuffer[ECMC_PLUGIN_MAX_PORTNAME_CHARS];
|
||||
|
||||
int createFFT(char* configStr) {
|
||||
|
||||
// create new ecmcFFT object
|
||||
ecmcFFT* fft = NULL;
|
||||
|
||||
// create asynport name for new object ()
|
||||
memset(portNameBuffer, 0, ECMC_PLUGIN_MAX_PORTNAME_CHARS);
|
||||
snprintf (portNameBuffer, ECMC_PLUGIN_MAX_PORTNAME_CHARS,
|
||||
ECMC_PLUGIN_PORTNAME_PREFIX "%d", fftObjCounter);
|
||||
try {
|
||||
fft = new ecmcFFT(fftObjCounter, configStr);
|
||||
fft = new ecmcFFT(fftObjCounter, configStr,portNameBuffer);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
if(fft) {
|
||||
|
||||
Reference in New Issue
Block a user