WIP.. it's a mess..
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcScope.cpp
|
||||
* ecmcDAQChannel.cpp
|
||||
*
|
||||
* Created on: Sept 22, 2020
|
||||
* Author: anderssandstrom
|
||||
@@ -14,7 +14,7 @@
|
||||
// Needed to get headers in ecmc right...
|
||||
#define ECMC_IS_PLUGIN
|
||||
|
||||
#define ECMC_PLUGIN_ASYN_PREFIX "plugin.scope"
|
||||
#define ECMC_PLUGIN_ASYN_PREFIX "plugin.daq"
|
||||
#define ECMC_PLUGIN_ASYN_ENABLE "enable"
|
||||
#define ECMC_PLUGIN_ASYN_RESULTDATA "resultdata"
|
||||
#define ECMC_PLUGIN_ASYN_SCOPE_SOURCE "source"
|
||||
@@ -33,7 +33,7 @@ if(cfgDbgMode_) { \
|
||||
#define ECMC_MAX_32BIT 0xFFFFFFFF
|
||||
|
||||
#include <sstream>
|
||||
#include "ecmcScope.h"
|
||||
#include "ecmcDAQChannel.h"
|
||||
#include "ecmcPluginClient.h"
|
||||
#include <limits>
|
||||
|
||||
@@ -43,9 +43,9 @@ if(cfgDbgMode_) { \
|
||||
* - invalid_argument
|
||||
* - runtime_error
|
||||
*/
|
||||
ecmcScope::ecmcScope(int scopeIndex, // index of this object (if several is created)
|
||||
ecmcDAQChannel::ecmcDAQChannel(int scopeIndex, // index of this object (if several is created)
|
||||
char* configStr){
|
||||
SCOPE_DBG_PRINT("ecmcScope::ecmcScope()");
|
||||
SCOPE_DBG_PRINT("ecmcDAQChannel::ecmcDAQChannel()");
|
||||
cfgDataSourceStr_ = NULL;
|
||||
cfgDataNexttimeStr_ = NULL;
|
||||
cfgTriggStr_ = NULL;
|
||||
@@ -105,7 +105,7 @@ ecmcScope::ecmcScope(int scopeIndex, // index of this object (if several
|
||||
resultDataBufferBytes_ = 0;
|
||||
}
|
||||
|
||||
ecmcScope::~ecmcScope() {
|
||||
ecmcDAQChannel::~ecmcDAQChannel() {
|
||||
|
||||
if(resultDataBuffer_) {
|
||||
delete[] resultDataBuffer_;
|
||||
@@ -127,8 +127,8 @@ ecmcScope::~ecmcScope() {
|
||||
|
||||
}
|
||||
|
||||
void ecmcScope::parseConfigStr(char *configStr) {
|
||||
SCOPE_DBG_PRINT("ecmcScope::parseConfigStr()");
|
||||
void ecmcDAQChannel::parseConfigStr(char *configStr) {
|
||||
SCOPE_DBG_PRINT("ecmcDAQChannel::parseConfigStr()");
|
||||
// check config parameters
|
||||
if (configStr && configStr[0]) {
|
||||
char *pOptions = strdup(configStr);
|
||||
@@ -210,8 +210,8 @@ void ecmcScope::parseConfigStr(char *configStr) {
|
||||
}
|
||||
}
|
||||
|
||||
void ecmcScope::connectToDataSources() {
|
||||
SCOPE_DBG_PRINT("ecmcScope::connectToDataSources()");
|
||||
void ecmcDAQChannel::connectToDataSources() {
|
||||
SCOPE_DBG_PRINT("ecmcDAQChannel::connectToDataSources()");
|
||||
/* Check if already linked (one call to connectToDataSources (enterRT) per loaded Scope lib (Scope object))
|
||||
But link should only happen once!!*/
|
||||
if( dataSourceLinked_ ) {
|
||||
@@ -284,9 +284,9 @@ void ecmcScope::connectToDataSources() {
|
||||
scopeState_ = ECMC_SCOPE_STATE_WAIT_TRIGG;
|
||||
}
|
||||
|
||||
bool ecmcScope::sourceDataTypeSupported(ecmcEcDataType dt) {
|
||||
bool ecmcDAQChannel::sourceDataTypeSupported(ecmcEcDataType dt) {
|
||||
|
||||
SCOPE_DBG_PRINT("ecmcScope::sourceDataTypeSupported()");
|
||||
SCOPE_DBG_PRINT("ecmcDAQChannel::sourceDataTypeSupported()");
|
||||
|
||||
switch(dt) {
|
||||
case ECMC_EC_NONE:
|
||||
@@ -316,7 +316,7 @@ bool ecmcScope::sourceDataTypeSupported(ecmcEcDataType dt) {
|
||||
* If the trigger is newer than "NEXT_TIME" then the dc clocks must be out of sync (see readme)
|
||||
* The analog samples from the prev cycles is always buffered to be able to also handle older timestamps (up to 2*NELM back in time)
|
||||
*/
|
||||
void ecmcScope::execute() {
|
||||
void ecmcDAQChannel::execute() {
|
||||
|
||||
size_t bytesToCp = 0;
|
||||
|
||||
@@ -511,7 +511,7 @@ void ecmcScope::execute() {
|
||||
* sourceDataNexttimeItemInfo_ is always considered to happen in the future (after trigg)
|
||||
* If 32 bit registers then it can max be 2^32 ns between trigg and nexttime (approx 4s).
|
||||
*/
|
||||
int64_t ecmcScope::timeDiff() {
|
||||
int64_t ecmcDAQChannel::timeDiff() {
|
||||
// retrun time from trigg to next
|
||||
int64_t retVal = 0;
|
||||
if(sourceTriggItemInfo_->dataBitCount < 64 || sourceDataNexttimeItemInfo_->dataBitCount < 64) {
|
||||
@@ -544,7 +544,7 @@ int64_t ecmcScope::timeDiff() {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void ecmcScope::printEcDataArray(uint8_t* data,
|
||||
void ecmcDAQChannel::printEcDataArray(uint8_t* data,
|
||||
size_t size,
|
||||
ecmcEcDataType dt,
|
||||
int objId) {
|
||||
@@ -599,56 +599,56 @@ void ecmcScope::printEcDataArray(uint8_t* data,
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
uint8_t ecmcScope::getUint8(uint8_t* data) {
|
||||
uint8_t ecmcDAQChannel::getUint8(uint8_t* data) {
|
||||
return *data;
|
||||
}
|
||||
|
||||
int8_t ecmcScope::getInt8(uint8_t* data) {
|
||||
int8_t ecmcDAQChannel::getInt8(uint8_t* data) {
|
||||
int8_t* p=(int8_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
uint16_t ecmcScope::getUint16(uint8_t* data) {
|
||||
uint16_t ecmcDAQChannel::getUint16(uint8_t* data) {
|
||||
uint16_t* p=(uint16_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
int16_t ecmcScope::getInt16(uint8_t* data) {
|
||||
int16_t ecmcDAQChannel::getInt16(uint8_t* data) {
|
||||
int16_t* p=(int16_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
uint32_t ecmcScope::getUint32(uint8_t* data) {
|
||||
uint32_t ecmcDAQChannel::getUint32(uint8_t* data) {
|
||||
uint32_t* p=(uint32_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
int32_t ecmcScope::getInt32(uint8_t* data) {
|
||||
int32_t ecmcDAQChannel::getInt32(uint8_t* data) {
|
||||
int32_t* p=(int32_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
uint64_t ecmcScope::getUint64(uint8_t* data) {
|
||||
uint64_t ecmcDAQChannel::getUint64(uint8_t* data) {
|
||||
uint64_t* p=(uint64_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
int64_t ecmcScope::getInt64(uint8_t* data) {
|
||||
int64_t ecmcDAQChannel::getInt64(uint8_t* data) {
|
||||
int64_t* p=(int64_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
float ecmcScope::getFloat32(uint8_t* data) {
|
||||
float ecmcDAQChannel::getFloat32(uint8_t* data) {
|
||||
float* p=(float*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
double ecmcScope::getFloat64(uint8_t* data) {
|
||||
double ecmcDAQChannel::getFloat64(uint8_t* data) {
|
||||
double* p=(double*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
size_t ecmcScope::getEcDataTypeByteSize(ecmcEcDataType dt){
|
||||
size_t ecmcDAQChannel::getEcDataTypeByteSize(ecmcEcDataType dt){
|
||||
switch(dt) {
|
||||
case ECMC_EC_NONE:
|
||||
return 0;
|
||||
@@ -718,7 +718,7 @@ size_t ecmcScope::getEcDataTypeByteSize(ecmcEcDataType dt){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ecmcScope::initAsyn() {
|
||||
void ecmcDAQChannel::initAsyn() {
|
||||
|
||||
ecmcAsynPortDriver *ecmcAsynPort = (ecmcAsynPortDriver *)getEcmcAsynPortDriver();
|
||||
if(!ecmcAsynPort) {
|
||||
@@ -903,7 +903,7 @@ void ecmcScope::initAsyn() {
|
||||
|
||||
}
|
||||
|
||||
asynParamType ecmcScope::getResultAsynDTFromEcDT(ecmcEcDataType ecDT) {
|
||||
asynParamType ecmcDAQChannel::getResultAsynDTFromEcDT(ecmcEcDataType ecDT) {
|
||||
|
||||
/*typedef enum {
|
||||
asynParamNotDefined,
|
||||
@@ -973,13 +973,13 @@ asynParamType ecmcScope::getResultAsynDTFromEcDT(ecmcEcDataType ecDT) {
|
||||
}
|
||||
|
||||
// Avoid issues with std:to_string()
|
||||
std::string ecmcScope::to_string(int value) {
|
||||
std::string ecmcDAQChannel::to_string(int value) {
|
||||
std::ostringstream os;
|
||||
os << value;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void ecmcScope::setEnable(int enable) {
|
||||
void ecmcDAQChannel::setEnable(int enable) {
|
||||
if(enable) {
|
||||
SCOPE_DBG_PRINT("INFO: Scope enabled.\n");
|
||||
}
|
||||
@@ -991,11 +991,11 @@ void ecmcScope::setEnable(int enable) {
|
||||
enbaleParam_->refreshParam(1);
|
||||
}
|
||||
|
||||
void ecmcScope::triggScope() {
|
||||
void ecmcDAQChannel::triggScope() {
|
||||
triggOnce_ = 1;
|
||||
}
|
||||
|
||||
void ecmcScope::setWaitForNextTrigg() {
|
||||
void ecmcDAQChannel::setWaitForNextTrigg() {
|
||||
oldTriggTime_ = triggTime_;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcScope.h
|
||||
* ecmcDAQChannel.h
|
||||
*
|
||||
* Created on: Mar 22, 2020
|
||||
* Author: anderssandstrom
|
||||
@@ -15,18 +15,11 @@
|
||||
#include <stdexcept>
|
||||
#include "ecmcDataItem.h"
|
||||
#include "ecmcAsynPortDriver.h"
|
||||
#include "ecmcScopeDefs.h"
|
||||
#include "ecmcDAQDefs.h"
|
||||
#include "inttypes.h"
|
||||
#include <string>
|
||||
|
||||
typedef enum {
|
||||
ECMC_SCOPE_STATE_INVALID, /**Invalid. */
|
||||
ECMC_SCOPE_STATE_WAIT_TRIGG, /**Waiting for trigger. */
|
||||
ECMC_SCOPE_STATE_WAIT_NEXT, /**Waiting analog. (trigger newer than next ai time)*/
|
||||
ECMC_SCOPE_STATE_COLLECT, /**Filling buffer (waiting for data). */
|
||||
} ecmcScopeState;
|
||||
|
||||
class ecmcScope {
|
||||
class ecmcDAQChannel {
|
||||
public:
|
||||
|
||||
/** ecmc Scope class
|
||||
@@ -36,19 +29,11 @@ class ecmcScope {
|
||||
* - runtime_error
|
||||
* - out_of_range
|
||||
*/
|
||||
ecmcScope(int scopeIndex, // index of this object
|
||||
char* configStr);
|
||||
~ecmcScope();
|
||||
ecmcDAQChannel(int index, char* name);
|
||||
~ecmcDAQChannel();
|
||||
|
||||
// Add data to buffer (called from "external" callback)
|
||||
// void dataUpdatedCallback(uint8_t* data,
|
||||
// size_t size,
|
||||
// ecmcEcDataType dt);
|
||||
// Call just before realtime because then all data sources should be available
|
||||
void connectToDataSources();
|
||||
void setEnable(int enable);
|
||||
//void clearBuffers();
|
||||
void triggScope();
|
||||
void execute();
|
||||
|
||||
private:
|
||||
@@ -61,6 +46,7 @@ class ecmcScope {
|
||||
void setWaitForNextTrigg();
|
||||
|
||||
|
||||
|
||||
uint8_t* resultDataBuffer_;
|
||||
uint8_t* lastScanSourceDataBuffer_;
|
||||
size_t resultDataBufferBytes_;
|
||||
@@ -81,7 +67,7 @@ class ecmcScope {
|
||||
uint64_t oldTriggTime_;
|
||||
uint64_t sourceNexttime_;
|
||||
int64_t sourceSampleRateNS_; // nanoseconds
|
||||
ecmcScopeState scopeState_;
|
||||
ecmcDAQChannelState scopeState_;
|
||||
uint64_t ecmcSmapleTimeNS_;
|
||||
int64_t sourceElementsPerSample_;
|
||||
size_t elementsInResultBuffer_;
|
||||
290
src/src/ecmcDAQDataTypeBase.cpp
Normal file
290
src/src/ecmcDAQDataTypeBase.cpp
Normal file
@@ -0,0 +1,290 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2024 PSI
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcDAQDataTypeBase.cpp
|
||||
*
|
||||
* Created on: March 1, 2024
|
||||
* Author: anders sandstrom
|
||||
* Credits to https://github.com/sgreg/dynamic-loading
|
||||
*
|
||||
\*************************************************************************/
|
||||
|
||||
// Needed to get headers in ecmc right...
|
||||
#define ECMC_IS_PLUGIN
|
||||
|
||||
#include <sstream>
|
||||
#include "ecmcDAQDataTypeBase.h"
|
||||
#include "ecmcPluginClient.h"
|
||||
|
||||
ecmcDAQDataTypeBase::ecmcDAQDataTypeBase(int type, char* name){
|
||||
dataSourceLinked_ = 0;
|
||||
name_ = name;
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
ecmcDAQDataTypeBase::~ecmcDAQDataTypeBase() {
|
||||
}
|
||||
|
||||
bool ecmcDAQDataTypeBase::getDataSourcesLinked() {
|
||||
return dataSourceLinked_;
|
||||
}
|
||||
|
||||
char* ecmcDAQDataTypeBase::getName() {
|
||||
return name_.c_str();
|
||||
}
|
||||
|
||||
int ecmcDAQDataTypeBase::getType() {
|
||||
return type_;
|
||||
}
|
||||
|
||||
void ecmcDAQDataTypeBase::printEcDataArray(uint8_t* data,
|
||||
size_t size,
|
||||
ecmcEcDataType dt,
|
||||
int objId) {
|
||||
printf("INFO: Scope id: %d, data: ",objId);
|
||||
|
||||
size_t dataElementSize = getEcDataTypeByteSize(dt);
|
||||
|
||||
uint8_t *pData = data;
|
||||
for(unsigned int i = 0; i < size / dataElementSize; ++i) {
|
||||
if(i % 10 == 0) {
|
||||
printf("\n");
|
||||
} else {
|
||||
printf(", ");
|
||||
}
|
||||
switch(dt) {
|
||||
case ECMC_EC_U8:
|
||||
printf("%hhu",getUint8(pData));
|
||||
break;
|
||||
case ECMC_EC_S8:
|
||||
printf("%hhd",getInt8(pData));
|
||||
break;
|
||||
case ECMC_EC_U16:
|
||||
printf("%hu",getUint16(pData));
|
||||
break;
|
||||
case ECMC_EC_S16:
|
||||
printf("%hd",getInt16(pData));
|
||||
break;
|
||||
case ECMC_EC_U32:
|
||||
printf("%u",getUint32(pData));
|
||||
break;
|
||||
case ECMC_EC_S32:
|
||||
printf("%d",getInt32(pData));
|
||||
break;
|
||||
case ECMC_EC_U64:
|
||||
printf("%" PRIu64 "",getInt64(pData));
|
||||
break;
|
||||
case ECMC_EC_S64:
|
||||
printf("%" PRId64 "",getInt64(pData));
|
||||
break;
|
||||
case ECMC_EC_F32:
|
||||
printf("%f",getFloat32(pData));
|
||||
break;
|
||||
case ECMC_EC_F64:
|
||||
printf("%lf",getFloat64(pData));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
pData += dataElementSize;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
uint8_t ecmcDAQDataTypeBase::getUint8(uint8_t* data) {
|
||||
return *data;
|
||||
}
|
||||
|
||||
int8_t ecmcDAQDataTypeBase::getInt8(uint8_t* data) {
|
||||
int8_t* p=(int8_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
uint16_t ecmcDAQDataTypeBase::getUint16(uint8_t* data) {
|
||||
uint16_t* p=(uint16_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
int16_t ecmcDAQDataTypeBase::getInt16(uint8_t* data) {
|
||||
int16_t* p=(int16_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
uint32_t ecmcDAQDataTypeBase::getUint32(uint8_t* data) {
|
||||
uint32_t* p=(uint32_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
int32_t ecmcDAQDataTypeBase::getInt32(uint8_t* data) {
|
||||
int32_t* p=(int32_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
uint64_t ecmcDAQDataTypeBase::getUint64(uint8_t* data) {
|
||||
uint64_t* p=(uint64_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
int64_t ecmcDAQDataTypeBase::getInt64(uint8_t* data) {
|
||||
int64_t* p=(int64_t*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
float ecmcDAQDataTypeBase::getFloat32(uint8_t* data) {
|
||||
float* p=(float*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
double ecmcDAQDataTypeBase::getFloat64(uint8_t* data) {
|
||||
double* p=(double*)data;
|
||||
return *p;
|
||||
}
|
||||
|
||||
size_t ecmcDAQDataTypeBase::getEcDataTypeByteSize(ecmcEcDataType dt){
|
||||
switch(dt) {
|
||||
case ECMC_EC_NONE:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case ECMC_EC_B1:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case ECMC_EC_B2:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case ECMC_EC_B3:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case ECMC_EC_B4:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case ECMC_EC_U8:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case ECMC_EC_S8:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case ECMC_EC_U16:
|
||||
return 2;
|
||||
break;
|
||||
|
||||
case ECMC_EC_S16:
|
||||
return 2;
|
||||
break;
|
||||
|
||||
case ECMC_EC_U32:
|
||||
return 4;
|
||||
break;
|
||||
|
||||
case ECMC_EC_S32:
|
||||
return 4;
|
||||
break;
|
||||
|
||||
case ECMC_EC_U64:
|
||||
return 8;
|
||||
break;
|
||||
|
||||
case ECMC_EC_S64:
|
||||
return 8;
|
||||
break;
|
||||
|
||||
case ECMC_EC_F32:
|
||||
return 4;
|
||||
break;
|
||||
|
||||
case ECMC_EC_F64:
|
||||
return 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
asynParamType ecmcDAQDataTypeBase::getResultAsynDTFromEcDT(ecmcEcDataType ecDT) {
|
||||
|
||||
/*typedef enum {
|
||||
asynParamNotDefined,
|
||||
asynParamInt32,
|
||||
asynParamUInt32Digital,
|
||||
asynParamFloat64,
|
||||
asynParamOctet,
|
||||
asynParamInt8Array,
|
||||
asynParamInt16Array,
|
||||
asynParamInt32Array,
|
||||
asynParamFloat32Array,
|
||||
asynParamFloat64Array,
|
||||
asynParamGenericPointer
|
||||
} asynParamType;*/
|
||||
|
||||
switch(ecDT) {
|
||||
case ECMC_EC_NONE:
|
||||
return asynParamNotDefined;
|
||||
break;
|
||||
case ECMC_EC_B1 :
|
||||
return asynParamNotDefined;
|
||||
break;
|
||||
case ECMC_EC_B2 :
|
||||
return asynParamNotDefined;
|
||||
break;
|
||||
case ECMC_EC_B3 :
|
||||
return asynParamNotDefined;
|
||||
break;
|
||||
case ECMC_EC_B4 :
|
||||
return asynParamNotDefined;
|
||||
break;
|
||||
case ECMC_EC_U8 :
|
||||
return asynParamInt8Array;
|
||||
break;
|
||||
case ECMC_EC_S8 :
|
||||
return asynParamInt8Array;
|
||||
break;
|
||||
case ECMC_EC_U16:
|
||||
return asynParamInt16Array;
|
||||
break;
|
||||
case ECMC_EC_S16:
|
||||
return asynParamInt16Array;
|
||||
break;
|
||||
case ECMC_EC_U32:
|
||||
return asynParamInt32Array;
|
||||
break;
|
||||
case ECMC_EC_S32:
|
||||
return asynParamInt32Array;
|
||||
break;
|
||||
case ECMC_EC_U64:
|
||||
return asynParamNotDefined;
|
||||
break;
|
||||
case ECMC_EC_S64:
|
||||
return asynParamNotDefined;
|
||||
break;
|
||||
case ECMC_EC_F32:
|
||||
return asynParamFloat32Array;
|
||||
break;
|
||||
case ECMC_EC_F64:
|
||||
return asynParamFloat64Array;
|
||||
break;
|
||||
default:
|
||||
return asynParamNotDefined;
|
||||
break;
|
||||
}
|
||||
return asynParamNotDefined;
|
||||
}
|
||||
|
||||
// Avoid issues with std:to_string()
|
||||
std::string ecmcDAQDataTypeBase::to_string(int value) {
|
||||
std::ostringstream os;
|
||||
os << value;
|
||||
return os.str();
|
||||
}
|
||||
57
src/src/ecmcDAQDataTypeBase.h
Normal file
57
src/src/ecmcDAQDataTypeBase.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2024 PSI
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcDAQDataTypeBase.h
|
||||
*
|
||||
* Created on: Mar 01, 2024
|
||||
* Author: anders sandstrom
|
||||
*
|
||||
\*************************************************************************/
|
||||
#ifndef ECMC_DAQ_DATATYPE_BASE_H_
|
||||
#define ECMC_DAQ_DATATYPE_BASE_H_
|
||||
|
||||
#include <stdexcept>
|
||||
#include "ecmcDataItem.h"
|
||||
#include <string>
|
||||
|
||||
class ecmcDAQDataTypeBase {
|
||||
public:
|
||||
|
||||
ecmcDAQDataTypeBase(int type, char* name);
|
||||
~ecmcDAQDataTypeBase();
|
||||
|
||||
virtual void connectToDataSources() = 0;
|
||||
virtual void execute() = 0;
|
||||
virtual size_t getDataElementCount() = 0;
|
||||
virtual double* getDataPtr() = 0;
|
||||
bool getDataSourcesLinked();
|
||||
char* getName();
|
||||
int getType();
|
||||
|
||||
protected:
|
||||
bool dataSourceLinked_;
|
||||
std::string name_;
|
||||
int type_;
|
||||
|
||||
// Some generic utility functions
|
||||
static uint8_t getUint8(uint8_t* data);
|
||||
static int8_t getInt8(uint8_t* data);
|
||||
static uint16_t getUint16(uint8_t* data);
|
||||
static int16_t getInt16(uint8_t* data);
|
||||
static uint32_t getUint32(uint8_t* data);
|
||||
static int32_t getInt32(uint8_t* data);
|
||||
static uint64_t getUint64(uint8_t* data);
|
||||
static int64_t getInt64(uint8_t* data);
|
||||
static float getFloat32(uint8_t* data);
|
||||
static double getFloat64(uint8_t* data);
|
||||
static size_t getEcDataTypeByteSize(ecmcEcDataType dt);
|
||||
static void printEcDataArray(uint8_t* data,
|
||||
size_t size,
|
||||
ecmcEcDataType dt,
|
||||
int objId);
|
||||
static std::string to_string(int value);
|
||||
};
|
||||
|
||||
#endif /* ECMC_DAQ_DATATYPE_BASE_H_ */
|
||||
116
src/src/ecmcDAQDataTypeGeneric.cpp
Normal file
116
src/src/ecmcDAQDataTypeGeneric.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2024 PSI
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcDAQDataTypeGeneric.cpp
|
||||
*
|
||||
* Created on: March 1, 2024
|
||||
* Author: anders sandstrom
|
||||
* Credits to https://github.com/sgreg/dynamic-loading
|
||||
*
|
||||
\*************************************************************************/
|
||||
|
||||
// Needed to get headers in ecmc right...
|
||||
#define ECMC_IS_PLUGIN
|
||||
|
||||
#include <sstream>
|
||||
#include "ecmcDAQDataTypeGeneric.h"
|
||||
#include "ecmcPluginClient.h"
|
||||
|
||||
ecmcDAQDataTypeGeneric::ecmcDAQDataTypeGeneric(char *ecTimeRising,char *ecTimeFalling){
|
||||
|
||||
sEcTimeRising_ = ecTimeRising;
|
||||
sEcTimeFalling_ = ecTimeFalling;
|
||||
dataItemTimeRising_ = NULL;
|
||||
dataItemInfoTimeRising_ = NULL;
|
||||
dataItemTimeFalling_ = NULL;
|
||||
dataItemInfoTimeFalling_ = NULL;
|
||||
for(int i=0; i< ECMC_DAQ_DATA_TYPE_1_DATA_ELEMENTS, ++i) {
|
||||
buffer_[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
ecmcDAQDataTypeGeneric::~ecmcDAQDataTypeGeneric() {
|
||||
delete(dataItemTimeRising_);
|
||||
delete(dataItemInfoTimeRising_);
|
||||
delete(dataItemTimeFalling_);
|
||||
delete(dataItemInfoTimeFalling_);
|
||||
}
|
||||
|
||||
void ecmcDAQDataTypeGeneric::connectToDataSources() {
|
||||
if( dataSourceLinked_ ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get data item for
|
||||
dataItemTimeRising_ = (ecmcDataItem*) getEcmcDataItem(sEcTimeRising_.c_str());
|
||||
|
||||
if(!dataItemTimeRising_) {
|
||||
throw std::runtime_error( "ERROR: Dataitem for time rinsing edge NULL." );
|
||||
}
|
||||
dataItemInfoTimeRising_ = dataItemTimeRising_->getDataItemInfo();
|
||||
|
||||
if(!dataItemInfoTimeRising_) {
|
||||
throw std::runtime_error( "ERROR: Dataiteminfo for time rising edge NULL." );
|
||||
}
|
||||
|
||||
// Get source nexttime dataItem
|
||||
sourceDataNexttimeItem_ = (ecmcDataItem*) getEcmcDataItem(cfgDataNexttimeStr_);
|
||||
if(!sourceDataNexttimeItem_) {
|
||||
SCOPE_DBG_PRINT("ERROR: Source nexttime dataitem NULL.\n");
|
||||
throw std::runtime_error( "ERROR: Source nexttime dataitem NULL." );
|
||||
}
|
||||
sourceDataNexttimeItemInfo_ = sourceDataNexttimeItem_->getDataItemInfo();
|
||||
|
||||
if(!sourceDataNexttimeItemInfo_) {
|
||||
SCOPE_DBG_PRINT("ERROR: Source nexttime dataitem info NULL.\n");
|
||||
throw std::runtime_error( "ERROR: Source nexttime dataitem info NULL." );
|
||||
}
|
||||
|
||||
// Get trigg dataItem
|
||||
sourceTriggItem_ = (ecmcDataItem*) getEcmcDataItem(cfgTriggStr_);
|
||||
if(!sourceTriggItem_) {
|
||||
SCOPE_DBG_PRINT("ERROR: Trigg dataitem NULL.\n");
|
||||
throw std::runtime_error( "ERROR: Trigg dataitem NULL." );
|
||||
}
|
||||
|
||||
sourceTriggItemInfo_ = sourceTriggItem_->getDataItemInfo();
|
||||
if(!sourceTriggItemInfo_) {
|
||||
SCOPE_DBG_PRINT("ERROR: Trigg dataitem info NULL.\n");
|
||||
throw std::runtime_error( "ERROR: Trigg dataitem info NULL." );
|
||||
}
|
||||
|
||||
if( sourceTriggItem_->read((uint8_t*)(&oldTriggTime_),sourceTriggItemInfo_->dataElementSize)){
|
||||
SCOPE_DBG_PRINT("ERROR: Failed read trigg time.\n");
|
||||
throw std::runtime_error( "ERROR: Failed read trigg time." );
|
||||
}
|
||||
|
||||
if(!sourceDataTypeSupported(sourceDataItem_->getEcmcDataType())) {
|
||||
SCOPE_DBG_PRINT("ERROR: Source data type not suppported.\n");
|
||||
throw std::runtime_error( "ERROR: Source data type not suppported.");
|
||||
}
|
||||
|
||||
// Register asyn parameters
|
||||
initAsyn();
|
||||
|
||||
dataSourceLinked_ = 1;
|
||||
scopeState_ = ECMC_SCOPE_STATE_WAIT_TRIGG;
|
||||
|
||||
}
|
||||
|
||||
void ecmcDAQDataTypeGeneric::execute() {
|
||||
|
||||
}
|
||||
|
||||
size_t ecmcDAQDataTypeGeneric::getDataElementCount() {
|
||||
return ECMC_DAQ_DATA_TYPE_1_DATA_ELEMENTS;
|
||||
}
|
||||
|
||||
double* ecmcDAQDataTypeGeneric::getDataPtr() {
|
||||
return &buffer[0];
|
||||
}
|
||||
|
||||
double ecmcDAQDataTypeGeneric::getType() {
|
||||
return ECMC_DAQ_DATA_TYPE_1_ID;
|
||||
}
|
||||
47
src/src/ecmcDAQDataTypeGeneric.h
Normal file
47
src/src/ecmcDAQDataTypeGeneric.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2024 PSI
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcDAQDataTypeGeneric.h
|
||||
*
|
||||
* Created on: Mar 01, 2024
|
||||
* Author: anders sandstrom
|
||||
*
|
||||
\*************************************************************************/
|
||||
#ifndef ECMC_DAQ_DATATYPE_1_H_
|
||||
#define ECMC_DAQ_DATATYPE_1_H_
|
||||
|
||||
#include <stdexcept>
|
||||
#include "ecmcDataItem.h"
|
||||
#include <string>
|
||||
#include "ecmcDAQDataTypeBase.h"
|
||||
#include "ecmcDataItem.h"
|
||||
#include <vector>
|
||||
|
||||
#define ECMC_DAQ_DATA_TYPE_1_DATA_ELEMENTS 2
|
||||
class ecmcDAQDataTypeGeneric : public ecmcDAQDataTypeBase {
|
||||
public:
|
||||
|
||||
ecmcDAQDataTypeGeneric();
|
||||
~ecmcDAQDataTypeGeneric();
|
||||
void connectToDataSources();
|
||||
void execute();
|
||||
size_t getDataElementCount();
|
||||
double* getDataPtr();
|
||||
double getType();
|
||||
void addEcData(char* ec)
|
||||
|
||||
private:
|
||||
std::string sEcTimeRising_;
|
||||
std::string sEcTimeFalling_;
|
||||
|
||||
double *buffer_;
|
||||
ecmcEc *ecMaster_;
|
||||
static std::vector<ecmcEcEntry*> entries;
|
||||
};
|
||||
|
||||
#endif /* ECMC_DAQ_DATATYPE_1_H_ */
|
||||
|
||||
|
||||
|
||||
184
src/src/ecmcDAQWrap.cpp
Normal file
184
src/src/ecmcDAQWrap.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2019 European Spallation Source ERIC
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcDAQWrap.cpp
|
||||
*
|
||||
* Created on: Sept 21, 2020
|
||||
* Author: anderssandstrom
|
||||
* Credits to https://github.com/sgreg/dynamic-loading
|
||||
*
|
||||
\*************************************************************************/
|
||||
|
||||
// Needed to get headers in ecmc right...
|
||||
#define ECMC_IS_PLUGIN
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include "ecmcDAQWrap.h"
|
||||
#include "ecmcDAQChannel.h"
|
||||
#include "ecmcDAQDefs.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
#define ECMC_PLUGIN_PORTNAME_PREFIX "PLUGIN.DAQ"
|
||||
#define ECMC_PLUGIN_DAQ_ERROR_CODE 1
|
||||
|
||||
static std::vector<ecmcDAQChannel*> channels;
|
||||
static int channelCounter = 0;
|
||||
|
||||
int createDAQ(char* name) {
|
||||
|
||||
// create new ecmcFFT object
|
||||
ecmcDAQChannel* channel = NULL;
|
||||
|
||||
try {
|
||||
channel = new ecmcDAQChannel(name);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
if(scope) {
|
||||
delete channel;
|
||||
}
|
||||
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||
return ECMC_PLUGIN_DAQ_ERROR_CODE;
|
||||
}
|
||||
|
||||
scopes.push_back(scope);
|
||||
channelCounter++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void deleteAllDAQs() {
|
||||
for(std::vector<ecmcDAQChannel*>::iterator pDAQChannel = scopes.begin(); pDAQChannel != scopes.end(); ++pDAQChannel) {
|
||||
if(*pDAQChannel) {
|
||||
delete (*pDAQChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int linkDataToDAQs() {
|
||||
for(std::vector<ecmcDAQChannel*>::iterator pDAQChannel = scopes.begin(); pDAQChannel != scopes.end(); ++pDAQChannel) {
|
||||
if(*pDAQChannel) {
|
||||
try {
|
||||
(*pDAQChannel)->connectToDataSources();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||
return ECMC_PLUGIN_DAQ_ERROR_CODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enableDAQ(int scopeIndex, int enable) {
|
||||
try {
|
||||
scopes.at(scopeIndex)->setEnable(enable);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. DAQ index out of range.\n",e.what());
|
||||
return ECMC_PLUGIN_DAQ_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int executeDAQCs() {
|
||||
try {
|
||||
for(std::vector<ecmcDAQChannel*>::iterator pDAQChannel = scopes.begin(); pDAQChannel != scopes.end(); ++pDAQChannel) {
|
||||
if(*pDAQChannel) {
|
||||
(*pDAQChannel)->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s.\n",e.what());
|
||||
return ECMC_PLUGIN_DAQ_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* EPICS iocsh shell command: ecmcAddDataType1ToChannel
|
||||
*/
|
||||
void ecmcAddDataType1ToChannelPrintHelp() {
|
||||
printf("\n");
|
||||
printf(" Use ecmcAddDataType1ToChannel(<ch_name>, <axis_index>)\n");
|
||||
printf(" <ch_name> : Name of channel to add data to.\n");
|
||||
printf(" <Axis id> : Axis index to add.\n");
|
||||
printf(" <velo limit> : Axis standstill velo limit [unit of axis].\n");
|
||||
printf(" <time> : Time for axis to be below velo limit [ms].\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int ecmcAddAxisToSafetyGroup(const char* name, int axis_id, double velo_lim, int stand_still_time) {
|
||||
if(!name) {
|
||||
ecmcAddAxisToSafetyGroupPrintHelp();
|
||||
return asynError;
|
||||
}
|
||||
|
||||
if(strcmp(name,"-h") == 0 || strcmp(name,"--help") == 0 ) {
|
||||
ecmcAddAxisToSafetyGroupPrintHelp();
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
if(axis_id <= 0) {
|
||||
printf("Error: Invalid axis id.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(velo_lim < 0) {
|
||||
printf("Error: Invalid velocity limit.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(stand_still_time < 0) {
|
||||
printf("Error: Invalid stand still filter time.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
try {
|
||||
return addAxisToSafetyGroup(name,axis_id, velo_lim, stand_still_time);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Add axis to safety group failed.\n",e.what());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
static const iocshArg initArg0_2 =
|
||||
{ "Group name", iocshArgString };
|
||||
static const iocshArg initArg1_2 =
|
||||
{ "Axis id []", iocshArgInt };
|
||||
static const iocshArg initArg2_2 =
|
||||
{ "Velo limit [unit same as axis cfg]", iocshArgDouble };
|
||||
static const iocshArg initArg3_2 =
|
||||
{ "Velo stand still filter time [ms]", iocshArgInt };
|
||||
|
||||
static const iocshArg *const initArgs_2[] = { &initArg0_2,
|
||||
&initArg1_2,
|
||||
&initArg2_2,
|
||||
&initArg3_2};
|
||||
|
||||
static const iocshFuncDef initFuncDef_2 = { "ecmcAddAxisToSafetyGroup", 4, initArgs_2};
|
||||
static void initCallFunc_2(const iocshArgBuf *args) {
|
||||
ecmcAddAxisToSafetyGroup(args[0].sval, args[1].ival, args[2].dval, args[3].ival);
|
||||
}
|
||||
|
||||
void ecmcSafetyPlgRegister(void) {
|
||||
iocshRegister(&initFuncDef_1, initCallFunc_1);
|
||||
iocshRegister(&initFuncDef_2, initCallFunc_2);
|
||||
}
|
||||
|
||||
epicsExportRegistrar(ecmcSafetyPlgRegister);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcPluginScope.cpp
|
||||
* ecmcPluginDAQ.cpp
|
||||
*
|
||||
* Created on: Sept 21, 2020
|
||||
* Author: anderssandstrom
|
||||
@@ -23,8 +23,8 @@ extern "C" {
|
||||
#include <string.h>
|
||||
|
||||
#include "ecmcPluginDefs.h"
|
||||
#include "ecmcScopeDefs.h"
|
||||
#include "ecmcScopeWrap.h"
|
||||
#include "ecmcDAQDefs.h"
|
||||
#include "ecmcDAQWrap.h"
|
||||
|
||||
static int lastEcmcError = 0;
|
||||
static char* lastConfStr = NULL;
|
||||
@@ -34,21 +34,21 @@ static char* lastConfStr = NULL;
|
||||
* Return value other than 0 will be considered error.
|
||||
* configStr can be used for configuration parameters.
|
||||
**/
|
||||
int scopeConstruct(char *configStr)
|
||||
int daqConstruct(char *configStr)
|
||||
{
|
||||
//This module is allowed to load several times so no need to check if loaded
|
||||
|
||||
// create FFT object and register data callback
|
||||
lastConfStr = strdup(configStr);
|
||||
return createScope(configStr);
|
||||
return 0; //createDAQ(configStr);
|
||||
}
|
||||
|
||||
/** Optional function.
|
||||
* Will be called once at unload.
|
||||
**/
|
||||
void scopeDestruct(void)
|
||||
void daqDestruct(void)
|
||||
{
|
||||
deleteAllScopes();
|
||||
deleteAllDAQs();
|
||||
if(lastConfStr){
|
||||
free(lastConfStr);
|
||||
}
|
||||
@@ -60,40 +60,40 @@ void scopeDestruct(void)
|
||||
* this plugin to react on ecmc errors
|
||||
* Return value other than 0 will be considered to be an error code in ecmc.
|
||||
**/
|
||||
int scopeRealtime(int ecmcError)
|
||||
int daqRealtime(int ecmcError)
|
||||
{
|
||||
lastEcmcError = ecmcError;
|
||||
return executeScopes();
|
||||
return executeDAQs();
|
||||
}
|
||||
|
||||
/** Link to data source here since all sources should be availabe at this stage
|
||||
* (for example ecmc PLC variables are defined only at enter of realtime)
|
||||
**/
|
||||
int scopeEnterRT(){
|
||||
return linkDataToScopes();
|
||||
int daqEnterRT(){
|
||||
return linkDataToDAQs();
|
||||
}
|
||||
|
||||
/** Optional function.
|
||||
* Will be called once just before leaving realtime mode
|
||||
* Return value other than 0 will be considered error.
|
||||
**/
|
||||
int scopeExitRT(void){
|
||||
int daqExitRT(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// // Plc function for clear of buffers
|
||||
// double scope_clear(double index) {
|
||||
// return (double)clearScope((int)index);
|
||||
// double daq_clear(double index) {
|
||||
// return (double)clearDAQ((int)index);
|
||||
// }
|
||||
|
||||
// Plc function for enable
|
||||
double scope_enable(double index, double enable) {
|
||||
return (double)enableScope((int)index, (int)enable);
|
||||
double daq_enable(double index, double enable) {
|
||||
return (double)enableDAQ((int)index, (int)enable);
|
||||
}
|
||||
|
||||
// // Plc function for trigg new measurement (will clear buffers)
|
||||
// double scope_trigg(double index) {
|
||||
// return (double)triggScope((int)index);
|
||||
// double daq_trigg(double index) {
|
||||
// return (double)triggDAQ((int)index);
|
||||
// }
|
||||
|
||||
// Register data for plugin so ecmc know what to use
|
||||
@@ -101,9 +101,9 @@ struct ecmcPluginData pluginDataDef = {
|
||||
// Allways use ECMC_PLUG_VERSION_MAGIC
|
||||
.ifVersion = ECMC_PLUG_VERSION_MAGIC,
|
||||
// Name
|
||||
.name = "ecmcPlugin_Scope",
|
||||
.name = "ecmcPlugin_DAQ",
|
||||
// Description
|
||||
.desc = "Scope plugin for use with ecmc.",
|
||||
.desc = "DAQ 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> : Ec source variable (example: ec0.s1.mm.CH1_ARRAY).\n"
|
||||
@@ -115,29 +115,29 @@ struct ecmcPluginData pluginDataDef = {
|
||||
// Plugin version
|
||||
.version = ECMC_EXAMPLE_PLUGIN_VERSION,
|
||||
// Optional construct func, called once at load. NULL if not definded.
|
||||
.constructFnc = scopeConstruct,
|
||||
.constructFnc = daqConstruct,
|
||||
// Optional destruct func, called once at unload. NULL if not definded.
|
||||
.destructFnc = scopeDestruct,
|
||||
.destructFnc = daqDestruct,
|
||||
// Optional func that will be called each rt cycle. NULL if not definded.
|
||||
.realtimeFnc = scopeRealtime,
|
||||
.realtimeFnc = daqRealtime,
|
||||
// Optional func that will be called once just before enter realtime mode
|
||||
.realtimeEnterFnc = scopeEnterRT,
|
||||
.realtimeEnterFnc = daqEnterRT,
|
||||
// Optional func that will be called once just before exit realtime mode
|
||||
.realtimeExitFnc = scopeExitRT,
|
||||
.realtimeExitFnc = daqExitRT,
|
||||
// PLC funcs
|
||||
.funcs[0] =
|
||||
{ /*----fft_clear----*/
|
||||
// Function name (this is the name you use in ecmc plc-code)
|
||||
.funcName = "scope_enable",
|
||||
.funcName = "daq_enable",
|
||||
// Function description
|
||||
.funcDesc = "scope_enable(index,enable) : Enable/disaable scope[index].",
|
||||
.funcDesc = "daq_enable(index,enable) : Enable/disaable daq[index].",
|
||||
/**
|
||||
* 12 different prototypes allowed (only doubles since reg in plc).
|
||||
* Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||
**/
|
||||
.funcArg0 = NULL,
|
||||
.funcArg1 = NULL,
|
||||
.funcArg2 = scope_enable,
|
||||
.funcArg2 = daq_enable,
|
||||
.funcArg3 = NULL,
|
||||
.funcArg4 = NULL,
|
||||
.funcArg5 = NULL,
|
||||
@@ -1,121 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2019 European Spallation Source ERIC
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcScopeWrap.cpp
|
||||
*
|
||||
* Created on: Sept 21, 2020
|
||||
* Author: anderssandstrom
|
||||
* Credits to https://github.com/sgreg/dynamic-loading
|
||||
*
|
||||
\*************************************************************************/
|
||||
|
||||
// Needed to get headers in ecmc right...
|
||||
#define ECMC_IS_PLUGIN
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include "ecmcScopeWrap.h"
|
||||
#include "ecmcScope.h"
|
||||
#include "ecmcScopeDefs.h"
|
||||
|
||||
#define ECMC_PLUGIN_PORTNAME_PREFIX "PLUGIN.SCOPE"
|
||||
#define ECMC_PLUGIN_SCOPE_ERROR_CODE 1
|
||||
|
||||
static std::vector<ecmcScope*> scopes;
|
||||
static int scopeObjCounter = 0;
|
||||
|
||||
int createScope(char* configStr) {
|
||||
|
||||
// create new ecmcFFT object
|
||||
ecmcScope* scope = NULL;
|
||||
|
||||
try {
|
||||
scope = new ecmcScope(scopeObjCounter, configStr);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
if(scope) {
|
||||
delete scope;
|
||||
}
|
||||
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
|
||||
scopes.push_back(scope);
|
||||
scopeObjCounter++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void deleteAllScopes() {
|
||||
for(std::vector<ecmcScope*>::iterator pscope = scopes.begin(); pscope != scopes.end(); ++pscope) {
|
||||
if(*pscope) {
|
||||
delete (*pscope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int linkDataToScopes() {
|
||||
for(std::vector<ecmcScope*>::iterator pscope = scopes.begin(); pscope != scopes.end(); ++pscope) {
|
||||
if(*pscope) {
|
||||
try {
|
||||
(*pscope)->connectToDataSources();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enableScope(int scopeIndex, int enable) {
|
||||
try {
|
||||
scopes.at(scopeIndex)->setEnable(enable);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Scope index out of range.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// int clearScope(int scopeIndex) {
|
||||
// try {
|
||||
// scopes.at(scopeIndex)->clearBuffers();
|
||||
// }
|
||||
// catch(std::exception& e) {
|
||||
// printf("Exception: %s. Scope index out of range.\n",e.what());
|
||||
// return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
int triggScope(int scopeIndex) {
|
||||
try {
|
||||
scopes.at(scopeIndex)->triggScope();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Scope index out of range.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int executeScopes() {
|
||||
try {
|
||||
for(std::vector<ecmcScope*>::iterator pscope = scopes.begin(); pscope != scopes.end(); ++pscope) {
|
||||
if(*pscope) {
|
||||
(*pscope)->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user