diff --git a/src/src/ecmcScope.cpp b/src/src/ecmcDAQChannel.cpp similarity index 95% rename from src/src/ecmcScope.cpp rename to src/src/ecmcDAQChannel.cpp index fd1cefc..a20bc29 100644 --- a/src/src/ecmcScope.cpp +++ b/src/src/ecmcDAQChannel.cpp @@ -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 -#include "ecmcScope.h" +#include "ecmcDAQChannel.h" #include "ecmcPluginClient.h" #include @@ -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_; } diff --git a/src/src/ecmcScope.h b/src/src/ecmcDAQChannel.h similarity index 81% rename from src/src/ecmcScope.h rename to src/src/ecmcDAQChannel.h index 2cd1ee0..5fb0e39 100644 --- a/src/src/ecmcScope.h +++ b/src/src/ecmcDAQChannel.h @@ -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 #include "ecmcDataItem.h" #include "ecmcAsynPortDriver.h" -#include "ecmcScopeDefs.h" +#include "ecmcDAQDefs.h" #include "inttypes.h" #include -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_; diff --git a/src/src/ecmcDAQDataTypeBase.cpp b/src/src/ecmcDAQDataTypeBase.cpp new file mode 100644 index 0000000..bf76287 --- /dev/null +++ b/src/src/ecmcDAQDataTypeBase.cpp @@ -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 +#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(); +} diff --git a/src/src/ecmcDAQDataTypeBase.h b/src/src/ecmcDAQDataTypeBase.h new file mode 100644 index 0000000..a48ca10 --- /dev/null +++ b/src/src/ecmcDAQDataTypeBase.h @@ -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 +#include "ecmcDataItem.h" +#include + +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_ */ diff --git a/src/src/ecmcDAQDataTypeGeneric.cpp b/src/src/ecmcDAQDataTypeGeneric.cpp new file mode 100644 index 0000000..b0a15bc --- /dev/null +++ b/src/src/ecmcDAQDataTypeGeneric.cpp @@ -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 +#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; +} diff --git a/src/src/ecmcDAQDataTypeGeneric.h b/src/src/ecmcDAQDataTypeGeneric.h new file mode 100644 index 0000000..eeef7f5 --- /dev/null +++ b/src/src/ecmcDAQDataTypeGeneric.h @@ -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 +#include "ecmcDataItem.h" +#include +#include "ecmcDAQDataTypeBase.h" +#include "ecmcDataItem.h" +#include + +#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 entries; +}; + +#endif /* ECMC_DAQ_DATATYPE_1_H_ */ + + + \ No newline at end of file diff --git a/src/src/ecmcScopeDefs.h b/src/src/ecmcDAQDefs.h similarity index 100% rename from src/src/ecmcScopeDefs.h rename to src/src/ecmcDAQDefs.h diff --git a/src/src/ecmcDAQWrap.cpp b/src/src/ecmcDAQWrap.cpp new file mode 100644 index 0000000..2106b95 --- /dev/null +++ b/src/src/ecmcDAQWrap.cpp @@ -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 +#include +#include +#include "ecmcDAQWrap.h" +#include "ecmcDAQChannel.h" +#include "ecmcDAQDefs.h" +#include + +#define ECMC_PLUGIN_PORTNAME_PREFIX "PLUGIN.DAQ" +#define ECMC_PLUGIN_DAQ_ERROR_CODE 1 + +static std::vector 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::iterator pDAQChannel = scopes.begin(); pDAQChannel != scopes.end(); ++pDAQChannel) { + if(*pDAQChannel) { + delete (*pDAQChannel); + } + } +} + +int linkDataToDAQs() { + for(std::vector::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::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(, )\n"); + printf(" : Name of channel to add data to.\n"); + printf(" : Axis index to add.\n"); + printf(" : Axis standstill velo limit [unit of axis].\n"); + printf("