Start with motion plugin as base (just minor cleanup and renaming made) WIP
This commit is contained in:
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
*~
|
||||
*-dev
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
core.*
|
||||
#*
|
||||
.#*
|
||||
\#*
|
||||
*.local
|
||||
\#*
|
||||
.cvsignore
|
||||
*_old/
|
||||
*PVs.list
|
||||
*-loc/*.Makefile
|
||||
ecmc_plugin_motion/*.Makefile
|
||||
*__*
|
||||
O*
|
||||
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"string_view": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"iosfwd": "cpp"
|
||||
}
|
||||
}
|
||||
258
Db/ecmcPluginMotion.template
Normal file
258
Db/ecmcPluginMotion.template
Normal file
@@ -0,0 +1,258 @@
|
||||
# Act pos
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-PosAct-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Pos Act")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynFloat64ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.actpos_arr")
|
||||
field(FTVL, "DOUBLE")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
field(EGU, "${RAW_EGU= }")
|
||||
}
|
||||
|
||||
# Set pos
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-PosSet-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Pos Set")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynFloat64ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.setpos_arr")
|
||||
field(FTVL, "DOUBLE")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
field(EGU, "${RAW_EGU= }")
|
||||
}
|
||||
|
||||
# Position Error
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-PosErr-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Pos Error (diff)")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynFloat64ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.diffpos_arr")
|
||||
field(FTVL, "DOUBLE")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
field(EGU, "${RAW_EGU= }")
|
||||
}
|
||||
|
||||
# X axis time (reltive within buffer)
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-Time-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Rel. time within buffer")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynFloat64ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.x_arr")
|
||||
field(FTVL, "DOUBLE")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Axis Enable
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-Ena-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Enable")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.enable_arr")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Axis Enabled
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-EnaAct-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Enabled")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.enabled_arr")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Axis Busy
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-Bsy-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Busy")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.busy_arr")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Axis Execute
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-Exe-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Execute")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.execute_arr")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Axis Traj source
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-TrjSrc-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Traj source")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.trajsrc_arr")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Axis Enc source
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-EncSrc-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Enc source")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.encsrc_arr")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Axis At target
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-AtTrg-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "At target")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.attarget_arr")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Axis Error Id
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-ErrId-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Error Id")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt32ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.error_arr")
|
||||
field(FTVL, "LONG")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# Axis Error Id
|
||||
record(waveform,"$(P)Plg-Mtn${INDEX}-Stat-Arr"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Status wd")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt32ArrayIn")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.statuswd_arr")
|
||||
field(FTVL, "LONG")
|
||||
field(NELM, "$(NELM)")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
record(bo,"$(P)Plg-Mtn${INDEX}-EnaCmd-RB"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(DESC, "Plg Enable")
|
||||
field(DTYP,"asynInt32")
|
||||
field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.enable")
|
||||
field(ZNAM,"FALSE")
|
||||
field(ONAM,"TRUE")
|
||||
field(DOL, "0")
|
||||
field(VAL, "0")
|
||||
}
|
||||
|
||||
record(ao,"$(P)Plg-Mtn${INDEX}-AxCmd-RB"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(DESC, "Axis")
|
||||
field(DTYP,"asynInt32")
|
||||
field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.axis_id")
|
||||
field(DOL, "0")
|
||||
field(VAL, "1")
|
||||
}
|
||||
|
||||
record(ai,"$(P)Plg-Mtn${INDEX}-SmpHz-RB"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(DESC, "Sample rate")
|
||||
field(DTYP,"asynFloat64")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.samplerate")
|
||||
field(VAL, "1")
|
||||
field(EGU, "Hz")
|
||||
field(SCAN, "I/O Intr")
|
||||
}
|
||||
|
||||
record(ai,"$(P)Plg-Mtn${INDEX}-BuffSze"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(DESC, "Buffer Size")
|
||||
field(DTYP,"asynInt32")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.buff_size")
|
||||
field(VAL, "1")
|
||||
}
|
||||
|
||||
record(ai,"$(P)Plg-Mtn${INDEX}-ElmCnt"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(DESC, "Elements in buffer count")
|
||||
field(DTYP,"asynInt32")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.elem_count")
|
||||
field(VAL, "1")
|
||||
}
|
||||
|
||||
record(bo,"$(P)Plg-Mtn${INDEX}-TrgCmd-RB"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(DESC, "Trigg command")
|
||||
field(DTYP,"asynInt32")
|
||||
field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.trigg")
|
||||
field(ZNAM,"IDLE")
|
||||
field(ONAM,"TRIGG")
|
||||
field(VAL, "0")
|
||||
field(HIGH, 0.001)
|
||||
}
|
||||
|
||||
record(longout,"$(P)Plg-Mtn${INDEX}-Mde-RB"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(DESC, "Mode selection")
|
||||
field(PINI, "1")
|
||||
field(TSE, "0")
|
||||
field(DTYP, "asynInt32")
|
||||
field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.mode")
|
||||
field(SCAN, "Passive")
|
||||
}
|
||||
|
||||
record(longout,"$(P)Plg-Mtn${INDEX}-Cmd-RB"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(DESC, "Command")
|
||||
field(PINI, "1")
|
||||
field(TSE, "0")
|
||||
field(DTYP, "asynInt32")
|
||||
field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.cmd")
|
||||
field(SCAN, "Passive")
|
||||
}
|
||||
|
||||
record(longin,"$(P)Plg-Mtn${INDEX}-Stat"){
|
||||
info(asyn:READBACK,"1")
|
||||
field(DESC, "Status")
|
||||
field(PINI, "1")
|
||||
field(TSE, "0")
|
||||
field(DTYP, "asynInt32")
|
||||
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.status")
|
||||
field(SCAN, "I/O Intr")
|
||||
}
|
||||
46
GNUmakefile
Normal file
46
GNUmakefile
Normal file
@@ -0,0 +1,46 @@
|
||||
include /ioc/tools/driver.makefile
|
||||
|
||||
MODULE = ecmc_plugin_safety
|
||||
|
||||
BUILDCLASSES = Linux
|
||||
ARCH_FILTER = deb10%
|
||||
|
||||
# Run 7.0.6 for now
|
||||
EXCLUDE_VERSIONS+=3 7.0.5 7.0.6
|
||||
|
||||
IGNORE_MODULES += asynMotor
|
||||
IGNORE_MODULES += motorBase
|
||||
|
||||
USR_CXXFLAGS += -std=c++17
|
||||
OPT_CXXFLAGS_YES = -O3
|
||||
|
||||
# dependencies
|
||||
# ECmasterECMC_VERSION = v1.1.0
|
||||
# motorECMC_VERSION = 7.0.7-ESS
|
||||
ecmc_VERSION = v9.0.1_RC4
|
||||
|
||||
################################################################################
|
||||
# THIS RELATES TO THE EtherCAT MASTER LIBRARY
|
||||
# IT IS OF PARAMOUNT IMPORTANCE TO LOAD THE PROPER KERNEL MODULE
|
||||
# ################################################################################
|
||||
USR_LDFLAGS += -lethercat
|
||||
|
||||
EC_MASTER_LIB = ${EPICS_MODULES}/ECmasterECMC/${ECmasterECMC_VERSION}/R${EPICSVERSION}/lib/${T_A}
|
||||
USR_LDFLAGS += -Wl,-rpath=${EC_MASTER_LIB}
|
||||
USR_LDFLAGS += -L ${EC_MASTER_LIB}
|
||||
|
||||
BASE_DIR = .
|
||||
SRC_DIR = $(BASE_DIR)/src
|
||||
DB_DIR = $(BASE_DIR)/Db
|
||||
|
||||
SOURCES += $(SRC_DIR)/ecmcPluginSafety.c
|
||||
SOURCES += $(SRC_DIR)/ecmcSafetyPlgWrap.cpp
|
||||
SOURCES += $(SRC_DIR)/ecmcSafetyPlg.cpp
|
||||
|
||||
#SOURCES += $(foreach d,${SRC_DIR}, $(wildcard $d/*.c) $(wildcard $d/*.cpp))
|
||||
HEADERS += $(foreach d,${SRC_DIR}, $(wildcard $d/*.h))
|
||||
DBDS += $(foreach d,${SRC_DIR}, $(wildcard $d/*.dbd))
|
||||
SCRIPTS += $(BASE_DIR)/startup.cmd
|
||||
SCRIPTS += $(BASE_DIR)/addMotionObj.cmd
|
||||
TEMPLATES += $(wildcard $(DB_DIR)/*.template)
|
||||
|
||||
11
README.md
Normal file
11
README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
ecmc_plugin_safety
|
||||
======
|
||||
Plugin designed for interfacing safety plc:s
|
||||
|
||||
IMPORTANT: this plugin does not offer any safety functionality. Its just a standard interface to an external safety systtem.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
||||
40
configure/CONFIG_MODULE
Normal file
40
configure/CONFIG_MODULE
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
EPICS_MODULE_NAME:=ecmc_plugin_motion
|
||||
|
||||
EPICS_MODULE_TAG:=master
|
||||
#
|
||||
E3_MODULE_VERSION:=master
|
||||
|
||||
# DEPENDENT MODULE VERSION
|
||||
# For Example,
|
||||
|
||||
ECMC_DEP_VERSION:=v9.0.1_RC1
|
||||
ASYN_DEP_VERSION:=4.41.0
|
||||
EXPRTK_DEP_VERSION:=addCompFunc
|
||||
MOTOR_DEP_VERSION:=7.0.6
|
||||
RUCKIG_DEP_VERSION:=1.0.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_motion
|
||||
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.5
|
||||
|
||||
E3_REQUIRE_NAME:=require
|
||||
E3_REQUIRE_VERSION:=3.4.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
|
||||
BIN
docs/ecmcPLC5HzFFT.png
Normal file
BIN
docs/ecmcPLC5HzFFT.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
docs/ecmcPLC5HzRAW.png
Normal file
BIN
docs/ecmcPLC5HzRAW.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
BIN
docs/gui/ecmcArrayGui.png
Normal file
BIN
docs/gui/ecmcArrayGui.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
BIN
docs/gui/ecmcFFTGui.png
Normal file
BIN
docs/gui/ecmcFFTGui.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
BIN
docs/gui/ecmcFFTMainGui.png
Normal file
BIN
docs/gui/ecmcFFTMainGui.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
0
iocsh/.keep
Normal file
0
iocsh/.keep
Normal file
40
iocsh/addSafetyAxis.cmd
Normal file
40
iocsh/addSafetyAxis.cmd
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
#==============================================================================
|
||||
# addMotionObj.cmd
|
||||
#-------------- Information:
|
||||
#- Description: ecmc_plugin_motion startup.cmd
|
||||
#-
|
||||
#- by Anders Sandström, Paul Scherrer Institute, 2023
|
||||
#- email: anders.sandstroem@psi.ch
|
||||
#-
|
||||
#-###############################################################################
|
||||
#-
|
||||
#- Arguments
|
||||
#- [mandatory]
|
||||
#- PLUGIN_ID = Plugin instansiation index, must be unique for each call
|
||||
#-
|
||||
#- [optional]
|
||||
#- AX = Axis id, default 1
|
||||
#- BUFF_SIZE = Buffer size, default 1000
|
||||
#- DBG = Debug mode, default 1
|
||||
#- ENA = Enable operation, default 1
|
||||
#- REPORT = Printout plugin details, default 1
|
||||
|
||||
#################################################################################
|
||||
|
||||
#- Load plugin: MOTION
|
||||
|
||||
#- Note: ECMC_PLG_MOTION_OBJ_INDEX is the index of motion object in motion plugin and not PLUGIN_ID.
|
||||
#- First loaded object will therefore have index
|
||||
epicsEnvSet(ECMC_PLG_MOTION_OBJ_INDEX,${ECMC_PLG_MOTION_OBJ_INDEX=0})
|
||||
|
||||
# Might need differet paths for PSI and ESS.. must check
|
||||
epicsEnvSet(ECMC_PLUGIN_FILNAME,"$(ecmc_plugin_motion_DIR)/lib/${EPICS_HOST_ARCH=linux-x86_64}/libecmc_plugin_motion.so")
|
||||
epicsEnvSet(ECMC_PLUGIN_CONFIG,"AXIS=${AX};BUFFER_SIZE=${BUFF_SIZE};DBG_PRINT=${DBG=1};ENABLE=${ENA=1};")
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}loadPlugin.cmd, "PLUGIN_ID=${PLUGIN_ID},FILE=${ECMC_PLUGIN_FILNAME},CONFIG='${ECMC_PLUGIN_CONFIG}', REPORT=${REPORT=1}"
|
||||
|
||||
dbLoadRecords(${ecmc_plugin_motion_TEMPLATES}ecmcPluginMotion.template,"P=$(IOC):,INDEX=${ECMC_PLG_MOTION_OBJ_INDEX=0},NELM=${BUFF_SIZE=1000}")
|
||||
|
||||
#- Increase of index (need to keep track in order to load correct db)
|
||||
ecmcEpicsEnvSetCalc("ECMC_PLG_MOTION_OBJ_INDEX" ,${ECMC_PLG_MOTION_OBJ_INDEX=0}+1)
|
||||
|
||||
93
iocsh/cfg/el7031.ax
Normal file
93
iocsh/cfg/el7031.ax
Normal file
@@ -0,0 +1,93 @@
|
||||
#General
|
||||
epicsEnvSet("ECMC_MOTOR_NAME", "Axis1")
|
||||
epicsEnvSet("ECMC_R", "Axis1-")
|
||||
epicsEnvSet("ECMC_AXIS_NO", "1")
|
||||
epicsEnvSet("ECMC_DESC", "Test EL7037")
|
||||
epicsEnvSet("ECMC_EGU", "deg") # Motor Record Unit
|
||||
epicsEnvSet("ECMC_PREC", "3") # Motor Record Precision
|
||||
epicsEnvSet("ECMC_AXISCONFIG", "") # Extra parameters to driver
|
||||
epicsEnvSet("ECMC_EC_AXIS_HEALTH", "") # Entry for axis health output (example: ec0.s1.binaryOutput01.0)
|
||||
epicsEnvSet("ECMC_MOD_RANGE" , "0") # Modulo range (traj setpoints and encoder values will be in range 0..ECMC_MOD_RANGE)
|
||||
epicsEnvSet("ECMC_MOD_TYPE", "0") # For positioning and MOD_RANGE is larger than 0: 0 = Normal, 1 = Always Fwd, 2 = Always Bwd, 3 = Closest Distance
|
||||
|
||||
#Encoder
|
||||
epicsEnvSet("ECMC_ENC_SCALE_NUM" "360")
|
||||
epicsEnvSet("ECMC_ENC_SCALE_DENOM" "12800")
|
||||
epicsEnvSet("ECMC_ENC_TYPE" "0") # Type: 0=Incremental, 1=Absolute
|
||||
epicsEnvSet("ECMC_ENC_BITS" "16") # Total bit count of encoder raw data
|
||||
epicsEnvSet("ECMC_ENC_ABS_BITS", "0") # Absolute bit count (for absolute encoders) always least significant part of ECMC_ENC_BITS
|
||||
epicsEnvSet("ECMC_ENC_ABS_OFFSET" "0") # Encoder offset in eng units (for absolute encoders)
|
||||
epicsEnvSet("ECMC_EC_ENC_ACTPOS", "ec0.s$(DRV_ID).positionActual01") # Ethercat entry for actual position input (encoder)
|
||||
epicsEnvSet("ECMC_EC_ENC_RESET", "") # Reset (if no encoder reset bit then leave empty)
|
||||
epicsEnvSet("ECMC_EC_ENC_ALARM_0", "") # Error 0 (if no encoder error bit then leave empty)
|
||||
epicsEnvSet("ECMC_EC_ENC_ALARM_1", "") # Error 1 (if no encoder error bit then leave empty)
|
||||
epicsEnvSet("ECMC_EC_ENC_ALARM_2", "") # Error 2 (if no encoder error bit then leave empty)
|
||||
epicsEnvSet("ECMC_EC_ENC_WARNING", "") # Warning (if no encoder warning bit then leave empty)
|
||||
|
||||
#Drive
|
||||
epicsEnvSet("ECMC_DRV_TYPE" "0") # Stepper: 0. DS402: 1 (DS402 = servos and advanced stepper drives)
|
||||
epicsEnvSet("ECMC_DRV_SCALE_NUM" "3600") # Fastest speed in engineering units
|
||||
epicsEnvSet("ECMC_DRV_SCALE_DENOM" "32768") # I/O range for ECMC_EC_ALIAS_DRV_VELO_SET
|
||||
epicsEnvSet("ECMC_EC_DRV_CONTROL", "ec0.s$(DRV_ID).driveControl01.0") # Ethercat entry for control word or bit output
|
||||
epicsEnvSet("ECMC_EC_DRV_STATUS", "ec0.s$(DRV_ID).driveStatus01.1") # Ethercat entry for status word or bit input
|
||||
epicsEnvSet("ECMC_EC_DRV_VELOCITY", "ec0.s$(DRV_ID).velocitySetpoint01") # Ethercat entry for velocity setpoint output
|
||||
epicsEnvSet("ECMC_EC_DRV_REDUCE_TORQUE", "ec0.s$(DRV_ID).driveControl01.2") # Ethercat entry for reduce torque output
|
||||
epicsEnvSet("ECMC_EC_DRV_BRAKE", "ec0.s$(DO_ID).binaryOutput01.0") # Ethercat entry for brake output
|
||||
epicsEnvSet("ECMC_DRV_BRAKE_OPEN_DLY_TIME", "1000") # Brake timing parameter in cycles (default 1kHz)
|
||||
epicsEnvSet("ECMC_DRV_BRAKE_CLOSE_AHEAD_TIME", "2000") # Brake timing parameter in cycles (default 1kHz)
|
||||
epicsEnvSet("ECMC_EC_DRV_RESET", "ec0.s$(DRV_ID).driveControl01.1") # Reset
|
||||
epicsEnvSet("ECMC_EC_DRV_ALARM_0", "ec0.s$(DRV_ID).driveStatus01.3") # Error
|
||||
epicsEnvSet("ECMC_EC_DRV_ALARM_1", "ec0.s$(DRV_ID).driveStatus01.7") # Stall
|
||||
epicsEnvSet("ECMC_EC_DRV_ALARM_2", "ec0.s$(DRV_ID).driveStatus01.14") # Sync error
|
||||
epicsEnvSet("ECMC_EC_DRV_WARNING", "ec0.s$(DRV_ID).driveStatus01.2") # Warning
|
||||
|
||||
#Trajectory
|
||||
epicsEnvSet("ECMC_VELO", "360.0")
|
||||
epicsEnvSet("ECMC_JOG_VEL", "360.0")
|
||||
epicsEnvSet("ECMC_JAR", "0.0") # JAR defaults to VELO/ACCL
|
||||
epicsEnvSet("ECMC_ACCS_EGU_PER_S2", "360")
|
||||
epicsEnvSet("ECMC_EMERG_DECEL", "1000") # Emergency deceleration
|
||||
|
||||
#Homing
|
||||
epicsEnvSet("ECMC_HOME_PROC", "1")
|
||||
epicsEnvSet("ECMC_HOME_POS", "0.0")
|
||||
epicsEnvSet("ECMC_HOME_VEL_TO", "5")
|
||||
epicsEnvSet("ECMC_HOME_VEL_FRM", "4")
|
||||
epicsEnvSet("ECMC_HOME_ACC", "21")
|
||||
epicsEnvSet("ECMC_HOME_DEC", "100")
|
||||
epicsEnvSet("ECMC_HOME_POS_MOVE_ENA", "0") # Enable move to position after successfull homing
|
||||
epicsEnvSet("ECMC_HOME_POS_MOVE_TARG_POS","0") # Target position to go to after successfull homing
|
||||
|
||||
#Controller
|
||||
epicsEnvSet("ECMC_CNTRL_KP", "5.0")
|
||||
epicsEnvSet("ECMC_CNTRL_KI", "0.02")
|
||||
epicsEnvSet("ECMC_CNTRL_KD", "0.0")
|
||||
epicsEnvSet("ECMC_CNTRL_KFF", "1.0")
|
||||
|
||||
#Monitoring
|
||||
# Switches
|
||||
epicsEnvSet("ECMC_EC_MON_LOWLIM", "ec0.s$(DRV_ID).ONE.0") # Ethercat entry for low limit switch input
|
||||
epicsEnvSet("ECMC_EC_MON_HIGHLIM", "ec0.s$(DRV_ID).ONE.0") # Ethercat entry for high limit switch inpuit
|
||||
epicsEnvSet("ECMC_EC_MON_HOME_SWITCH", "ec0.s$(DRV_ID).ONE.0") # Ethercat entry for home switch input
|
||||
epicsEnvSet("ECMC_EC_MON_EXT_INTERLOCK", "ec0.s$(DRV_ID).ONE.0") # Ethercat entry for external interlock input
|
||||
|
||||
# Softlimits (disable with 0,0,0)
|
||||
epicsEnvSet("ECMC_SOFT_LOW_LIM", "$(SM_DLLM=0)")
|
||||
epicsEnvSet("ECMC_SOFT_HIGH_LIM", "$(SM_DHLM=0)")
|
||||
epicsEnvSet("ECMC_DXLM_ENABLE", "0")
|
||||
|
||||
# Position lag
|
||||
epicsEnvSet("ECMC_MON_LAG_MON_TOL", "5")
|
||||
epicsEnvSet("ECMC_MON_LAG_MON_TIME", "100")
|
||||
epicsEnvSet("ECMC_MON_LAG_MON_ENA", "0")
|
||||
|
||||
# At target
|
||||
epicsEnvSet("ECMC_MON_AT_TARGET_TOL", "0.1")
|
||||
epicsEnvSet("ECMC_MON_AT_TARGET_TIME", "100")
|
||||
epicsEnvSet("ECMC_MON_AT_TARGET_ENA", "1")
|
||||
|
||||
# Velocity
|
||||
epicsEnvSet("ECMC_MON_VELO_MAX", "21000.0")
|
||||
epicsEnvSet("ECMC_MON_VELO_MAX_TRAJ_TIME","100")
|
||||
epicsEnvSet("ECMC_MON_VELO_MAX_DRV_TIME", "200")
|
||||
epicsEnvSet("ECMC_MON_VELO_MAX_ENA", "0")
|
||||
9
iocsh/plc/plc_no_ec_fft_sin.plc
Normal file
9
iocsh/plc/plc_no_ec_fft_sin.plc
Normal file
@@ -0,0 +1,9 @@
|
||||
###############################################################################################
|
||||
# For help on syntax, variables and functions, please read the file: "plcSyntaxHelp.plc"
|
||||
#
|
||||
# PLC Functionality Demo:
|
||||
# No hardware related variables
|
||||
#
|
||||
|
||||
static.time:=ec_get_time()/1E9;
|
||||
static.sineval:=sin(2*pi*${FREQ=10}*static.time);
|
||||
345
iocsh/pvs.log
Normal file
345
iocsh/pvs.log
Normal file
@@ -0,0 +1,345 @@
|
||||
IOC_TEST:m0s001-Drv01-Cmd-RB
|
||||
IOC_TEST:m0s001-Drv01-Spd-RB
|
||||
IOC_TEST:m0s001-Enc01-PosAct
|
||||
IOC_TEST:m0s001-Enc01-LtchPosAct
|
||||
IOC_TEST:m0s001-Enc01-Cmd-RB
|
||||
IOC_TEST:m0s001-Enc01-PosCmd-RB
|
||||
IOC_TEST:Axis1-Vel-RB
|
||||
IOC_TEST:Axis1-Acc-RB
|
||||
IOC_TEST:Axis1-EncAct
|
||||
IOC_TEST:Axis1-CfgSREV-RB
|
||||
IOC_TEST:Axis1-CfgUREV-RB
|
||||
IOC_TEST:Axis1-CfgPMIN-RB
|
||||
IOC_TEST:Axis1-CfgPMAX-RB
|
||||
IOC_TEST:Axis1-CfgSPDB-RB
|
||||
IOC_TEST:Axis1-CfgRDBD-RB
|
||||
IOC_TEST:Axis1-CfgRDBD-Tim-RB
|
||||
IOC_TEST:Axis1-CfgPOSLAG-RB
|
||||
IOC_TEST:Axis1-CfgPOSLAG-Tim-RB
|
||||
IOC_TEST:Axis1-CfgDHLM-RB
|
||||
IOC_TEST:Axis1-CfgDLLM-RB
|
||||
IOC_TEST:Axis1-CfgVELO-RB
|
||||
IOC_TEST:Axis1-CfgVMAX-RB
|
||||
IOC_TEST:Axis1-CfgJVEL-RB
|
||||
IOC_TEST:Axis1-CfgACCS-RB
|
||||
IOC_TEST:Axis1-HomPos-RB
|
||||
IOC_TEST:Axis1-PosAct
|
||||
IOC_TEST:Axis1-VelAct
|
||||
IOC_TEST:Axis1-PosSet
|
||||
IOC_TEST:Axis1-PosErr
|
||||
IOC_TEST:Axis1-PLC-Err
|
||||
IOC_TEST:Plg-Mtn0-SmpHz-RB
|
||||
IOC_TEST:Plg-Mtn0-BuffSze
|
||||
IOC_TEST:Plg-Mtn0-ElmCnt
|
||||
IOC_TEST:MCU-AppMode
|
||||
IOC_TEST:MCU-ErrId
|
||||
IOC_TEST:MCU-ThdLatMin
|
||||
IOC_TEST:MCU-ThdLatMax
|
||||
IOC_TEST:MCU-ThdPrdMin
|
||||
IOC_TEST:MCU-ThdPrdMax
|
||||
IOC_TEST:MCU-ThdExeMin
|
||||
IOC_TEST:MCU-ThdExeMax
|
||||
IOC_TEST:MCU-ThdSndMin
|
||||
IOC_TEST:MCU-ThdSndMax
|
||||
IOC_TEST:m0s001-Drv01-WrnAlrm
|
||||
IOC_TEST:m0s001-Drv01-ErrAlrm
|
||||
IOC_TEST:m0s001-Drv01-StlAlrm
|
||||
IOC_TEST:m0s001-Drv01-SyncErrAlrm
|
||||
IOC_TEST:m0s001-Enc01-ExtLtchOK
|
||||
IOC_TEST:m0s001-Enc01-OpnCrctAlrm
|
||||
IOC_TEST:m0s001-Enc01-WrnAlrm
|
||||
IOC_TEST:m0s001-Enc01-SyncErrAlrm
|
||||
IOC_TEST:m0s001-Online
|
||||
IOC_TEST:m0s001-Operational
|
||||
IOC_TEST:m0s001-Alstate-Init
|
||||
IOC_TEST:m0s001-Alstate-Preop
|
||||
IOC_TEST:m0s001-Alstate-Safeop
|
||||
IOC_TEST:m0s001-Alstate-Op
|
||||
IOC_TEST:m0s002-BO01-RB
|
||||
IOC_TEST:m0s002-BO02-RB
|
||||
IOC_TEST:m0s002-BO03-RB
|
||||
IOC_TEST:m0s002-BO04-RB
|
||||
IOC_TEST:m0s002-BO05-RB
|
||||
IOC_TEST:m0s002-BO06-RB
|
||||
IOC_TEST:m0s002-BO07-RB
|
||||
IOC_TEST:m0s002-BO08-RB
|
||||
IOC_TEST:m0s002-BO09-RB
|
||||
IOC_TEST:m0s002-BO10-RB
|
||||
IOC_TEST:m0s002-BO11-RB
|
||||
IOC_TEST:m0s002-BO12-RB
|
||||
IOC_TEST:m0s002-BO13-RB
|
||||
IOC_TEST:m0s002-BO14-RB
|
||||
IOC_TEST:m0s002-BO15-RB
|
||||
IOC_TEST:m0s002-BO16-RB
|
||||
IOC_TEST:m0s002-BO01-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO01-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO01-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO01-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO02-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO02-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO02-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO02-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO03-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO03-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO03-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO03-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO04-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO04-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO04-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO04-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO05-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO05-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO05-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO05-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO06-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO06-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO06-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO06-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO07-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO07-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO07-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO07-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO08-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO08-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO08-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO08-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO09-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO09-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO09-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO09-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO10-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO10-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO10-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO10-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO11-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO11-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO11-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO11-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO12-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO12-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO12-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO12-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO13-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO13-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO13-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO13-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO14-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO14-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO14-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO14-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO15-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO15-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO15-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO15-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-BO16-OvrTmpAlrm
|
||||
IOC_TEST:m0s002-BO16-OpnLdAlrm
|
||||
IOC_TEST:m0s002-BO16-OvrCurrAlrm
|
||||
IOC_TEST:m0s002-BO16-ShrtCircAlrm
|
||||
IOC_TEST:m0s002-Online
|
||||
IOC_TEST:m0s002-Operational
|
||||
IOC_TEST:m0s002-Alstate-Init
|
||||
IOC_TEST:m0s002-Alstate-Preop
|
||||
IOC_TEST:m0s002-Alstate-Safeop
|
||||
IOC_TEST:m0s002-Alstate-Op
|
||||
IOC_TEST:Axis1-EnaCmd-RB
|
||||
IOC_TEST:Axis1-EnaAct
|
||||
IOC_TEST:Axis1-ExeCmd-RB
|
||||
IOC_TEST:Axis1-Busy
|
||||
IOC_TEST:Axis1-AtTarget
|
||||
IOC_TEST:Axis1-Moving
|
||||
IOC_TEST:Axis1-LimFwd
|
||||
IOC_TEST:Axis1-LimBwd
|
||||
IOC_TEST:Axis1-HomeSwitch
|
||||
IOC_TEST:Axis1-Homed
|
||||
IOC_TEST:Axis1-InRT
|
||||
IOC_TEST:Axis1-TrjSrcTyp-RB
|
||||
IOC_TEST:Axis1-EncSrcTyp-RB
|
||||
IOC_TEST:Axis1-CmdFrmPLCCmd-RB
|
||||
IOC_TEST:Axis1-SftLimFwdEna-RB
|
||||
IOC_TEST:Axis1-SftLimBwdEna-RB
|
||||
IOC_TEST:Axis1-PLC-EnaCmd-RB
|
||||
IOC_TEST:Axis1-PLC-FirstScan
|
||||
IOC_TEST:Axis1-Err
|
||||
IOC_TEST:Axis1-Wrn
|
||||
IOC_TEST:MCU-ThdRTPrioOK
|
||||
IOC_TEST:MCU-ThdMemLocked
|
||||
IOC_TEST:m0-LinkUp
|
||||
IOC_TEST:m0-AlStates-Init
|
||||
IOC_TEST:m0-AlStates-Preop
|
||||
IOC_TEST:m0-AlStates-Safeop
|
||||
IOC_TEST:m0-AlStates-Op
|
||||
IOC_TEST:m0-Dom-RedunActive
|
||||
IOC_TEST:m0-Dom-WC-Zero
|
||||
IOC_TEST:m0-Dom-WC-Incomplete
|
||||
IOC_TEST:m0-Dom-WC-Complete
|
||||
IOC_TEST:m0-Stat-OK
|
||||
REQMOD:raspberrypi-10406:exit
|
||||
REQMOD:raspberrypi-10406:MODULES
|
||||
REQMOD:raspberrypi-10406:VERSIONS
|
||||
REQMOD:raspberrypi-10406:MOD_VER
|
||||
IOC_TEST:Axis1-Arr-Stat
|
||||
IOC_TEST:Axis1-PLC-Expr-RB
|
||||
IOC_TEST:Plg-Mtn0-PosAct-Arr
|
||||
IOC_TEST:Plg-Mtn0-PosSet-Arr
|
||||
IOC_TEST:Plg-Mtn0-PosErr-Arr
|
||||
IOC_TEST:Plg-Mtn0-Time-Arr
|
||||
IOC_TEST:Plg-Mtn0-Ena-Arr
|
||||
IOC_TEST:Plg-Mtn0-EnaAct-Arr
|
||||
IOC_TEST:Plg-Mtn0-Bsy-Arr
|
||||
IOC_TEST:Plg-Mtn0-Exe-Arr
|
||||
IOC_TEST:Plg-Mtn0-TrjSrc-Arr
|
||||
IOC_TEST:Plg-Mtn0-EncSrc-Arr
|
||||
IOC_TEST:Plg-Mtn0-AtTrg-Arr
|
||||
IOC_TEST:Plg-Mtn0-ErrId-Arr
|
||||
IOC_TEST:MCU-ErrMsg
|
||||
IOC_TEST:MCU-Updated
|
||||
IOC_TEST:m0s001-Enc01-LtchCmd
|
||||
IOC_TEST:Axis1-MtnCmd
|
||||
IOC_TEST:Axis1-movVelCmd
|
||||
IOC_TEST:Axis1-movRelCmd
|
||||
IOC_TEST:Axis1-movAbsCmd
|
||||
IOC_TEST:Axis1-movHomCmd
|
||||
IOC_TEST:Axis1-HomProc-RB
|
||||
IOC_TEST:Axis1-Type
|
||||
IOC_TEST:Axis1-DrvType
|
||||
IOC_TEST:Axis1-TrajType
|
||||
IOC_TEST:m0s001-One
|
||||
IOC_TEST:m0s001-Zero
|
||||
IOC_TEST:m0s002-One
|
||||
IOC_TEST:m0s002-Zero
|
||||
IOC_TEST:Axis1-DIR_
|
||||
IOC_TEST:Axis1-ErrRst
|
||||
IOC_TEST:Axis1-HomProc
|
||||
IOC_TEST:Axis1-MtnCmdData
|
||||
IOC_TEST:Plg-Mtn0-Mde-RB
|
||||
IOC_TEST:Plg-Mtn0-Cmd-RB
|
||||
IOC_TEST:m0s001-Stat
|
||||
IOC_TEST:m0s002-Stat
|
||||
IOC_TEST:Axis1-MR-ErrId
|
||||
IOC_TEST:Axis1-CfgRDBD-En-RB
|
||||
IOC_TEST:Axis1-CfgPOSLAG-En-RB
|
||||
IOC_TEST:Axis1-CfgDHLM-En-RB
|
||||
IOC_TEST:Axis1-CfgDLLM-En-RB
|
||||
IOC_TEST:Axis1-Stat
|
||||
IOC_TEST:Axis1-ErrId
|
||||
IOC_TEST:Axis1-WrnId
|
||||
IOC_TEST:Plg-Mtn0-Stat
|
||||
IOC_TEST:m0-Stat
|
||||
IOC_TEST:m0-SlvCntr
|
||||
IOC_TEST:m0-MemmapCntr
|
||||
IOC_TEST:m0-DomFailCntrTot
|
||||
IOC_TEST:m0-EntryCntr
|
||||
IOC_TEST:m0-Dom-Stat
|
||||
IOC_TEST:MCU-Cfg-Info
|
||||
IOC_TEST:MCU-Cfg-Naming
|
||||
IOC_TEST:MCU-Cfg-Mode
|
||||
IOC_TEST:MCU-Cfg-PVA
|
||||
IOC_TEST:Axis1-DbgStrToLOG
|
||||
IOC_TEST:MCU-Cfg-AX1-Pfx
|
||||
IOC_TEST:MCU-Cfg-AX1-Nam
|
||||
IOC_TEST:MCU-Cfg-AX1-PfxNam
|
||||
IOC_TEST:m0s001-EntryCntr
|
||||
IOC_TEST:m0s002-EntryCntr
|
||||
IOC_TEST:Axis1-SeqState
|
||||
IOC_TEST:Axis1-LastIlock
|
||||
IOC_TEST:m0-SlvRsp
|
||||
IOC_TEST:m0-Dom-WC
|
||||
IOC_TEST:m0s001-Enc01-LtchRst
|
||||
IOC_TEST:Axis1-Cmd_
|
||||
REQMOD:raspberrypi-10406:BaseVersion
|
||||
REQMOD:raspberrypi-10406:require_VER
|
||||
REQMOD:raspberrypi-10406:ecmccfg_VER
|
||||
REQMOD:raspberrypi-10406:asyn_VER
|
||||
REQMOD:raspberrypi-10406:exprtk_VER
|
||||
REQMOD:raspberrypi-10406:motor_VER
|
||||
REQMOD:raspberrypi-10406:ruckig_VER
|
||||
REQMOD:raspberrypi-10406:ecmc_VER
|
||||
IOC_TEST:m0s001-HWType
|
||||
IOC_TEST:m0s002-HWType
|
||||
IOC_TEST:Axis1-MsgTxt
|
||||
REQMOD:raspberrypi-10406:ecmc_plugin_motion_VER
|
||||
IOC_TEST:m0s001-Drv01-Stat
|
||||
IOC_TEST:m0s001-Enc01-Stat
|
||||
IOC_TEST:m0s001-Stat_
|
||||
IOC_TEST:m0s002-BO01-Stat
|
||||
IOC_TEST:m0s002-BO02-Stat
|
||||
IOC_TEST:m0s002-BO03-Stat
|
||||
IOC_TEST:m0s002-BO04-Stat
|
||||
IOC_TEST:m0s002-BO05-Stat
|
||||
IOC_TEST:m0s002-BO06-Stat
|
||||
IOC_TEST:m0s002-BO07-Stat
|
||||
IOC_TEST:m0s002-BO08-Stat
|
||||
IOC_TEST:m0s002-BO09-Stat
|
||||
IOC_TEST:m0s002-BO10-Stat
|
||||
IOC_TEST:m0s002-BO11-Stat
|
||||
IOC_TEST:m0s002-BO12-Stat
|
||||
IOC_TEST:m0s002-BO13-Stat
|
||||
IOC_TEST:m0s002-BO14-Stat
|
||||
IOC_TEST:m0s002-BO15-Stat
|
||||
IOC_TEST:m0s002-BO16-Stat
|
||||
IOC_TEST:m0s002-Stat_
|
||||
IOC_TEST:Axis1-Stat_
|
||||
IOC_TEST:ThdRTStat_
|
||||
IOC_TEST:m0-Stat_
|
||||
IOC_TEST:m0-Dom-Stat_
|
||||
IOC_TEST:m0s001-Enc01-LtchAutRst
|
||||
IOC_TEST:Axis1-MtnCmd_
|
||||
IOC_TEST:MCU-Cfg-EC-Mst
|
||||
IOC_TEST:MCU-Cfg-Rate
|
||||
IOC_TEST:MCU-Cfg-Time
|
||||
IOC_TEST:MCU-Cfg-PV-Time
|
||||
IOC_TEST:m0s001-Drv01-Cmd
|
||||
IOC_TEST:m0s001-Drv01-Spd
|
||||
IOC_TEST:m0s001-Enc01-Cmd
|
||||
IOC_TEST:m0s001-Enc01-PosCmd
|
||||
IOC_TEST:m0s001-NxtObjId
|
||||
IOC_TEST:MCU-Cfg-EC-FrstObjId
|
||||
IOC_TEST:m0s002-NxtObjId
|
||||
IOC_TEST:Axis1-OFF_
|
||||
IOC_TEST:Axis1-MRES_
|
||||
IOC_TEST:Axis1-HomPos
|
||||
IOC_TEST:Axis1-VelToHom
|
||||
IOC_TEST:Axis1-VelFrmHom
|
||||
IOC_TEST:Axis1-AccHom
|
||||
IOC_TEST:Axis1-TgtPosCmd
|
||||
IOC_TEST:Axis1-TgtVelCmd
|
||||
IOC_TEST:Axis1-Id
|
||||
IOC_TEST:MCU-Cfg-AX1-NxtObjId
|
||||
IOC_TEST:MCU-Cfg-AX-FrstObjId
|
||||
IOC_TEST:MCU-Cfg-PLG{Index}-NxtObjId
|
||||
IOC_TEST:MCU-Cfg-PLG-FrstObjId
|
||||
IOC_TEST:Plg-Mtn0-AxCmd-RB
|
||||
IOC_TEST:MCU-Cfg-Eng-Mode
|
||||
IOC_TEST:m0s001-Enc01-LchAutRstSp
|
||||
IOC_TEST:m0s002-BO01
|
||||
IOC_TEST:m0s002-BO02
|
||||
IOC_TEST:m0s002-BO03
|
||||
IOC_TEST:m0s002-BO04
|
||||
IOC_TEST:m0s002-BO05
|
||||
IOC_TEST:m0s002-BO06
|
||||
IOC_TEST:m0s002-BO07
|
||||
IOC_TEST:m0s002-BO08
|
||||
IOC_TEST:m0s002-BO09
|
||||
IOC_TEST:m0s002-BO10
|
||||
IOC_TEST:m0s002-BO11
|
||||
IOC_TEST:m0s002-BO12
|
||||
IOC_TEST:m0s002-BO13
|
||||
IOC_TEST:m0s002-BO14
|
||||
IOC_TEST:m0s002-BO15
|
||||
IOC_TEST:m0s002-BO16
|
||||
IOC_TEST:Axis1-EnaCmd
|
||||
IOC_TEST:Axis1-ExeCmd
|
||||
IOC_TEST:Axis1-StpCmd
|
||||
IOC_TEST:Axis1-RstCmd
|
||||
IOC_TEST:Axis1-EncSrcTyp-Cmd
|
||||
IOC_TEST:Axis1-TrjSrcTyp-Cmd
|
||||
IOC_TEST:Axis1-PLC-EnaCmd
|
||||
IOC_TEST:Axis1-CmdFrmPLCCmd
|
||||
IOC_TEST:Axis1-SftLimBwdEna
|
||||
IOC_TEST:Axis1-SftLimFwdEna
|
||||
IOC_TEST:Plg-Mtn0-EnaCmd-RB
|
||||
IOC_TEST:Plg-Mtn0-TrgCmd-RB
|
||||
IOC_TEST:MCU-ErrRst
|
||||
IOC_TEST:Axis1-MCU1-asyn
|
||||
IOC_TEST:MCU-Cmd
|
||||
IOC_TEST:Axis1
|
||||
62
iocsh/test_plugin_motion.script
Normal file
62
iocsh/test_plugin_motion.script
Normal file
@@ -0,0 +1,62 @@
|
||||
##############################################################################
|
||||
## Example: Configuraftion for running ecmc motion plugin
|
||||
##############################################################################
|
||||
|
||||
## Initiation:
|
||||
epicsEnvSet("IOC" ,"$(IOC="IOC_TEST")")
|
||||
epicsEnvSet("SCRIPTEXEC" ,"$(SCRIPTEXEC="iocshLoad")")
|
||||
|
||||
require ecmccfg "9.0.1_RC1"
|
||||
|
||||
# run module startup.cmd (only needed at ESS PSI auto call at require)
|
||||
$(ECMCCFG_INIT="")$(SCRIPTEXEC) ${ecmccfg_DIR}startup.cmd, "IOC=$(IOC),ECMC_VER=v9.0.1_RC1, EC_RATE=500"
|
||||
|
||||
|
||||
##############################################################################
|
||||
## Configure hardware
|
||||
|
||||
epicsEnvSet("ECMC_EC_SLAVE_NUM", "1")
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}configureSlave.cmd, "SLAVE_ID=$(ECMC_EC_SLAVE_NUM), HW_DESC=EL7031, CONFIG=-Motor-Trinamic-QMot-QSH4218-41-10-035"
|
||||
epicsEnvSet("DRV_ID", "${ECMC_EC_SLAVE_NUM}")
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL2819"
|
||||
epicsEnvSet("DO_ID", "${ECMC_EC_SLAVE_NUM}")
|
||||
|
||||
# Configure drv input 1 as drv enable
|
||||
ecmcConfigOrDie "Cfg.EcAddSdo(${DRV_ID},0x8012,0x32,1,1)"
|
||||
OK
|
||||
# Control external drv enable
|
||||
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(${DO_ID},binaryOutput02,1)"
|
||||
|
||||
#Apply hardware configuration
|
||||
ecmcConfigOrDie "Cfg.EcApplyConfig(1)"
|
||||
|
||||
##############################################################################
|
||||
## AXIS 1
|
||||
#
|
||||
epicsEnvSet("DEV", "$(IOC)")
|
||||
$(SCRIPTEXEC) ($(ecmccfg_DIR)configureAxis.cmd, CONFIG=./cfg/el7031.ax)
|
||||
|
||||
##############################################################################
|
||||
## Load plugin: MOTION
|
||||
#
|
||||
epicsEnvSet(ECMC_PLUGIN_CONFIG,"PLUGIN_ID=1,AX=1,BUFF_SIZE=200,DBG=0,ENA=1")
|
||||
require ecmc_plugin_motion master ${ECMC_PLUGIN_CONFIG}
|
||||
# below needed at ESS but not PSI:
|
||||
${SCRIPTEXEC} ${ecmc_plugin_motion_DIR}startup.cmd "${ECMC_PLUGIN_CONFIG}"
|
||||
|
||||
##############################################################################
|
||||
############# Configure diagnostics:
|
||||
|
||||
ecmcConfigOrDie "Cfg.EcSetDiagnostics(1)"
|
||||
ecmcConfigOrDie "Cfg.EcEnablePrintouts(0)"
|
||||
ecmcConfigOrDie "Cfg.EcSetDomainFailedCyclesLimit(100)"
|
||||
ecmcConfigOrDie "Cfg.SetDiagAxisIndex(1)"
|
||||
ecmcConfigOrDie "Cfg.SetDiagAxisFreq(2)"
|
||||
ecmcConfigOrDie "Cfg.SetDiagAxisEnable(0)"
|
||||
|
||||
##############################################################################
|
||||
############# go active:
|
||||
$(SCRIPTEXEC) ($(ecmccfg_DIR)setAppMode.cmd)
|
||||
|
||||
iocInit
|
||||
dbl > pvs.log
|
||||
54
iocsh/test_plugin_motion_psi.script
Normal file
54
iocsh/test_plugin_motion_psi.script
Normal file
@@ -0,0 +1,54 @@
|
||||
##############################################################################
|
||||
## Example: Configuraftion for running ecmc motion plugin
|
||||
##############################################################################
|
||||
|
||||
## Initiation:
|
||||
epicsEnvSet("IOC" ,"$(IOC="IOC_TEST")")
|
||||
epicsEnvSet("ECMCCFG_INIT" ,"") #Only run startup once (auto at PSI, need call at ESS), variable set to "#" in startup.cmd
|
||||
epicsEnvSet("SCRIPTEXEC" ,"$(SCRIPTEXEC="iocshLoad")")
|
||||
|
||||
require ecmccfg "sandst_a_v9.0.1_RC1" "ECMC_VER=v9.0.1_RC1"
|
||||
|
||||
##############################################################################
|
||||
## Configure hardware
|
||||
|
||||
epicsEnvSet("ECMC_EC_SLAVE_NUM", "4")
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}configureSlave.cmd, "SLAVE_ID=$(ECMC_EC_SLAVE_NUM), HW_DESC=EL7031, CONFIG=-Motor-Trinamic-QMot-QSH4218-41-10-035"
|
||||
epicsEnvSet("DRV_ID", "${ECMC_EC_SLAVE_NUM}")
|
||||
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "SLAVE_ID=6,HW_DESC=EL2008"
|
||||
epicsEnvSet(DO_ID,${ECMC_EC_SLAVE_NUM})
|
||||
|
||||
#Apply hardware configuration
|
||||
ecmcConfigOrDie "Cfg.EcApplyConfig(1)"
|
||||
|
||||
##############################################################################
|
||||
## AXIS 1
|
||||
#
|
||||
epicsEnvSet("DEV", "$(IOC)")
|
||||
$(SCRIPTEXEC) ($(ecmccfg_DIR)configureAxis.cmd, CONFIG=./cfg/el7031.ax)
|
||||
|
||||
##############################################################################
|
||||
## Load plugin: MOTION
|
||||
#
|
||||
epicsEnvSet(ECMC_PLUGIN_CONFIG,"PLUGIN_ID=1,AX=1,BUFF_SIZE=200,DBG=0,ENA=1")
|
||||
require ecmc_plugin_motion sandst_a "${ECMC_PLUGIN_CONFIG}"
|
||||
# below needed at ESS but not PSI:
|
||||
#${SCRIPTEXEC} ${ecmc_plugin_motion_DIR}startup.cmd "${ECMC_PLUGIN_CONFIG}"
|
||||
|
||||
##############################################################################
|
||||
############# Configure diagnostics:
|
||||
|
||||
ecmcConfigOrDie "Cfg.EcSetDiagnostics(1)"
|
||||
ecmcConfigOrDie "Cfg.EcEnablePrintouts(0)"
|
||||
ecmcConfigOrDie "Cfg.EcSetDomainFailedCyclesLimit(100)"
|
||||
ecmcConfigOrDie "Cfg.SetDiagAxisIndex(1)"
|
||||
ecmcConfigOrDie "Cfg.SetDiagAxisFreq(2)"
|
||||
ecmcConfigOrDie "Cfg.SetDiagAxisEnable(0)"
|
||||
|
||||
##############################################################################
|
||||
############# go active:
|
||||
$(SCRIPTEXEC) ($(ecmccfg_DIR)setAppMode.cmd)
|
||||
|
||||
iocInit
|
||||
dbl > pvs.log
|
||||
298
src/ecmcPluginSafety.c
Normal file
298
src/ecmcPluginSafety.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2023 Paul Scherrer Institute
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcPluginExample.cpp
|
||||
*
|
||||
* Created on: july 10, 2023
|
||||
* 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 "ecmcMotionPlgDefs.h"
|
||||
#include "ecmcMotionPlgWrap.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 motionConstruct(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 createMotionObj(configStr);
|
||||
}
|
||||
|
||||
/** Optional function.
|
||||
* Will be called once at unload.
|
||||
**/
|
||||
void motionDestruct(void)
|
||||
{
|
||||
deleteAllMotionObjs();
|
||||
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 motionRealtime(int ecmcError)
|
||||
{
|
||||
executeMotionObjs();
|
||||
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 motionEnterRT(){
|
||||
return linkDataTomotionObjs();
|
||||
}
|
||||
|
||||
/** Optional function.
|
||||
* Will be called once just before leaving realtime mode
|
||||
* Return value other than 0 will be considered error.
|
||||
**/
|
||||
int motionExitRT(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_Motion",
|
||||
// Description
|
||||
.desc = "Motion plugin for commissioning of ecmc motion axes.",
|
||||
// Option description
|
||||
.optionDesc = "\n "ECMC_PLUGIN_DBG_PRINT_OPTION_CMD"<1/0> : Enables/disables printouts from plugin, default = disabled.\n"
|
||||
" "ECMC_PLUGIN_AXIS_OPTION_CMD"<axis id> : Sets default source axis id.\n"
|
||||
" "ECMC_PLUGIN_BUFFER_SIZE_OPTION_CMD"<size> : Data points to collect, default = 4096.\n"
|
||||
" "ECMC_PLUGIN_RATE_OPTION_CMD"<rate hz> : Sampling rate in Hz"
|
||||
" "ECMC_PLUGIN_MODE_OPTION_CMD"<TRIGG/CONT> : Sampling rate in Hz"
|
||||
,
|
||||
// Plugin version
|
||||
.version = ECMC_EXAMPLE_PLUGIN_VERSION,
|
||||
// Optional construct func, called once at load. NULL if not definded.
|
||||
.constructFnc = motionConstruct,
|
||||
// Optional destruct func, called once at unload. NULL if not definded.
|
||||
.destructFnc = motionDestruct,
|
||||
// Optional func that will be called each rt cycle. NULL if not definded.
|
||||
.realtimeFnc = motionRealtime,
|
||||
// Optional func that will be called once just before enter realtime mode
|
||||
.realtimeEnterFnc = motionEnterRT,
|
||||
// Optional func that will be called once just before exit realtime mode
|
||||
.realtimeExitFnc = motionExitRT,
|
||||
// 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[0] = {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[0] = {0}, // last element set all to zero..
|
||||
};
|
||||
|
||||
ecmc_plugin_register(pluginDataDef);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif // ifdef __cplusplus
|
||||
1064
src/ecmcSafetyPlg.cpp
Normal file
1064
src/ecmcSafetyPlg.cpp
Normal file
File diff suppressed because it is too large
Load Diff
168
src/ecmcSafetyPlg.h
Normal file
168
src/ecmcSafetyPlg.h
Normal file
@@ -0,0 +1,168 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2023 Paul Scherrer Institute
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcMotionPlg.h
|
||||
*
|
||||
* Created on: july 10, 2023
|
||||
* Author: anderssandstrom
|
||||
*
|
||||
\*************************************************************************/
|
||||
#ifndef ECMC_MOTION_PLG_H_
|
||||
#define ECMC_MOTION_PLG_H_
|
||||
|
||||
#include <stdexcept>
|
||||
#include "ecmcDataItem.h"
|
||||
#include "ecmcAsynPortDriver.h"
|
||||
#include "ecmcMotionPlgDefs.h"
|
||||
#include "inttypes.h"
|
||||
#include <string>
|
||||
#include "dbBase.h"
|
||||
#include "ecmcAxisBase.h"
|
||||
#include "ecmcDataBuffer.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsEvent.h"
|
||||
|
||||
#define ECMC_PLUGIN_MOTION_ERROR_AXIS_OUT_OF_RANGE 1
|
||||
|
||||
typedef enum TRIGG_MODE{
|
||||
NO_MODE = 0,
|
||||
CONT = 1,
|
||||
TRIGG = 2,
|
||||
} TRIGG_MODE;
|
||||
|
||||
class ecmcMotionPlg : public asynPortDriver {
|
||||
public:
|
||||
|
||||
/** ecmc Motion Plg class
|
||||
* This object can throw:
|
||||
* - bad_alloc
|
||||
* - invalid_argument
|
||||
* - runtime_error
|
||||
* - out_of_range
|
||||
*/
|
||||
ecmcMotionPlg(int objIndex, // index of this object
|
||||
char* configStr,
|
||||
char* portName);
|
||||
~ecmcMotionPlg();
|
||||
|
||||
// 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 doWriteWorker(); // low prio worker thread
|
||||
void setEnable(int enable);
|
||||
void clearBuffers();
|
||||
void triggMotionObject();
|
||||
void executeMotionObject();
|
||||
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 readFloat64(asynUser *pasynUser, epicsFloat64 *value);
|
||||
|
||||
|
||||
private:
|
||||
void parseConfigStr(char *configStr);
|
||||
void addDataToBuffer(double data);
|
||||
void initAsyn();
|
||||
static int dataTypeSupported(ecmcEcDataType dt);
|
||||
int setAxis(int axisId);
|
||||
int setMode(TRIGG_MODE mode);
|
||||
int setTrigg(int trigg);
|
||||
void writeBuffers();
|
||||
void switchBuffers();
|
||||
|
||||
|
||||
epicsMutexId axisMutex_;
|
||||
|
||||
double* xAxisArray_; // FFT x axis with freqs
|
||||
size_t elementsInBuffer_;
|
||||
double ecmcSampleRateHz_;
|
||||
int dataSourceLinked_; // To avoid link several times
|
||||
int command_;
|
||||
int status_;
|
||||
// ecmc callback handle for use when deregister at unload
|
||||
int callbackHandle_;
|
||||
int destructs_;
|
||||
int objectId_; // Unique object id
|
||||
int triggOnce_;
|
||||
int cycleCounter_;
|
||||
int ignoreCycles_;
|
||||
|
||||
// Config options
|
||||
int cfgDbgMode_; // Config: allow dbg printouts
|
||||
size_t cfgArraySize_; // Config: Data set size
|
||||
int cfgEnable_; // Config: Enable data acq./calc.
|
||||
double cfgSampleRateHz_; // Config: Sample rate (defaults to ecmc rate)
|
||||
double cfgDataSampleRateHz_;// Config: Sample for data
|
||||
int cfgAxisIndex_; // Config: Enable data acq./calc.
|
||||
TRIGG_MODE cfgMode_; // Config: Mode continous or triggered.
|
||||
|
||||
// Asyn
|
||||
int asynEnableId_; // Enable/disable acq./calcs
|
||||
int asynYActPosArrayId_;
|
||||
int asynYSetPosArrayId_;
|
||||
int asynYDiffPosArrayId_;
|
||||
int asynXAxisArrayId_;
|
||||
int asynTriggId_; // Trigg new measurement
|
||||
int asynAxisId_; // motion axis id
|
||||
int asynSRateId_; // Sample rate
|
||||
int asynElementsInBufferId_; // Current buffer index
|
||||
int asynBufferSizeId_; // Current buffer index
|
||||
int asynCommandId_;
|
||||
int asynStatusId_;
|
||||
int asynModeId_;
|
||||
|
||||
ecmcAxisBase *axis_;
|
||||
// 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);
|
||||
|
||||
ecmcDataBuffer<epicsFloat64> *actPosBuffer_;
|
||||
ecmcDataBuffer<epicsFloat64> *setPosBuffer_;
|
||||
ecmcDataBuffer<epicsFloat64> *diffPosBuffer_;
|
||||
ecmcDataBuffer<epicsFloat64> *xPosBuffer_;
|
||||
ecmcDataBuffer<epicsInt8> *enableBuffer_;
|
||||
ecmcDataBuffer<epicsInt8> *enabledBuffer_;
|
||||
ecmcDataBuffer<epicsInt8> *busyBuffer_;
|
||||
ecmcDataBuffer<epicsInt8> *executeBuffer_;
|
||||
ecmcDataBuffer<epicsInt8> *trajSourceBuffer_;
|
||||
ecmcDataBuffer<epicsInt8> *encSourceBuffer_;
|
||||
ecmcDataBuffer<epicsInt8> *atTargetBuffer_;
|
||||
ecmcDataBuffer<epicsInt32> *errorIdBuffer_;
|
||||
ecmcDataBuffer<epicsInt32> *statusWdBuffer_;
|
||||
|
||||
bool bTriggInProgress_;
|
||||
double xdt_;
|
||||
double xTime_;
|
||||
epicsEvent doWriteEvent_;
|
||||
int writeBusy_;
|
||||
timespec writePauseTime_;
|
||||
};
|
||||
|
||||
#endif /* ECMC_MOTION_PLG_H_ */
|
||||
39
src/ecmcSafetyPlgDefs.h
Normal file
39
src/ecmcSafetyPlgDefs.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2023 Paul Scherrer Institute
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcMotionPlgDefs.h
|
||||
*
|
||||
* Created on: july 10, 2023
|
||||
* Author: anderssandstrom
|
||||
* Credits to https://github.com/sgreg/dynamic-loading
|
||||
*
|
||||
\*************************************************************************/
|
||||
|
||||
#ifndef ECMC_MOTION_PLG_DEFS_H_
|
||||
#define ECMC_MOTION_PLG_DEFS_H_
|
||||
|
||||
#define ECMC_PLUGIN_ASYN_PREFIX "plugin.motion"
|
||||
|
||||
// Options
|
||||
#define ECMC_PLUGIN_DBG_PRINT_OPTION_CMD "DBG_PRINT="
|
||||
#define ECMC_PLUGIN_AXIS_OPTION_CMD "AXIS="
|
||||
#define ECMC_PLUGIN_BUFFER_SIZE_OPTION_CMD "BUFFER_SIZE="
|
||||
#define ECMC_PLUGIN_RATE_OPTION_CMD "RATE="
|
||||
#define ECMC_PLUGIN_ENABLE_OPTION_CMD "ENABLE="
|
||||
#define ECMC_PLUGIN_MODE_OPTION_CMD "MODE="
|
||||
|
||||
// CONT, TRIGG
|
||||
#define ECMC_PLUGIN_MODE_CONT_OPTION "CONT"
|
||||
#define ECMC_PLUGIN_MODE_TRIGG_OPTION "TRIGG"
|
||||
|
||||
|
||||
/** Just one error code in "c" part of plugin
|
||||
(error handled with exceptions i c++ part) */
|
||||
#define ECMC_PLUGIN_MOTION_ERROR_CODE 1
|
||||
|
||||
// Default size (must be n²)
|
||||
#define ECMC_PLUGIN_DEFAULT_ARRAY_SIZE 4096
|
||||
|
||||
#endif /* ECMC_MOTION_PLG_DEFS_H_ */
|
||||
126
src/ecmcSafetyPlgWrap.cpp
Normal file
126
src/ecmcSafetyPlgWrap.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2023 Paul Scherrer Institute
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcMotionPlgWrap.cpp
|
||||
*
|
||||
* Created on: july 10, 2023
|
||||
* 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 "ecmcMotionPlgWrap.h"
|
||||
#include "ecmcMotionPlg.h"
|
||||
|
||||
#define ECMC_PLUGIN_MAX_PORTNAME_CHARS 64
|
||||
#define ECMC_PLUGIN_PORTNAME_PREFIX "PLUGIN.MOTION"
|
||||
|
||||
static std::vector<ecmcMotionPlg*> motionObjs;
|
||||
static int motionObjCounter = 0;
|
||||
static char portNameBuffer[ECMC_PLUGIN_MAX_PORTNAME_CHARS];
|
||||
|
||||
int createMotionObj(char* configStr) {
|
||||
|
||||
// create new ecmcMotionPlg object
|
||||
ecmcMotionPlg* motionObj = 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", motionObjCounter);
|
||||
try {
|
||||
motionObj = new ecmcMotionPlg(motionObjCounter, configStr, portNameBuffer);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
if(motionObj) {
|
||||
delete motionObj;
|
||||
}
|
||||
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||
return ECMC_PLUGIN_MOTION_ERROR_CODE;
|
||||
}
|
||||
|
||||
motionObjs.push_back(motionObj);
|
||||
motionObjCounter++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void deleteAllMotionObjs() {
|
||||
for(std::vector<ecmcMotionPlg*>::iterator pMotionObj = motionObjs.begin(); pMotionObj != motionObjs.end(); ++pMotionObj) {
|
||||
if(*pMotionObj) {
|
||||
delete (*pMotionObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int linkDataTomotionObjs() {
|
||||
for(std::vector<ecmcMotionPlg*>::iterator pMotionObj = motionObjs.begin(); pMotionObj != motionObjs.end(); ++pMotionObj) {
|
||||
if(*pMotionObj) {
|
||||
try {
|
||||
(*pMotionObj)->connectToDataSource();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||
return ECMC_PLUGIN_MOTION_ERROR_CODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enableMotionObj(int objIndex, int enable) {
|
||||
try {
|
||||
motionObjs.at(objIndex)->setEnable(enable);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Motion object index out of range.\n",e.what());
|
||||
return ECMC_PLUGIN_MOTION_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int clearMotionObj(int objIndex) {
|
||||
try {
|
||||
motionObjs.at(objIndex)->clearBuffers();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Motion object index out of range.\n",e.what());
|
||||
return ECMC_PLUGIN_MOTION_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int triggMotionObj(int objIndex) {
|
||||
try {
|
||||
motionObjs.at(objIndex)->triggMotionObject();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Motion object index out of range.\n",e.what());
|
||||
return ECMC_PLUGIN_MOTION_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int executeMotionObjs() {
|
||||
|
||||
for(std::vector<ecmcMotionPlg*>::iterator pMotionObj = motionObjs.begin(); pMotionObj != motionObjs.end(); ++pMotionObj) {
|
||||
if(*pMotionObj) {
|
||||
try {
|
||||
(*pMotionObj)->executeMotionObject();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||
return ECMC_PLUGIN_MOTION_ERROR_CODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
109
src/ecmcSafetyPlgWrap.h
Normal file
109
src/ecmcSafetyPlgWrap.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2023 Paul Scherrer Institute
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcMotionPlgWrap.h
|
||||
*
|
||||
* Created on: july 10, 2023
|
||||
* Author: anderssandstrom
|
||||
*
|
||||
\*************************************************************************/
|
||||
#ifndef ECMC_MOTION_PLG_WRAP_H_
|
||||
#define ECMC_MOTION_PLG_WRAP_H_
|
||||
#include "ecmcMotionPlgDefs.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif // ifdef __cplusplus
|
||||
|
||||
/** \brief Create new Motion object
|
||||
*
|
||||
* The plugin supports creation of multiple Motion 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 createMotionObj(char *configStr);
|
||||
|
||||
/** \brief Enable/disable Motion object
|
||||
*
|
||||
* Enable/disable Motion 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 enableMotionObj(int objIndex, 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 clearMotionObj(int objIndex);
|
||||
|
||||
/** \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 modeMotionObj(int objIndex, 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 triggMotionObj(int objIndex);
|
||||
|
||||
|
||||
/** \brief execute 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 executeMotionObjs();
|
||||
|
||||
/** \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 linkDataTomotionObjs();
|
||||
|
||||
/** \brief Deletes all created fft objects\n
|
||||
*
|
||||
* Should be called when destructs.\n
|
||||
*/
|
||||
|
||||
void deleteAllMotionObjs();
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif // ifdef __cplusplus
|
||||
|
||||
#endif /* ECMC_MOTION_PLG_WRAP_H_ */
|
||||
32
startup.cmd
Normal file
32
startup.cmd
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
#==============================================================================
|
||||
# startup.cmd
|
||||
#-------------- Information:
|
||||
#- Description: ecmc_plugin_motion startup.cmd
|
||||
#-
|
||||
#- by Anders Sandström, Paul Scherrer Institute, 2023
|
||||
#- email: anders.sandstroem@psi.ch
|
||||
#-
|
||||
#-###############################################################################
|
||||
#-
|
||||
#- Arguments
|
||||
#- [mandatory]
|
||||
#- PLUGIN_ID = Plugin instansiation index, must be unique for each call
|
||||
#-
|
||||
#- [optional]
|
||||
#- AX = Axis id, default 1
|
||||
#- BUFF_SIZE = Buffer size, default 1000
|
||||
#- DBG = Debug mode, default 1
|
||||
#- ENA = Enable operation, default 1
|
||||
#- REPORT = Printout plugin details, default 1
|
||||
|
||||
#################################################################################
|
||||
|
||||
#- Load plugin: MOTION
|
||||
|
||||
# Only allow call startup.cmd once. if more objects are needed then use addMotionObj.cmd directlly.
|
||||
|
||||
#- add One motion plugin object, only run startup once
|
||||
${ECMC_PLG_MOTION_INIT=""}${SCRIPTEXEC} $(ecmc_plugin_motion_DIR)addMotionObj.cmd "PLUGIN_ID=${PLUGIN_ID},AX=${AX=1},BUFF_SIZE=${BUFF_SIZE=1000},DBG=${DBG=1},ENA=${ENA=1},REPORT=${REPORT=1}"
|
||||
|
||||
epicsEnvSet("ECMC_PLG_MOTION_INIT" ,"#")
|
||||
0
template/.keep
Normal file
0
template/.keep
Normal file
Reference in New Issue
Block a user