diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.cpp b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.cpp index 9712c58..62108e5 100644 --- a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.cpp +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.cpp @@ -14,62 +14,22 @@ // Needed to get headers in ecmc right... #define ECMC_IS_PLUGIN -// Error Codes -#define ECMC_ERROR_ASYNPORT_NULL 1 -#define ECMC_ERROR_ASYN_PARAM_FAIL 2 - #include "ecmcFFT.h" -#include "ecmcPluginClient.h" -#include "ecmcAsynPortDriver.h" -// Vars -static int counter = 0; -static ecmcAsynDataItem *paramCount = NULL; - -// Use ecmcPluginClient.h interface -double getSampleRate() { - - return getEcmcSampleRate(); +// data callback +void dataUpdatedCallback(uint8_t* data, size_t size, ecmcEcDataType dt, void* obj) { + printf("Data updates\n"); } -// Use ecmcPluginClient.h interface -void* getAsynPort() { - return getEcmcAsynPortDriver(); +ecmcFFT::ecmcFFT(ecmcDataItem* dataItem, ecmcAsynPortDriver* asynPort) { + dataItem_ = dataItem; + asynPort_ = asynPort; } -// register a dummy asyn parameter "plugin.adv.counter" -int initAsyn() { - - ecmcAsynPortDriver *ecmcAsynPort = (ecmcAsynPortDriver *)getEcmcAsynPortDriver(); - if(!ecmcAsynPort) { - printf("Error: ecmcPlugin_FFT: ecmcAsynPortDriver NULL."); - return ECMC_ERROR_ASYNPORT_NULL; - } +ecmcFFT::~ecmcFFT() { - // Add a dummy counter that incraeses one for each rt cycle - paramCount = ecmcAsynPort->addNewAvailParam( - "plugin.adv.counter", // name - asynParamInt32, // asyn type - (uint8_t *)&(counter),// pointer to data - sizeof(counter), // size of data - ECMC_EC_S32, // ecmc data type - 0); // die if fail - if(!paramCount) { - printf("Error: ecmcPlugin_FFT: Failed to create asyn param \"plugin.adv.counter\"."); - return ECMC_ERROR_ASYN_PARAM_FAIL; - } - paramCount->addSupportedAsynType(asynParamInt32); // Only allw records of this type - paramCount->setAllowWriteToEcmc(false); // read only - paramCount->refreshParam(1); // read once into asyn param lib - ecmcAsynPort->callParamCallbacks(ECMC_ASYN_DEFAULT_LIST, ECMC_ASYN_DEFAULT_ADDR); - return 0; } -// increase value of counter and refresh asyn param -void increaseCounter(){ - counter++; - if(paramCount){ - paramCount->refreshParamRT(0); - // "callParamCallbacks" are handled in ecmc rt thread so don't call - } +int ecmcFFT::ConnectToDataSource() { + return dataItem_->regDataUpdatedCallback(dataUpdatedCallback, this); } diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.h b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.h index c5b54bd..13e6e87 100644 --- a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.h +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.h @@ -12,21 +12,20 @@ #ifndef ECMC_FFT_H_ #define ECMC_FFT_H_ -#ifdef __cplusplus -extern "C" { -#endif // ifdef __cplusplus +#include "ecmcDataItem.h" +#include "ecmcAsynPortDriver.h" -// get ecmc rt sample rate from ecmcPluginClient.h funcs -double getSampleRate(); -// get ecmcAsynPort from ecmcPluginClient.h funcs -void* getAsynPort(); -// register a dummy asyn parameter "plugin.adv.counter" -int initAsyn(); -// increase value of counter and refresh asyn param -void increaseCounter(); +class ecmcFFT { + public: + ecmcFFT(ecmcDataItem *dataItem, ecmcAsynPortDriver* asynPort); + ~ecmcFFT(); -#ifdef __cplusplus -} -#endif // ifdef __cplusplus + //Register callback + int ConnectToDataSource(); + + private: + ecmcDataItem *dataItem_; + ecmcAsynPortDriver *asynPort_; +}; #endif /* ECMC_FFT_H_ */ diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.cpp b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.cpp new file mode 100644 index 0000000..e9d2b85 --- /dev/null +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.cpp @@ -0,0 +1,56 @@ +/*************************************************************************\ +* 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. +* +* ecmcFFTWrap.cpp +* +* Created on: Mar 22, 2020 +* Author: anderssandstrom +* Credits to https://github.com/sgreg/dynamic-loading +* +\*************************************************************************/ + +// Needed to get headers in ecmc right... +#define ECMC_IS_PLUGIN + +#include "ecmcFFTWrap.h" +#include "ecmcFFT.h" +#include "ecmcAsynPortDriver.h" +#include "ecmcPluginClient.h" + +static ecmcFFT* fft = NULL; +static ecmcDataItem* dataItem = NULL; +static ecmcAsynPortDriver* ecmcAsynPort = NULL; +static int dbgModeOption = 0; + +int createFFT(char* source, int dbgMode) { + dbgModeOption = dbgMode; + // Get ecmcDataItem for source + dataItem = (ecmcDataItem*)getEcmcDataItem(source); + if(!dataItem) { + PRINT_IF_DBG_MODE("%s/%s:%d: Error: dataItem=NULL (source %s not found) (0x%x).\n", + __FILE__, __FUNCTION__, __LINE__, source, + ECMC_PLUGIN_ERROR_DATA_SOURCE_NULL); + return ECMC_PLUGIN_ERROR_DATA_SOURCE_NULL; + } + + // Get ecmcAsynPort + ecmcAsynPort = (ecmcAsynPortDriver*)getEcmcAsynPortDriver(); + if(!ecmcAsynPort) { + PRINT_IF_DBG_MODE("%s/%s:%d: Error: ecmcAsynPort NULL (0x%x).\n", + __FILE__, __FUNCTION__, __LINE__, ECMC_PLUGIN_ERROR_ASYNPORT_NULL); + return ECMC_PLUGIN_ERROR_ASYNPORT_NULL; + } + + // create new ecmcFFT object + fft = new ecmcFFT(dataItem, ecmcAsynPort); + if(!fft) { + PRINT_IF_DBG_MODE("%s/%s:%d: Error: ecmcFFT NULL (0x%x).\n", + __FILE__, __FUNCTION__, __LINE__, ECMC_PLUGIN_ERROR_FFT_NULL); + return ECMC_PLUGIN_ERROR_FFT_NULL; + } + + // Register callback + return fft->ConnectToDataSource(); +} diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.h b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.h new file mode 100644 index 0000000..6a2a80e --- /dev/null +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.h @@ -0,0 +1,40 @@ +/*************************************************************************\ +* 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. +* +* ecmcFFTWrap.h +* +* Created on: Mar 22, 2020 +* Author: anderssandstrom +* +\*************************************************************************/ +#ifndef ECMC_FFT_WRAP_H_ +#define ECMC_FFT_WRAP_H_ + +# ifdef __cplusplus +extern "C" { +# endif // ifdef __cplusplus + +//Error codes +#define ECMC_PLUGIN_ERROR_CONFIG_STR_PARSE_FAIL 1 +#define ECMC_PLUGIN_ERROR_NO_SOURCE 2 +#define ECMC_PLUGIN_ERROR_DATA_SOURCE_NULL 3 +#define ECMC_PLUGIN_ERROR_ASYNPORT_NULL 4 +#define ECMC_PLUGIN_ERROR_FFT_NULL 5 + +#define PRINT_IF_DBG_MODE(fmt, ...) \ + { \ + if(dbgModeOption){ \ + printf(fmt, ## __VA_ARGS__); \ + } \ + } \ + + +int createFFT(char *source, int dbgMode); + +# ifdef __cplusplus +} +# endif // ifdef __cplusplus + +#endif /* ECMC_FFT_WRAP_H_ */ diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcPluginFFT.c b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcPluginFFT.c index 0a0c632..4073057 100644 --- a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcPluginFFT.c +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcPluginFFT.c @@ -23,32 +23,24 @@ extern "C" { #include #include "ecmcPluginDefs.h" -#include "ecmcFFT.h" +#include "ecmcPluginClient.h" +#include "ecmcFFTWrap.h" +//Options #define ECMC_PLUGIN_DBG_OPTION_CMD "DBG_PRINT=" #define ECMC_PLUGIN_SOURCE_OPTION_CMD "SOURCE=" -#define PRINT_IF_DBG_MODE(fmt, ...) \ - { \ - if(dbgModeOption){ \ - printf(fmt, ## __VA_ARGS__); \ - } \ - } \ - -static int lastEcmcError = 0; -static double ecmcSampleRate = 0; -static void* ecmcAsynPort = NULL; -static char* confStr = NULL; -static int dbgModeOption = 0; -static char* source = NULL; - +static int lastEcmcError = 0; +static char* confStr = NULL; +static int dbgModeOption = 0; +static char* source = NULL; /** Optional. * Will be called once after successfull load into ecmc. * Return value other than 0 will be considered error. * configStr can be used for configuration parameters. **/ -int adv_exampleConstruct(char * configStr) +int adv_exampleConstruct(char *configStr) { PRINT_IF_DBG_MODE("%s/%s:%d: ConfigStr=\"%s\"...\n",__FILE__, __FUNCTION__, __LINE__,configStr); // check config parameters @@ -56,7 +48,8 @@ int adv_exampleConstruct(char * configStr) char *pOptions = strdup(configStr); char *pThisOption = pOptions; char *pNextOption = pOptions; - + PRINT_IF_DBG_MODE("%s/%s:%d: Error: "ECMC_PLUGIN_SOURCE_OPTION_CMD"NULL.\n", + __FILE__, __FUNCTION__, __LINE__); while (pNextOption && pNextOption[0]) { pNextOption = strchr(pNextOption, ';'); if (pNextOption) { @@ -80,22 +73,21 @@ int adv_exampleConstruct(char * configStr) } free(pOptions); } + //printout options PRINT_IF_DBG_MODE("%s/%s:%d: %s%d, %s\"%s\"\n",__FILE__, __FUNCTION__, __LINE__,ECMC_PLUGIN_DBG_OPTION_CMD, dbgModeOption, ECMC_PLUGIN_SOURCE_OPTION_CMD, source); - // Determine ecmc sample rate (just for demo) - ecmcSampleRate = getSampleRate(); - PRINT_IF_DBG_MODE("%s/%s:%d: Ecmc sample rate is: %lf ms\n",__FILE__, __FUNCTION__, __LINE__,ecmcSampleRate); + // Check that SOURCE are defined + if(!source) { + PRINT_IF_DBG_MODE("%s/%s:%d: Error: "ECMC_PLUGIN_SOURCE_OPTION_CMD"NULL (0x%x).\n", + __FILE__, __FUNCTION__, __LINE__, ECMC_PLUGIN_ERROR_NO_SOURCE); + return ECMC_PLUGIN_ERROR_NO_SOURCE; + } - // Use ecmcAsynPort (just for demo) - ecmcAsynPort = getAsynPort(); - - // init asyn param counter - initAsyn(ecmcAsynPort); - - return 0; + // create FFT object and register data callback + return createFFT(source, dbgModeOption); } /** Optional function. @@ -122,8 +114,6 @@ void adv_exampleDestruct(void) **/ int adv_exampleRealtime(int ecmcError) { - //Update asynparam counter - increaseCounter(); lastEcmcError = ecmcError; return 0; } diff --git a/ecmcPlugin_FFT.Makefile b/ecmcPlugin_FFT.Makefile index 869f597..69e3125 100644 --- a/ecmcPlugin_FFT.Makefile +++ b/ecmcPlugin_FFT.Makefile @@ -47,6 +47,7 @@ USR_INCLUDES += -I$(where_am_I)$(APPSRC) TEMPLATES += $(wildcard $(APPDB)/*.db) SOURCES += $(APPSRC)/ecmcPluginFFT.c +SOURCES += $(APPSRC)/ecmcFFTWrap.cpp SOURCES += $(APPSRC)/ecmcFFT.cpp db: