diff --git a/GNUmakefile b/GNUmakefile index 0172317..7b297b2 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -21,11 +21,17 @@ ecmc_VERSION = 9.1.0 BASE_DIR = . SRC_DIR = $(BASE_DIR)/src DB_DIR = $(BASE_DIR)/Db - +SCRIPTS_DIR = $(BASE_DIR)/scripts +DB_DIR = $(BASE_DIR)/Db SOURCES += $(SRC_DIR)/ecmcDAQDataArray.cpp SOURCES += $(SRC_DIR)/ecmcDAQDataChannel.cpp SOURCES += $(SRC_DIR)/ecmcDAQWrap.cpp SOURCES += $(SRC_DIR)/ecmcPluginDAQ.c DBDS += $(SRC_DIR)/ecmcDAQPlg.dbd TEMPLATES += $(wildcard $(DB_DIR)/*.template) -SCRIPTS += ./startup.cmd \ No newline at end of file +SCRIPTS += ./startup.cmd +SCRIPTS += $(SCRIPTS_DIR)/ecmcAddDaqArray.cmd +SCRIPTS += $(SCRIPTS_DIR)ecmcAddDaqChannel.cmd +SCRIPTS += $(SCRIPTS_DIR)ecmcAddDaqDataItem.cmd +SCRIPTS += $(SCRIPTS_DIR)ecmcLoadDaqArrayRecords.cmd + diff --git a/scripts/ecmcAddDaqArray.cmd b/scripts/ecmcAddDaqArray.cmd new file mode 100644 index 0000000..011d337 --- /dev/null +++ b/scripts/ecmcAddDaqArray.cmd @@ -0,0 +1,20 @@ + +#============================================================================== +# ecmcAddDaqArray.cmd +#-------------- Information: +#- Description: ecmc_plugin_daq ecmcAddDaqArray.cmd +#- Add a DAQ-Array object +#- +#- by Anders Sandström, Paul Scherrer Institute, 2024 +#- email: anders.sandstroem@psi.ch +#- +#-############################################################################### +#- +#- Arguments +#- NAME : Name of DAQ array object +#- +################################################################################# + +#- Name , Asyn port name +ecmcAddDAQArray(${NAME},ECMC.PLUGIN.DAQ.${NAME}) + diff --git a/scripts/ecmcAddDaqChannel.cmd b/scripts/ecmcAddDaqChannel.cmd new file mode 100644 index 0000000..6725796 --- /dev/null +++ b/scripts/ecmcAddDaqChannel.cmd @@ -0,0 +1,19 @@ + +#============================================================================== +# ecmcAddDaqChannel.cmd +#-------------- Information: +#- Description: ecmc_plugin_daq ecmcAddDaqChannel.cmd +#- Add a DAQ-channel to the last added DAQ-array object +#- +#- by Anders Sandström, Paul Scherrer Institute, 2024 +#- email: anders.sandstroem@psi.ch +#- +#-############################################################################### +#- +#- Arguments +#- TYPE : Type (number of data type) +#- +################################################################################# + +ecmcAddDAQChannel(${TYPE}) + diff --git a/scripts/ecmcAddDaqDataItem.cmd b/scripts/ecmcAddDaqDataItem.cmd new file mode 100644 index 0000000..5ae3d85 --- /dev/null +++ b/scripts/ecmcAddDaqDataItem.cmd @@ -0,0 +1,26 @@ + +#============================================================================== +# ecmcAddDaqDataItem.cmd +#-------------- Information: +#- Description: ecmc_plugin_daq ecmcAddDaqDataItem.cmd +#- Add a DAQ-dataitem to the last added DAQ-channel object +#- +#- by Anders Sandström, Paul Scherrer Institute, 2024 +#- email: anders.sandstroem@psi.ch +#- +#-############################################################################### +#- +#- Arguments +#- PARAM : Parameter to add (ec0.s1.positionActual01) +#- FORMAT: Optional formatting of data +#- 0 = raw (default) : Take raw value (do not apply special format)\n"); +#- 1 = time_micro_s : Time: Recalc 64bit nano seconds to 32 bit micro second counter\n"); +#- 2 = time_micro_s_minus_period : Time: Recalc 64bit nano seconds to 32 bit micro second counter minus one ec-period.\n"); +#- Useful for oversampling slaves where normally the nextsync time is available.\n"); +#- The calculated time then would correspond to the first data in the array recived.\n"); +#- 3 = time_ns_minus_period : Time: Raw value minus one period.\n"); +#- +################################################################################# + +ecmcAddDAQItem(${PARAM},${FORMAT=0}) + diff --git a/scripts/ecmcLoadDaqArrayRecords.cmd b/scripts/ecmcLoadDaqArrayRecords.cmd new file mode 100644 index 0000000..12723ad --- /dev/null +++ b/scripts/ecmcLoadDaqArrayRecords.cmd @@ -0,0 +1,26 @@ + +#============================================================================== +# ecmcLoadDaqArrayRecords.cmd +#-------------- Information: +#- Description: ecmc_plugin_daq ecmcLoadDaqArrayRecords.cmd +#- Load database for a DAQ-Array +#- +#- by Anders Sandström, Paul Scherrer Institute, 2024 +#- email: anders.sandstroem@psi.ch +#- +#-############################################################################### +#- +#- Arguments +#- NAME : Name of DAQ array +#- +################################################################################# + +# Read NELM +ecmcDAQReadNelm(${NAME},"DAQ_NELM") +ecmcIf("${DAQ_NELM=-1}<0") +${IF_TRUE}ecmcExit : Failed read DAQ array NELM +ecmcEndIf() + +dbLoadTemplate(ecmcPluginDAQ.template,"P=${ECMC_PREFIX},Name=${NAME},NELM=${DAQ_NELM},PORT=ECMC.PLUGIN.DAQ.${NAME}") +epicsEnvUnset(DAQ_NELM) + diff --git a/src/ecmcDAQDataArray.cpp b/src/ecmcDAQDataArray.cpp index 01ee7ee..c2aaa4d 100644 --- a/src/ecmcDAQDataArray.cpp +++ b/src/ecmcDAQDataArray.cpp @@ -201,3 +201,8 @@ void ecmcDAQDataArray::initAsyn() { callParamCallbacks(); return; } + +size_t ecmcDAQDataArray::getArraySize() { + return totalElementCount_; +} + diff --git a/src/ecmcDAQDataArray.h b/src/ecmcDAQDataArray.h index e8da595..4d8ccc5 100644 --- a/src/ecmcDAQDataArray.h +++ b/src/ecmcDAQDataArray.h @@ -30,6 +30,7 @@ class ecmcDAQDataArray : public asynPortDriver { // Always add to last added channel void addDataItemToChannel(const char* name, int format); void setEnable(int enable); + size_t getArraySize(); private: void buildArrayHeader(); diff --git a/src/ecmcDAQWrap.cpp b/src/ecmcDAQWrap.cpp index a1f32a6..ba1c997 100644 --- a/src/ecmcDAQWrap.cpp +++ b/src/ecmcDAQWrap.cpp @@ -51,6 +51,26 @@ int createDAQArray(const char* name, const char* portName ) { return 0; } +ecmcDAQDataArray* getDAQArrayFromName(const char *name) { + // Find group by name + for(std::vector::iterator array = arrays.begin(); array != arrays.end(); ++array) { + bool found = strcmp(name, (*array)->getName().c_str()) == 0; + if(found) { + return (*array); + } + } + return NULL; +} + + +int getDAQDataArrayNelm(const char *name){ + ecmcDAQDataArray array = getDAQArrayFromName(name); + if(!array){ + return -1; + } + return array->getArraySize(); +} + int createDAQChannel(int type) { try { @@ -261,11 +281,68 @@ static void initCallFunc_2(const iocshArgBuf *args) { ecmcAddDAQItem(args[0].sval,args[1].ival); } + +/** + * EPICS iocsh shell command: ecmcAddDAQItem +*/ +void ecmcDAQReadNelmHelp() { + printf("\n"); + printf(" Use ecmcDAQReadNELM(,)\n"); + printf(" : Name of DAQ array object.\n"); + printf(" : Variable for return value.\n"); + printf("\n"); +} +nelmBuffer[100]; + +int ecmcDAQReadNelm(const char* name, const char* result_var) { + if(!name) { + ecmcAddDAQArrayHelp(); + return asynError; + } + if(!result_var) { + ecmcAddDAQArrayHelp(); + return asynError; + } + if(strcmp(name,"-h") == 0 || strcmp(name,"--help") == 0 ) { + ecmcDAQReadNelmHelp(); + return asynSuccess; + } + + memset(&nelmBuffer[0],0,100); + + int nelm = 0; + try { + nelm = getDAQDataArrayNelm(name); + sprintf(nelmBuffer, "%zu", nelm); + epicsEnvSet(result_var, nelmBuffer); + } + catch(std::exception& e) { + printf("Exception: %s. Find DAQ item failed.\n",e.what()); + exit(EXIT_FAILURE); + } + + return asynSuccess; +} + +static const iocshArg initArg0_3 = +{ "name", iocshArgString }; + +static const iocshArg initArg1_3 = +{ "Return value variable", iocshArgString }; + +static const iocshArg *const initArgs_3[] = { &initArg0_3, + &initArg1_3}; + +static const iocshFuncDef initFuncDef_3 = { "ecmcDAQReadNelm", 2, initArgs_3}; +static void initCallFunc_3(const iocshArgBuf *args) { + ecmcDAQReadNelm(args[0].sval,args[1].sval); +} // Register void ecmcDAQPlgRegister(void) { iocshRegister(&initFuncDef_0, initCallFunc_0); iocshRegister(&initFuncDef_1, initCallFunc_1); iocshRegister(&initFuncDef_2, initCallFunc_2); + iocshRegister(&initFuncDef_3, initCallFunc_3); } epicsExportRegistrar(ecmcDAQPlgRegister);