Initial commint (based on fft plugin, still sources left)
This commit is contained in:
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
*~
|
||||||
|
*-dev
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
core.*
|
||||||
|
#*
|
||||||
|
.#*
|
||||||
|
\#*
|
||||||
|
*.local
|
||||||
|
\#*
|
||||||
|
.cvsignore
|
||||||
|
*_old/
|
||||||
|
*PVs.list
|
||||||
|
*-loc/*.Makefile
|
||||||
|
ecmc_plugin_fft/*.Makefile
|
||||||
|
*__*
|
||||||
28
Makefile
Normal file
28
Makefile
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2018 - 2019 European Spallation Source ERIC
|
||||||
|
#
|
||||||
|
# The program is free software: you can redistribute
|
||||||
|
# it and/or modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation, either version 2 of the
|
||||||
|
# License, or any newer version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
# more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# this program. If not, see https://www.gnu.org/licenses/gpl-2.0.txt
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Author : Jeong Han Lee
|
||||||
|
# email : han.lee@esss.se
|
||||||
|
# Date : 2020Mar22-1607-33CET
|
||||||
|
# version : 1.0.0
|
||||||
|
|
||||||
|
TOP:=$(CURDIR)
|
||||||
|
|
||||||
|
include $(TOP)/configure/CONFIG
|
||||||
|
|
||||||
|
include $(TOP)/configure/RULES
|
||||||
|
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
e3-ecmc_plugin_socketcan
|
||||||
|
======
|
||||||
|
ESS Site-specific EPICS module : ecmcPlugin_socketcan
|
||||||
0
cmds/.keep
Normal file
0
cmds/.keep
Normal file
11
configure/CONFIG
Normal file
11
configure/CONFIG
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#
|
||||||
|
VARS_EXCLUDES := $(.VARIABLES)
|
||||||
|
|
||||||
|
include $(TOP)/configure/RELEASE
|
||||||
|
include $(TOP)/configure/CONFIG_MODULE
|
||||||
|
|
||||||
|
E3_REQUIRE_LOCATION := $(EPICS_BASE)/$(E3_REQUIRE_NAME)/$(E3_REQUIRE_VERSION)
|
||||||
|
REQUIRE_CONFIG := $(E3_REQUIRE_LOCATION)/configure
|
||||||
|
|
||||||
|
include $(REQUIRE_CONFIG)/CONFIG
|
||||||
|
|
||||||
37
configure/CONFIG_MODULE
Normal file
37
configure/CONFIG_MODULE
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#
|
||||||
|
EPICS_MODULE_NAME:=ecmc_plugin_socketcan
|
||||||
|
|
||||||
|
EPICS_MODULE_TAG:=master
|
||||||
|
#
|
||||||
|
E3_MODULE_VERSION:=master
|
||||||
|
|
||||||
|
# DEPENDENT MODULE VERSION
|
||||||
|
# For Example,
|
||||||
|
|
||||||
|
ECMC_DEP_VERSION:=6.3.0
|
||||||
|
ASYN_DEP_VERSION:=4.37.0
|
||||||
|
|
||||||
|
#DEVLIB2_DEP_VERSION:=2.9.0
|
||||||
|
#PCRE_DEP_VERSION:=8.41.0
|
||||||
|
#ADCORE_DEP_VERSION:=3.7.0
|
||||||
|
#ADSUPPORT_DEP_VERSION:=1.9.0
|
||||||
|
#LOKI_DEP_VERSION=1.0.0
|
||||||
|
#NDS_DEP_VERSION=2.3.3
|
||||||
|
#SIS8300DRV_DEP_VERSION=4.3.1
|
||||||
|
#SEQUENCER_DEP_VERSION=2.2.7
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#E3_KMOD_SRC_PATH:=$(E3_MODULE_SRC_PATH)
|
||||||
|
#
|
||||||
|
# In most case, we don't need to touch the following variables.
|
||||||
|
#
|
||||||
|
|
||||||
|
E3_MODULE_NAME:=$(EPICS_MODULE_NAME)
|
||||||
|
E3_MODULE_SRC_PATH:=ecmc_plugin_fft
|
||||||
|
E3_MODULE_MAKEFILE:=$(EPICS_MODULE_NAME).Makefile
|
||||||
|
|
||||||
|
|
||||||
|
-include $(TOP)/configure/CONFIG_OPTIONS
|
||||||
|
# The definitions shown below can also be placed in an untracked CONFIG_MODULE.local
|
||||||
|
-include $(TOP)/configure/CONFIG_MODULE.local
|
||||||
|
|
||||||
6
configure/CONFIG_OPTIONS
Normal file
6
configure/CONFIG_OPTIONS
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
# WITH_PVA:=NO
|
||||||
|
#
|
||||||
|
# The definitions shown below can also be placed in an untracked CONFIG_OPTIONS.local
|
||||||
|
-include $(TOP)/configure/CONFIG_OPTIONS.local
|
||||||
|
|
||||||
11
configure/RELEASE
Normal file
11
configure/RELEASE
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#
|
||||||
|
EPICS_BASE:=${HOME}/epics/base-7.0.4
|
||||||
|
|
||||||
|
E3_REQUIRE_NAME:=require
|
||||||
|
E3_REQUIRE_VERSION:=3.3.0
|
||||||
|
|
||||||
|
# The definitions shown below can also be placed in an untracked RELEASE.local
|
||||||
|
-include $(TOP)/../../RELEASE.local
|
||||||
|
-include $(TOP)/../RELEASE.local
|
||||||
|
-include $(TOP)/configure/RELEASE.local
|
||||||
|
|
||||||
12
configure/RULES
Normal file
12
configure/RULES
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
include $(REQUIRE_CONFIG)/RULES_E3
|
||||||
|
include $(REQUIRE_CONFIG)/DEFINES_FT
|
||||||
|
include $(REQUIRE_CONFIG)/RULES_PATCH
|
||||||
|
include $(REQUIRE_CONFIG)/RULES_E3_SITELIBS
|
||||||
|
|
||||||
|
include $(REQUIRE_CONFIG)/RULES_VLIBS
|
||||||
|
include $(REQUIRE_CONFIG)/RULES_VARS
|
||||||
|
|
||||||
|
include $(TOP)/configure/module/RULES_MODULE
|
||||||
|
-include $(TOP)/configure/module/RULES_DKMS_L
|
||||||
|
|
||||||
38
configure/module/RULES_DKMS_L
Normal file
38
configure/module/RULES_DKMS_L
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
# KMOD_NAME := mrf
|
||||||
|
|
||||||
|
# .PHONY: dkms_add
|
||||||
|
|
||||||
|
# dkms_add: conf
|
||||||
|
# $(MSI) -M name="$(E3_MODULE_NAME)" -M version="$(E3_MODULE_VERSION)" -M kmod_name="$(KMOD_NAME)" $(TOP)/dkms/dkms_with_msi.conf.in > $(TOP)/dkms/dkms_with_msi.conf
|
||||||
|
# $(QUIET) cat $(TOP)/dkms/dkms_with_msi.conf $(TOP)/dkms/dkms_without_msi.conf > $(TOP)/dkms/dkms.conf
|
||||||
|
# $(QUIET) install -m 644 $(TOP)/dkms/dkms.conf $(E3_KMOD_SRC_PATH)/
|
||||||
|
# $(SUDO) install -d /usr/src/$(E3_MODULE_NAME)-$(E3_MODULE_VERSION)
|
||||||
|
# $(SUDO) cp -r $(TOP)/$(E3_KMOD_SRC_PATH)/* /usr/src/$(E3_MODULE_NAME)-$(E3_MODULE_VERSION)/
|
||||||
|
# $(SUDO) $(DKMS) add $(DKMS_ARGS)
|
||||||
|
|
||||||
|
|
||||||
|
# setup:
|
||||||
|
# $(QUIET) $(SUDO2) 'echo KERNEL==\"uio*\", ATTR{name}==\"mrf-pci\", MODE=\"0666\" | tee /etc/udev/rules.d/99-$(KMOD_NAME).rules'
|
||||||
|
# $(QUIET) $(SUDO) /bin/udevadm control --reload-rules
|
||||||
|
# $(QUIET) $(SUDO) /bin/udevadm trigger
|
||||||
|
# $(QUIET) $(SUDO2) 'echo $(KMOD_NAME) | tee /etc/modules-load.d/$(KMOD_NAME).conf'
|
||||||
|
# $(QUIET) $(SUDO) depmod --quick
|
||||||
|
# $(QUIET) $(SUDO) modprobe -rv $(KMOD_NAME)
|
||||||
|
# $(QUIET) $(SUDO) modprobe -v $(KMOD_NAME)
|
||||||
|
# $(QUIET) echo ""
|
||||||
|
# $(QUIET) echo ""
|
||||||
|
# $(QUIET) echo "It is OK to see \"E3/RULES_DKMS:37: recipe for target 'setup' failed\""
|
||||||
|
# $(QUIET) echo "---------------------------------------------------------------------"
|
||||||
|
# $(QUIET) -ls -l /dev/uio* 2>/dev/null
|
||||||
|
# $(QUIET) echo "---------------------------------------------------------------------"
|
||||||
|
|
||||||
|
|
||||||
|
# setup_clean:
|
||||||
|
# $(QUIET) $(SUDO) modprobe -rv $(KMOD_NAME)
|
||||||
|
# $(SUDO) rm -f /etc/modules-load.d/$(KMOD_NAME).conf
|
||||||
|
# $(SUDO) rm -f /etc/udev/rules.d/99-$(KMOD_NAME).rules
|
||||||
|
|
||||||
|
|
||||||
|
# .PHONY: setup setup_clean
|
||||||
|
|
||||||
20
configure/module/RULES_MODULE
Normal file
20
configure/module/RULES_MODULE
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#
|
||||||
|
.PHONY: db hdrs
|
||||||
|
|
||||||
|
db: conf
|
||||||
|
$(QUIET) $(E3_MODULE_MAKE_CMDS) db
|
||||||
|
|
||||||
|
hdrs:
|
||||||
|
# $(SUDO) install -m 755 -d $(E3_MODULES_INSTALL_LOCATION_INC)/pv
|
||||||
|
# cd $(E3_MODULES_INSTALL_LOCATION_INC) && $(SUDO) mv *.h pv/
|
||||||
|
|
||||||
|
#.PHONY: epics
|
||||||
|
#epics:
|
||||||
|
# $(QUIET)echo "EPICS_BASE:=$(EPICS_BASE)" > $(TOP)/$(E3_MODULE_SRC_PATH)/configure/RELEASE
|
||||||
|
# $(QUIET)echo "ASYN:=$(M_ASYN)" > $(TOP)/$(E3_MODULE_SRC_PATH)/configure/RELEASE
|
||||||
|
# $(QUIET)echo "SSCAN:=$(M_SSCAN)" >> $(TOP)/$(E3_MODULE_SRC_PATH)/configure/RELEASE
|
||||||
|
# $(QUIET)echo "SNCSEQ:=$(M_SNCSEQ)" >> $(TOP)/$(E3_MODULE_SRC_PATH)/configure/RELEASE
|
||||||
|
# $(QUIET)echo "CHECK_RELEASE:=YES" > $(TOP)/$(E3_MODULE_SRC_PATH)/configure/CONFIG_SITE
|
||||||
|
# $(QUIET)echo "INSTALL_LOCATION:=$(M_DEVLIB2)" >> $(TOP)/$(E3_MODULE_SRC_PATH)/configure/CONFIG_SITE
|
||||||
|
# $(SUDOBASH) "$(MAKE) -C $(E3_MODULE_SRC_PATH)"
|
||||||
|
|
||||||
28
docs/.MODULE_LOG
Normal file
28
docs/.MODULE_LOG
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
>>
|
||||||
|
Script is used : e3TemplateGenerator.bash
|
||||||
|
Script Path : /home/anderssandstrom/plugin_ecmc/e3-tools/e3TemplateGenerator
|
||||||
|
Script Version : 1.0.8
|
||||||
|
Script Run Time : 2020Mar22-1607-33CET
|
||||||
|
User : anderssandstrom
|
||||||
|
e3-tools Hash : bf03d40
|
||||||
|
>>
|
||||||
|
>> git diff
|
||||||
|
|
||||||
|
>>
|
||||||
|
>> git diff --cached
|
||||||
|
|
||||||
|
>>
|
||||||
|
>> git diff HEAD
|
||||||
|
|
||||||
|
|
||||||
|
>>
|
||||||
|
>> Your sources are located in e3-ecmcPlugin_Simple.
|
||||||
|
>>
|
||||||
|
EPICS_MODULE_NAME : ecmcPlugin_Simple
|
||||||
|
E3_MODULE_SRC_PATH : ecmcPlugin_Simple
|
||||||
|
E3_TARGET_URL : https://github.com/anderssandstrom
|
||||||
|
>>
|
||||||
|
e3 module name : e3-ecmcPlugin_Simple
|
||||||
|
e3 target url full : https://github.com/anderssandstrom/e3-ecmcPlugin_Simple.git
|
||||||
|
>>
|
||||||
|
e3 module is located in siteMods
|
||||||
62
ecmc_plugin_socketcan.Makefile
Normal file
62
ecmc_plugin_socketcan.Makefile
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2019 European Spallation Source ERIC
|
||||||
|
#
|
||||||
|
# The program is free software: you can redistribute
|
||||||
|
# it and/or modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation, either version 2 of the
|
||||||
|
# License, or any newer version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
# more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# this program. If not, see https://www.gnu.org/licenses/gpl-2.0.txt
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Author : anderssandstrom
|
||||||
|
# email : anderssandstrom@esss.se
|
||||||
|
# Date : 2020Mar22-1607-33CET
|
||||||
|
# version : 0.0.0
|
||||||
|
#
|
||||||
|
# template file is generated by ./e3TemplateGenerator.bash with bf03d40
|
||||||
|
# Please look at many other _module_.Makefile in e3-* repository
|
||||||
|
#
|
||||||
|
|
||||||
|
## The following lines are mandatory, please don't change them.
|
||||||
|
where_am_I := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||||
|
include $(E3_REQUIRE_TOOLS)/driver.makefile
|
||||||
|
include $(E3_REQUIRE_CONFIG)/DECOUPLE_FLAGS
|
||||||
|
|
||||||
|
ifneq ($(strip $(ASYN_DEP_VERSION)),)
|
||||||
|
asyn_VERSION=$(ASYN_DEP_VERSION)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(strip $(ECMC_DEP_VERSION)),)
|
||||||
|
ecmc_VERSION=$(ECMC_DEP_VERSION)
|
||||||
|
endif
|
||||||
|
|
||||||
|
APP:=ecmc_plugin_fftApp
|
||||||
|
APPDB:=$(APP)/Db
|
||||||
|
APPSRC:=$(APP)/src
|
||||||
|
|
||||||
|
USR_CFLAGS += -shared -fPIC -Wall -Wextra
|
||||||
|
USR_LDFLAGS += -lstdc++
|
||||||
|
USR_INCLUDES += -I$(where_am_I)$(APPSRC)
|
||||||
|
|
||||||
|
TEMPLATES += $(wildcard $(APPDB)/*.db)
|
||||||
|
TEMPLATES += $(wildcard $(APPDB)/*.template)
|
||||||
|
SOURCES += $(APPSRC)/ecmcPluginFFT.c
|
||||||
|
SOURCES += $(APPSRC)/ecmcFFTWrap.cpp
|
||||||
|
SOURCES += $(APPSRC)/ecmcFFT.cpp
|
||||||
|
|
||||||
|
db:
|
||||||
|
|
||||||
|
.PHONY: db
|
||||||
|
|
||||||
|
vlibs:
|
||||||
|
|
||||||
|
.PHONY: vlibs
|
||||||
|
|
||||||
|
###
|
||||||
62
ecmc_plugin_socketcan/ecmc_plugin_socketcan.Makefile
Normal file
62
ecmc_plugin_socketcan/ecmc_plugin_socketcan.Makefile
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2019 European Spallation Source ERIC
|
||||||
|
#
|
||||||
|
# The program is free software: you can redistribute
|
||||||
|
# it and/or modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation, either version 2 of the
|
||||||
|
# License, or any newer version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
# more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# this program. If not, see https://www.gnu.org/licenses/gpl-2.0.txt
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Author : anderssandstrom
|
||||||
|
# email : anderssandstrom@esss.se
|
||||||
|
# Date : 2020Mar22-1607-33CET
|
||||||
|
# version : 0.0.0
|
||||||
|
#
|
||||||
|
# template file is generated by ./e3TemplateGenerator.bash with bf03d40
|
||||||
|
# Please look at many other _module_.Makefile in e3-* repository
|
||||||
|
#
|
||||||
|
|
||||||
|
## The following lines are mandatory, please don't change them.
|
||||||
|
where_am_I := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||||
|
include $(E3_REQUIRE_TOOLS)/driver.makefile
|
||||||
|
include $(E3_REQUIRE_CONFIG)/DECOUPLE_FLAGS
|
||||||
|
|
||||||
|
ifneq ($(strip $(ASYN_DEP_VERSION)),)
|
||||||
|
asyn_VERSION=$(ASYN_DEP_VERSION)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(strip $(ECMC_DEP_VERSION)),)
|
||||||
|
ecmc_VERSION=$(ECMC_DEP_VERSION)
|
||||||
|
endif
|
||||||
|
|
||||||
|
APP:=ecmc_plugin_fftApp
|
||||||
|
APPDB:=$(APP)/Db
|
||||||
|
APPSRC:=$(APP)/src
|
||||||
|
|
||||||
|
USR_CFLAGS += -shared -fPIC -Wall -Wextra
|
||||||
|
USR_LDFLAGS += -lstdc++
|
||||||
|
USR_INCLUDES += -I$(where_am_I)$(APPSRC)
|
||||||
|
|
||||||
|
TEMPLATES += $(wildcard $(APPDB)/*.db)
|
||||||
|
TEMPLATES += $(wildcard $(APPDB)/*.template)
|
||||||
|
SOURCES += $(APPSRC)/ecmcPluginFFT.c
|
||||||
|
SOURCES += $(APPSRC)/ecmcFFTWrap.cpp
|
||||||
|
SOURCES += $(APPSRC)/ecmcFFT.cpp
|
||||||
|
|
||||||
|
db:
|
||||||
|
|
||||||
|
.PHONY: db
|
||||||
|
|
||||||
|
vlibs:
|
||||||
|
|
||||||
|
.PHONY: vlibs
|
||||||
|
|
||||||
|
###
|
||||||
1057
ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcFFT.cpp
Normal file
1057
ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcFFT.cpp
Normal file
File diff suppressed because it is too large
Load Diff
153
ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcFFT.h
Normal file
153
ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcFFT.h
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/*************************************************************************\
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* ecmcFFT.h
|
||||||
|
*
|
||||||
|
* Created on: Mar 22, 2020
|
||||||
|
* Author: anderssandstrom
|
||||||
|
*
|
||||||
|
\*************************************************************************/
|
||||||
|
#ifndef ECMC_FFT_H_
|
||||||
|
#define ECMC_FFT_H_
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "ecmcDataItem.h"
|
||||||
|
#include "ecmcAsynPortDriver.h"
|
||||||
|
#include "ecmcFFTDefs.h"
|
||||||
|
#include "inttypes.h"
|
||||||
|
#include <string>
|
||||||
|
#include "kissfft/kissfft.hh"
|
||||||
|
|
||||||
|
class ecmcFFT : public asynPortDriver {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** ecmc FFT class
|
||||||
|
* This object can throw:
|
||||||
|
* - bad_alloc
|
||||||
|
* - invalid_argument
|
||||||
|
* - runtime_error
|
||||||
|
* - out_of_range
|
||||||
|
*/
|
||||||
|
ecmcFFT(int fftIndex, // index of this object
|
||||||
|
char* configStr,
|
||||||
|
char* portName);
|
||||||
|
~ecmcFFT();
|
||||||
|
|
||||||
|
// 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 connectToDataSource();
|
||||||
|
void setEnable(int enable);
|
||||||
|
void setModeFFT(FFT_MODE mode);
|
||||||
|
FFT_STATUS getStatusFFT();
|
||||||
|
void clearBuffers();
|
||||||
|
void triggFFT();
|
||||||
|
void doCalcWorker(); // Called from worker thread calc the results
|
||||||
|
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);
|
||||||
|
virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void parseConfigStr(char *configStr);
|
||||||
|
void addDataToBuffer(double data);
|
||||||
|
void calcFFT();
|
||||||
|
void scaleFFT();
|
||||||
|
void calcFFTAmp();
|
||||||
|
void calcFFTXAxis();
|
||||||
|
void removeDCOffset();
|
||||||
|
void removeLin();
|
||||||
|
void initAsyn();
|
||||||
|
void updateStatus(FFT_STATUS status); // Also updates asynparam
|
||||||
|
static int dataTypeSupported(ecmcEcDataType dt);
|
||||||
|
|
||||||
|
ecmcDataItem *dataItem_;
|
||||||
|
ecmcDataItemInfo *dataItemInfo_;
|
||||||
|
ecmcAsynPortDriver *asynPort_;
|
||||||
|
kissfft<double>* fftDouble_;
|
||||||
|
double* rawDataBuffer_; // Input data (real)
|
||||||
|
double* prepProcDataBuffer_; // Preprocessed data (real)
|
||||||
|
std::complex<double>* fftBufferInput_; // Result (complex)
|
||||||
|
std::complex<double>* fftBufferResult_; // Result (complex)
|
||||||
|
double* fftBufferResultAmp_; // Resulting amplitude (abs of fftBufferResult_)
|
||||||
|
double* fftBufferXAxis_; // FFT x axis with freqs
|
||||||
|
size_t elementsInBuffer_;
|
||||||
|
double ecmcSampleRateHz_;
|
||||||
|
int dataSourceLinked_; // To avoid link several times
|
||||||
|
// ecmc callback handle for use when deregister at unload
|
||||||
|
int callbackHandle_;
|
||||||
|
int fftWaitingForCalc_;
|
||||||
|
int destructs_;
|
||||||
|
int objectId_; // Unique object id
|
||||||
|
int triggOnce_;
|
||||||
|
int cycleCounter_;
|
||||||
|
int ignoreCycles_;
|
||||||
|
double scale_; // Config: Data set size
|
||||||
|
FFT_STATUS status_; // Status/state (NO_STAT, IDLE, ACQ, CALC)
|
||||||
|
|
||||||
|
// Config options
|
||||||
|
char* cfgDataSourceStr_; // Config: data source string
|
||||||
|
int cfgDbgMode_; // Config: allow dbg printouts
|
||||||
|
int cfgApplyScale_; // Config: apply scale 1/nfft
|
||||||
|
int cfgDcRemove_; // Config: remove dc (average)
|
||||||
|
int cfgLinRemove_; // Config: remove linear componet (by least square)
|
||||||
|
size_t cfgNfft_; // Config: Data set size
|
||||||
|
int cfgEnable_; // Config: Enable data acq./calc.
|
||||||
|
FFT_MODE cfgMode_; // Config: Mode continous or triggered.
|
||||||
|
double cfgFFTSampleRateHz_; // Config: Sample rate (defaults to ecmc rate)
|
||||||
|
double cfgScale_;
|
||||||
|
double cfgDataSampleRateHz_; // Config: Sample for data
|
||||||
|
|
||||||
|
// Asyn
|
||||||
|
int asynEnableId_; // Enable/disable acq./calcs
|
||||||
|
int asynRawDataId_; // Raw data (input) array (double)
|
||||||
|
int asynPPDataId_; // Pre-processed data 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
|
||||||
|
int asynNfftId_; // NFFT
|
||||||
|
int asynSRateId_; // Sample rate
|
||||||
|
int asynElementsInBuffer_; // Current buffer index
|
||||||
|
|
||||||
|
// Thread related
|
||||||
|
epicsEvent doCalcEvent_;
|
||||||
|
|
||||||
|
|
||||||
|
// 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 void printComplexArray(std::complex<double>* fftBuff,
|
||||||
|
size_t elements,
|
||||||
|
int objId);
|
||||||
|
static std::string to_string(int value);
|
||||||
|
static int leastSquare(int n,
|
||||||
|
const double y[],
|
||||||
|
double* k,
|
||||||
|
double* m); // y=kx+m
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ECMC_FFT_H_ */
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*************************************************************************\
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* ecmcFFTDefs.h
|
||||||
|
*
|
||||||
|
* Created on: Mar 22, 2020
|
||||||
|
* Author: anderssandstrom
|
||||||
|
* Credits to https://github.com/sgreg/dynamic-loading
|
||||||
|
*
|
||||||
|
\*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ECMC_FFT_DEFS_H_
|
||||||
|
#define ECMC_FFT_DEFS_H_
|
||||||
|
|
||||||
|
// Options
|
||||||
|
#define ECMC_PLUGIN_DBG_PRINT_OPTION_CMD "DBG_PRINT="
|
||||||
|
#define ECMC_PLUGIN_SOURCE_OPTION_CMD "SOURCE="
|
||||||
|
#define ECMC_PLUGIN_NFFT_OPTION_CMD "NFFT="
|
||||||
|
//#define ECMC_PLUGIN_APPLY_SCALE_OPTION_CMD "APPLY_SCALE="
|
||||||
|
#define ECMC_PLUGIN_RM_DC_OPTION_CMD "RM_DC="
|
||||||
|
#define ECMC_PLUGIN_ENABLE_OPTION_CMD "ENABLE="
|
||||||
|
#define ECMC_PLUGIN_RATE_OPTION_CMD "RATE="
|
||||||
|
#define ECMC_PLUGIN_RM_LIN_OPTION_CMD "RM_LIN="
|
||||||
|
#define ECMC_PLUGIN_SCALE_OPTION_CMD "SCALE="
|
||||||
|
|
||||||
|
|
||||||
|
// CONT, TRIGG
|
||||||
|
#define ECMC_PLUGIN_MODE_OPTION_CMD "MODE="
|
||||||
|
#define ECMC_PLUGIN_MODE_CONT_OPTION "CONT"
|
||||||
|
#define ECMC_PLUGIN_MODE_TRIGG_OPTION "TRIGG"
|
||||||
|
|
||||||
|
typedef enum FFT_MODE{
|
||||||
|
NO_MODE = 0,
|
||||||
|
CONT = 1,
|
||||||
|
TRIGG = 2,
|
||||||
|
} FFT_MODE;
|
||||||
|
|
||||||
|
typedef enum FFT_STATUS{
|
||||||
|
NO_STAT = 0,
|
||||||
|
IDLE = 1, // Doing nothing, waiting for trigg
|
||||||
|
ACQ = 2, // Acquireing data
|
||||||
|
CALC = 3, // Calc FFT
|
||||||
|
} FFT_STATUS;
|
||||||
|
|
||||||
|
/** Just one error code in "c" part of plugin
|
||||||
|
(error handled with exceptions i c++ part) */
|
||||||
|
#define ECMC_PLUGIN_FFT_ERROR_CODE 1
|
||||||
|
|
||||||
|
// Default size (must be n²)
|
||||||
|
#define ECMC_PLUGIN_DEFAULT_NFFT 4096
|
||||||
|
|
||||||
|
#endif /* ECMC_FFT_DEFS_H_ */
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
/*************************************************************************\
|
||||||
|
* 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 <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, portNameBuffer);
|
||||||
|
}
|
||||||
|
catch(std::exception& e) {
|
||||||
|
if(fft) {
|
||||||
|
delete fft;
|
||||||
|
}
|
||||||
|
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||||
|
return ECMC_PLUGIN_FFT_ERROR_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffts.push_back(fft);
|
||||||
|
fftObjCounter++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteAllFFTs() {
|
||||||
|
for(std::vector<ecmcFFT*>::iterator pfft = ffts.begin(); pfft != ffts.end(); ++pfft) {
|
||||||
|
if(*pfft) {
|
||||||
|
delete (*pfft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int linkDataToFFTs() {
|
||||||
|
for(std::vector<ecmcFFT*>::iterator pfft = ffts.begin(); pfft != ffts.end(); ++pfft) {
|
||||||
|
if(*pfft) {
|
||||||
|
try {
|
||||||
|
(*pfft)->connectToDataSource();
|
||||||
|
}
|
||||||
|
catch(std::exception& e) {
|
||||||
|
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||||
|
return ECMC_PLUGIN_FFT_ERROR_CODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int enableFFT(int fftIndex, int enable) {
|
||||||
|
try {
|
||||||
|
ffts.at(fftIndex)->setEnable(enable);
|
||||||
|
}
|
||||||
|
catch(std::exception& e) {
|
||||||
|
printf("Exception: %s. FFT index out of range.\n",e.what());
|
||||||
|
return ECMC_PLUGIN_FFT_ERROR_CODE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clearFFT(int fftIndex) {
|
||||||
|
try {
|
||||||
|
ffts.at(fftIndex)->clearBuffers();
|
||||||
|
}
|
||||||
|
catch(std::exception& e) {
|
||||||
|
printf("Exception: %s. FFT index out of range.\n",e.what());
|
||||||
|
return ECMC_PLUGIN_FFT_ERROR_CODE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int triggFFT(int fftIndex) {
|
||||||
|
try {
|
||||||
|
ffts.at(fftIndex)->triggFFT();
|
||||||
|
}
|
||||||
|
catch(std::exception& e) {
|
||||||
|
printf("Exception: %s. FFT index out of range.\n",e.what());
|
||||||
|
return ECMC_PLUGIN_FFT_ERROR_CODE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int modeFFT(int fftIndex, FFT_MODE mode) {
|
||||||
|
try {
|
||||||
|
ffts.at(fftIndex)->setModeFFT(mode);
|
||||||
|
}
|
||||||
|
catch(std::exception& e) {
|
||||||
|
printf("Exception: %s. FFT index out of range.\n",e.what());
|
||||||
|
return ECMC_PLUGIN_FFT_ERROR_CODE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FFT_STATUS statFFT(int fftIndex) {
|
||||||
|
try {
|
||||||
|
return ffts.at(fftIndex)->getStatusFFT();
|
||||||
|
}
|
||||||
|
catch(std::exception& e) {
|
||||||
|
printf("Exception: %s. FFT index out of range.\n",e.what());
|
||||||
|
return NO_STAT;
|
||||||
|
}
|
||||||
|
return NO_STAT;
|
||||||
|
}
|
||||||
112
ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcFFTWrap.h
Normal file
112
ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcFFTWrap.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*************************************************************************\
|
||||||
|
* 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_
|
||||||
|
#include "ecmcFFTDefs.h"
|
||||||
|
|
||||||
|
# ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
# endif // ifdef __cplusplus
|
||||||
|
|
||||||
|
/** \brief Create new FFT object
|
||||||
|
*
|
||||||
|
* The plugin supports creation of multiple FFT objects\n
|
||||||
|
* (if loaded several times).\n
|
||||||
|
* The different fft are adressed by fftindex (in other functions below).\n
|
||||||
|
* The first loaded fft get index 0 and then increases for each load.\n
|
||||||
|
* This function call will create the custom asynparameters dedicated for this plugin.\
|
||||||
|
* The configuration string needs to define a data source by:\n
|
||||||
|
* "SOURCE=<data source>;"\n
|
||||||
|
* Example:\n
|
||||||
|
* "SOURCE=ec0.s1.AI_1";\n
|
||||||
|
* \param[in] configStr Configuration string.\n
|
||||||
|
*
|
||||||
|
* \return 0 if success or otherwise an error code.\n
|
||||||
|
*/
|
||||||
|
int createFFT(char *configStr);
|
||||||
|
|
||||||
|
/** \brief Enable/disable FFT object
|
||||||
|
*
|
||||||
|
* Enable/disable FFT object. If disabled no data will be acquired\n
|
||||||
|
* and no calculations will be made.\n
|
||||||
|
* \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n
|
||||||
|
* \param[in] enable enable/disable (1/0).\n
|
||||||
|
*
|
||||||
|
* \return 0 if success or otherwise an error code.\n
|
||||||
|
*/
|
||||||
|
int enableFFT(int fftIndex, int enable);
|
||||||
|
|
||||||
|
/** \brief Clear FFT object\n
|
||||||
|
*
|
||||||
|
* Clears buffers. After this command the acquistion can start from scratch.\n
|
||||||
|
* \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n
|
||||||
|
*
|
||||||
|
* \return 0 if success or otherwise an error code.\n
|
||||||
|
*/
|
||||||
|
int clearFFT(int fftIndex);
|
||||||
|
|
||||||
|
/** \brief Set mode of FFT object
|
||||||
|
*
|
||||||
|
* The FFT object can measure in two differnt modes:\n
|
||||||
|
* CONT(1) : Continious measurement (Acq data, calc, then Acq data ..)\n
|
||||||
|
* TRIGG(2): Measurements are triggered from plc or over asyn and is only done once (untill next trigger)\n
|
||||||
|
* \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n
|
||||||
|
* \param[in] mode Mode CONT(1) or TRIGG(2)\n
|
||||||
|
*
|
||||||
|
* \return 0 if success or otherwise an error code.\n
|
||||||
|
*/
|
||||||
|
int modeFFT(int fftIndex, FFT_MODE mode);
|
||||||
|
|
||||||
|
/** \brief Trigger FFT object\n
|
||||||
|
*
|
||||||
|
* If in triggered mode a new measurment cycle is initiated (fft will be cleared first).\n
|
||||||
|
* \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n
|
||||||
|
*
|
||||||
|
* \return 0 if success or otherwise an error code.\n
|
||||||
|
*/
|
||||||
|
int triggFFT(int fftIndex);
|
||||||
|
|
||||||
|
/** \brief Get status of FFT object
|
||||||
|
*
|
||||||
|
* The FFT object can be in different states:\n
|
||||||
|
* NO_STAT(0): Invalid state (something is most likely wrong)\n
|
||||||
|
* IDLE(1) : Waiting for trigger in triggered mode\n
|
||||||
|
* ACQ(2) : Acquiring data (filling data buffer)\n
|
||||||
|
* CALC(3) : Calculating FFT results\n
|
||||||
|
* \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n
|
||||||
|
*
|
||||||
|
* \return Status of fft (if index is out of range NO_STAT will be returned).\n
|
||||||
|
*/
|
||||||
|
FFT_STATUS statFFT(int fftIndex);
|
||||||
|
|
||||||
|
/** \brief Link data to _all_ fft objects
|
||||||
|
*
|
||||||
|
* This tells the FFT lib to connect to ecmc to find it's data source.\n
|
||||||
|
* This function should be called just before entering realtime since then all\n
|
||||||
|
* data sources in ecmc will be definded (plc sources are compiled just before runtime\n
|
||||||
|
* so are only fist accesible now).\n
|
||||||
|
* \return 0 if success or otherwise an error code.\n
|
||||||
|
*/
|
||||||
|
int linkDataToFFTs();
|
||||||
|
|
||||||
|
/** \brief Deletes all created fft objects\n
|
||||||
|
*
|
||||||
|
* Should be called when destructs.\n
|
||||||
|
*/
|
||||||
|
|
||||||
|
void deleteAllFFTs();
|
||||||
|
|
||||||
|
# ifdef __cplusplus
|
||||||
|
}
|
||||||
|
# endif // ifdef __cplusplus
|
||||||
|
|
||||||
|
#endif /* ECMC_FFT_WRAP_H_ */
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
/*************************************************************************\
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* ecmcPluginExample.cpp
|
||||||
|
*
|
||||||
|
* Created on: Mar 21, 2020
|
||||||
|
* Author: anderssandstrom
|
||||||
|
*
|
||||||
|
\*************************************************************************/
|
||||||
|
|
||||||
|
// Needed to get headers in ecmc right...
|
||||||
|
#define ECMC_IS_PLUGIN
|
||||||
|
#define ECMC_EXAMPLE_PLUGIN_VERSION 2
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "ecmcPluginDefs.h"
|
||||||
|
#include "ecmcFFTDefs.h"
|
||||||
|
#include "ecmcFFTWrap.h"
|
||||||
|
|
||||||
|
static int lastEcmcError = 0;
|
||||||
|
static char* lastConfStr = 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 fftConstruct(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 createFFT(configStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Optional function.
|
||||||
|
* Will be called once at unload.
|
||||||
|
**/
|
||||||
|
void fftDestruct(void)
|
||||||
|
{
|
||||||
|
deleteAllFFTs();
|
||||||
|
if(lastConfStr){
|
||||||
|
free(lastConfStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Optional function.
|
||||||
|
* Will be called each realtime cycle if definded
|
||||||
|
* ecmcError: Error code of ecmc. Makes it posible for
|
||||||
|
* this plugin to react on ecmc errors
|
||||||
|
* Return value other than 0 will be considered to be an error code in ecmc.
|
||||||
|
**/
|
||||||
|
int fftRealtime(int ecmcError)
|
||||||
|
{
|
||||||
|
lastEcmcError = ecmcError;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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 fftEnterRT(){
|
||||||
|
return linkDataToFFTs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Optional function.
|
||||||
|
* Will be called once just before leaving realtime mode
|
||||||
|
* Return value other than 0 will be considered error.
|
||||||
|
**/
|
||||||
|
int fftExitRT(void){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plc function for clear of buffers
|
||||||
|
double fft_clear(double index) {
|
||||||
|
return (double)clearFFT((int)index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plc function for enable
|
||||||
|
double fft_enable(double index, double enable) {
|
||||||
|
return (double)enableFFT((int)index, (int)enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plc function for trigg new measurement (will clear buffers)
|
||||||
|
double fft_trigg(double index) {
|
||||||
|
return (double)triggFFT((int)index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plc function for enable
|
||||||
|
double fft_mode(double index, double mode) {
|
||||||
|
return (double)modeFFT((int)index, (FFT_MODE)((int)mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plc function for enable
|
||||||
|
double fft_stat(double index) {
|
||||||
|
return (double)statFFT((int)index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register data for plugin so ecmc know what to use
|
||||||
|
struct ecmcPluginData pluginDataDef = {
|
||||||
|
// Allways use ECMC_PLUG_VERSION_MAGIC
|
||||||
|
.ifVersion = ECMC_PLUG_VERSION_MAGIC,
|
||||||
|
// Name
|
||||||
|
.name = "ecmcPlugin_FFT",
|
||||||
|
// Description
|
||||||
|
.desc = "FFT 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> : Sets source variable for FFT (example: ec0.s1.AI_1).\n"
|
||||||
|
" "ECMC_PLUGIN_NFFT_OPTION_CMD"<nfft> : Data points to collect, default = 4096.\n"
|
||||||
|
" "ECMC_PLUGIN_SCALE_OPTION_CMD"scalefactor : Apply scale to source data, default = 1.0.\n"
|
||||||
|
" "ECMC_PLUGIN_RM_DC_OPTION_CMD"<1/0> : Remove DC offset of input data (SOURCE), default = disabled.\n"
|
||||||
|
" "ECMC_PLUGIN_RM_LIN_OPTION_CMD"<1/0> : Remove linear component in data (SOURCE) by least square, default = disabled.\n"
|
||||||
|
" "ECMC_PLUGIN_ENABLE_OPTION_CMD"<1/0> : Enable data acq. and calcs (can be controlled over asyn), default = disabled.\n"
|
||||||
|
" "ECMC_PLUGIN_MODE_OPTION_CMD"<CONT/TRIGG> : Continious or triggered mode, defaults to TRIGG\n"
|
||||||
|
" "ECMC_PLUGIN_RATE_OPTION_CMD"<rate in hz> : fft data sample rate in hz (must be lower than ecmc rate and (ecmc_rate/fft_rate)=integer), default = ecmc rate."
|
||||||
|
,
|
||||||
|
// Plugin version
|
||||||
|
.version = ECMC_EXAMPLE_PLUGIN_VERSION,
|
||||||
|
// Optional construct func, called once at load. NULL if not definded.
|
||||||
|
.constructFnc = fftConstruct,
|
||||||
|
// Optional destruct func, called once at unload. NULL if not definded.
|
||||||
|
.destructFnc = fftDestruct,
|
||||||
|
// Optional func that will be called each rt cycle. NULL if not definded.
|
||||||
|
.realtimeFnc = fftRealtime,
|
||||||
|
// Optional func that will be called once just before enter realtime mode
|
||||||
|
.realtimeEnterFnc = fftEnterRT,
|
||||||
|
// Optional func that will be called once just before exit realtime mode
|
||||||
|
.realtimeExitFnc = fftExitRT,
|
||||||
|
// PLC funcs
|
||||||
|
.funcs[0] =
|
||||||
|
{ /*----fft_clear----*/
|
||||||
|
// Function name (this is the name you use in ecmc plc-code)
|
||||||
|
.funcName = "fft_clear",
|
||||||
|
// Function description
|
||||||
|
.funcDesc = "double fft_clear(index) : Clear/reset fft[index].",
|
||||||
|
/**
|
||||||
|
* 7 different prototypes allowed (only doubles since reg in plc).
|
||||||
|
* Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||||
|
**/
|
||||||
|
.funcArg0 = NULL,
|
||||||
|
.funcArg1 = fft_clear,
|
||||||
|
.funcArg2 = NULL,
|
||||||
|
.funcArg3 = NULL,
|
||||||
|
.funcArg4 = NULL,
|
||||||
|
.funcArg5 = NULL,
|
||||||
|
.funcArg6 = NULL,
|
||||||
|
.funcArg7 = NULL,
|
||||||
|
.funcArg8 = NULL,
|
||||||
|
.funcArg9 = NULL,
|
||||||
|
.funcArg10 = NULL,
|
||||||
|
.funcGenericObj = NULL,
|
||||||
|
},
|
||||||
|
.funcs[1] =
|
||||||
|
{ /*----fft_enable----*/
|
||||||
|
// Function name (this is the name you use in ecmc plc-code)
|
||||||
|
.funcName = "fft_enable",
|
||||||
|
// Function description
|
||||||
|
.funcDesc = "double fft_enable(index, enable) : Set enable for fft[index].",
|
||||||
|
/**
|
||||||
|
* 7 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 = fft_enable,
|
||||||
|
.funcArg3 = NULL,
|
||||||
|
.funcArg4 = NULL,
|
||||||
|
.funcArg5 = NULL,
|
||||||
|
.funcArg6 = NULL,
|
||||||
|
.funcArg7 = NULL,
|
||||||
|
.funcArg8 = NULL,
|
||||||
|
.funcArg9 = NULL,
|
||||||
|
.funcArg10 = NULL,
|
||||||
|
.funcGenericObj = NULL,
|
||||||
|
},
|
||||||
|
.funcs[2] =
|
||||||
|
{ /*----fft_trigg----*/
|
||||||
|
// Function name (this is the name you use in ecmc plc-code)
|
||||||
|
.funcName = "fft_trigg",
|
||||||
|
// Function description
|
||||||
|
.funcDesc = "double fft_trigg(index) : Trigg new measurement for fft[index]. Will clear buffers.",
|
||||||
|
/**
|
||||||
|
* 7 different prototypes allowed (only doubles since reg in plc).
|
||||||
|
* Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||||
|
**/
|
||||||
|
.funcArg0 = NULL,
|
||||||
|
.funcArg1 = fft_trigg,
|
||||||
|
.funcArg2 = NULL,
|
||||||
|
.funcArg3 = NULL,
|
||||||
|
.funcArg4 = NULL,
|
||||||
|
.funcArg5 = NULL,
|
||||||
|
.funcArg6 = NULL,
|
||||||
|
.funcArg7 = NULL,
|
||||||
|
.funcArg8 = NULL,
|
||||||
|
.funcArg9 = NULL,
|
||||||
|
.funcArg10 = NULL,
|
||||||
|
.funcGenericObj = NULL,
|
||||||
|
},
|
||||||
|
.funcs[3] =
|
||||||
|
{ /*----fft_mode----*/
|
||||||
|
// Function name (this is the name you use in ecmc plc-code)
|
||||||
|
.funcName = "fft_mode",
|
||||||
|
// Function description
|
||||||
|
.funcDesc = "double fft_mode(index, mode) : Set mode Cont(1)/Trigg(2) for fft[index].",
|
||||||
|
/**
|
||||||
|
* 7 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 = fft_mode,
|
||||||
|
.funcArg3 = NULL,
|
||||||
|
.funcArg4 = NULL,
|
||||||
|
.funcArg5 = NULL,
|
||||||
|
.funcArg6 = NULL,
|
||||||
|
.funcArg7 = NULL,
|
||||||
|
.funcArg8 = NULL,
|
||||||
|
.funcArg9 = NULL,
|
||||||
|
.funcArg10 = NULL,
|
||||||
|
.funcGenericObj = NULL,
|
||||||
|
},
|
||||||
|
.funcs[4] =
|
||||||
|
{ /*----fft_stat----*/
|
||||||
|
// Function name (this is the name you use in ecmc plc-code)
|
||||||
|
.funcName = "fft_stat",
|
||||||
|
// Function description
|
||||||
|
.funcDesc = "double fft_stat(index) : Get status of fft (NO_STAT, IDLE, ACQ, CALC) for fft[index].",
|
||||||
|
/**
|
||||||
|
* 7 different prototypes allowed (only doubles since reg in plc).
|
||||||
|
* Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||||
|
**/
|
||||||
|
.funcArg0 = NULL,
|
||||||
|
.funcArg1 = fft_stat,
|
||||||
|
.funcArg2 = NULL,
|
||||||
|
.funcArg3 = NULL,
|
||||||
|
.funcArg4 = NULL,
|
||||||
|
.funcArg5 = NULL,
|
||||||
|
.funcArg6 = NULL,
|
||||||
|
.funcArg7 = NULL,
|
||||||
|
.funcArg8 = NULL,
|
||||||
|
.funcArg9 = NULL,
|
||||||
|
.funcArg10 = NULL,
|
||||||
|
.funcGenericObj = NULL,
|
||||||
|
},
|
||||||
|
.funcs[5] = {0}, // last element set all to zero..
|
||||||
|
// PLC consts
|
||||||
|
/* CONTINIOUS MODE = 1 */
|
||||||
|
.consts[0] = {
|
||||||
|
.constName = "fft_CONT",
|
||||||
|
.constDesc = "FFT Mode: Continious",
|
||||||
|
.constValue = CONT
|
||||||
|
},
|
||||||
|
/* TRIGGERED MODE = 2 */
|
||||||
|
.consts[1] = {
|
||||||
|
.constName = "fft_TRIGG",
|
||||||
|
.constDesc = "FFT Mode :Triggered",
|
||||||
|
.constValue = TRIGG
|
||||||
|
},
|
||||||
|
/* TRIGGERED MODE = 2 */
|
||||||
|
.consts[2] = {
|
||||||
|
.constName = "fft_NO_STAT",
|
||||||
|
.constDesc = "FFT Status: Invalid state",
|
||||||
|
.constValue = NO_STAT,
|
||||||
|
},
|
||||||
|
/* TRIGGERED MODE = 2 */
|
||||||
|
.consts[3] = {
|
||||||
|
.constName = "fft_IDLE",
|
||||||
|
.constDesc = "FFT Status: Idle state (waiting for trigger)",
|
||||||
|
.constValue = IDLE
|
||||||
|
},
|
||||||
|
/* TRIGGERED MODE = 2 */
|
||||||
|
.consts[4] = {
|
||||||
|
.constName = "fft_ACQ",
|
||||||
|
.constDesc = "FFT Status: Acquiring data",
|
||||||
|
.constValue = ACQ
|
||||||
|
},
|
||||||
|
/* TRIGGERED MODE = 2 */
|
||||||
|
.consts[5] = {
|
||||||
|
.constName = "fft_CALC",
|
||||||
|
.constDesc = "FFT Status: Calculating result",
|
||||||
|
.constValue = CALC
|
||||||
|
},
|
||||||
|
.consts[6] = {0}, // last element set all to zero..
|
||||||
|
};
|
||||||
|
|
||||||
|
ecmc_plugin_register(pluginDataDef);
|
||||||
|
|
||||||
|
# ifdef __cplusplus
|
||||||
|
}
|
||||||
|
# endif // ifdef __cplusplus
|
||||||
0
iocsh/.keep
Normal file
0
iocsh/.keep
Normal file
7
patch/Site/HISTORY.md
Normal file
7
patch/Site/HISTORY.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# E3_MODULE_VERSION-what_ever_filename.p0.patch
|
||||||
|
|
||||||
|
Generic Description.....
|
||||||
|
|
||||||
|
* created by Jeong Han Lee, han.lee@esss.se
|
||||||
|
* related URL or reference https://github.com/icshwi
|
||||||
|
* Tuesday, February 13 13:24:57 CET 2018
|
||||||
22
patch/Site/README.md
Normal file
22
patch/Site/README.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Site Specific EPICS Module Patch Files
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
The changes were tested in local environemnt, and commits to the forked repository and do pull request to the epics community module repository.
|
||||||
|
|
||||||
|
* Check the original HASH, and your own master
|
||||||
|
* feb8856 : The original HASH
|
||||||
|
* master : Changed
|
||||||
|
|
||||||
|
|
||||||
|
## How to create a p0 patch file between commits
|
||||||
|
|
||||||
|
|
||||||
|
* Show what the difference between commits
|
||||||
|
|
||||||
|
|
||||||
|
* Create p0 patch
|
||||||
|
|
||||||
|
```
|
||||||
|
$git diff feb8856 master --no-prefix > ../patch/Site/E3_MODULE_VERSION-what_ever_filename.p0.patch
|
||||||
|
```
|
||||||
|
|
||||||
0
template/.keep
Normal file
0
template/.keep
Normal file
Reference in New Issue
Block a user