Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
cc88331652 | |||
7023f52336 | |||
83a995a16d | |||
c445af75c1 | |||
124aa97cd6 | |||
ebc3de1bd2 | |||
bd3b808312 | |||
73c9c98329 | |||
9a3b0f7666 | |||
0eed0c9357 | |||
7263a0772f | |||
9c507a05ba | |||
dc966bc976 | |||
edd3005f85 | |||
af4d16d25f | |||
6ea6fdcb85 | |||
389e7f9157 | |||
8858761e74 | |||
2950f21353 | |||
28999f2212 | |||
7c1693e606 | |||
c75957f284 | |||
8f0c240e76 | |||
5dff3bc23b |
1
Makefile
1
Makefile
@ -1,3 +1,4 @@
|
||||
# This is for building the IOC application against the EEE-setup
|
||||
#Makefile at top of application tree
|
||||
TOP = .
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
33
Makefile.EEE
Normal file
33
Makefile.EEE
Normal file
@ -0,0 +1,33 @@
|
||||
# This build the SINQ stuff as an EEE module. Which we cannot use yet because of the political problem
|
||||
# of integrating this module into the EEE distribution
|
||||
include ${EPICS_ENV_PATH}/module.Makefile
|
||||
|
||||
PROJECT=sinq
|
||||
|
||||
USR_DEPENDENCIES = asyn,4.27.0
|
||||
USR_DEPENDENCIES += motor,6.10.0
|
||||
USR_DEPENDENCIES += synAppsStd,3.4.1
|
||||
USR_DEPENDENCIES += streamdevice,2.6.0
|
||||
USR_DEPENDENCIES += busy,1.6.0
|
||||
USR_DEPENDENCIES += pcre,8.36.0
|
||||
|
||||
|
||||
TEMPLATES += sinqEPICSApp/Db/dimetix.db
|
||||
TEMPLATES += sinqEPICSApp/Db/slsvme.db
|
||||
TEMPLATES += sinqEPICSApp/Db/spsamor.db
|
||||
TEMPLATES += sinqEPICSApp/Db/el737Record.db
|
||||
|
||||
|
||||
DBDS += sinqEPICSApp/src/sinq.dbd
|
||||
|
||||
SUBSTITUTIONS=-none-
|
||||
|
||||
OPIS=-none-
|
||||
|
||||
# What we need at SINQ
|
||||
SOURCES += sinqEPICSApp/src/devScalerEL737.c
|
||||
SOURCES += sinqEPICSApp/src/EL734Driver.cpp
|
||||
SOURCES += sinqEPICSApp/src/NanotecDriver.cpp
|
||||
SOURCES += sinqEPICSApp/src/stptok.cpp
|
||||
|
||||
# MISCS would be the place to keep the stream device template files
|
33
Makefile.RHEL7
Normal file
33
Makefile.RHEL7
Normal file
@ -0,0 +1,33 @@
|
||||
# This build the sinq extensions for the PSI EPICS setup
|
||||
include /ioc/tools/driver.makefile
|
||||
|
||||
MODULE=sinq
|
||||
|
||||
BUILDCLASSES=Linux
|
||||
|
||||
# additional module dependencies
|
||||
REQUIRED+=SynApps
|
||||
REQUIRED+=stream
|
||||
|
||||
# using a test version
|
||||
scaler_VERSION=koennecke
|
||||
|
||||
TEMPLATES += sinqEPICSApp/Db/dimetix.db
|
||||
TEMPLATES += sinqEPICSApp/Db/slsvme.db
|
||||
TEMPLATES += sinqEPICSApp/Db/spsamor.db
|
||||
|
||||
DBDS += sinqEPICSApp/src/sinq.dbd
|
||||
|
||||
# What we need at SINQ
|
||||
SOURCES += sinqEPICSApp/src/devScalerEL737.c
|
||||
SOURCES += sinqEPICSApp/src/SINQController.cpp
|
||||
SOURCES += sinqEPICSApp/src/SINQAxis.cpp
|
||||
SOURCES += sinqEPICSApp/src/EL734Driver.cpp
|
||||
SOURCES += sinqEPICSApp/src/NanotecDriver.cpp
|
||||
SOURCES += sinqEPICSApp/src/stptok.cpp
|
||||
SOURCES += sinqEPICSApp/src/PhytronDriver.cpp
|
||||
SOURCES += sinqEPICSApp/src/pmacAsynIPPort.c
|
||||
SOURCES += sinqEPICSApp/src/pmacAxis.cpp
|
||||
SOURCES += sinqEPICSApp/src/pmacController.cpp
|
||||
|
||||
# MISCS would be the place to keep the stream device template files
|
@ -32,3 +32,5 @@ INSTALL_LOCATION=/afs/psi.ch/project/sinqdev/sinqepicsapp
|
||||
# You must rebuild in the iocBoot directory for this to
|
||||
# take effect.
|
||||
#IOCS_APPL_TOP = </IOC/path/to/application/top>
|
||||
STATIC_BUILD=NO
|
||||
SHARED_LIBRARIES=YES
|
||||
|
@ -25,16 +25,17 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
|
||||
|
||||
# EPICS_BASE usually appears last so other apps can override stuff:
|
||||
EPICS_BASE=/usr/local/epics
|
||||
EPICS_BASE=/opt/epics/bases/base-3.14.12.5
|
||||
|
||||
# Set RULES here if you want to take build rules from somewhere
|
||||
# other than EPICS_BASE:
|
||||
#RULES=/path/to/epics/support/module/rules/x-y
|
||||
MOTOR=/usr/local/epics/support/motor-6-7
|
||||
ASYN=/usr/local/epics/support/asyn-4-18
|
||||
STD=/usr/local/epics/support/std-3-1
|
||||
ANC=/usr/local/epics/anc350v17
|
||||
STREAMS=/usr/local/epics/support/StreamDevice-2-6
|
||||
LAKESHORE336=/usr/local/epics/support/lakeshore336
|
||||
BUSY=/usr/local/epics/support/busy-1-4
|
||||
OXINSTCRYOJET=/usr/local/epics/support/OxInstCryojet-2-18-3
|
||||
MOTOR=/opt/epics/modules/motor/6.10.0/3.14.12.5
|
||||
ASYN=/opt/epics/modules/asyn/4.27.0/3.14.12.5
|
||||
SYNAPPSSTD=/opt/epics/modules/synAppsStd/3.4.1/3.14.12.5/
|
||||
#ANC=/usr/local/epics/anc350v17
|
||||
STREAMS=/opt/epics/modules/streamdevice/2.6.0/3.14.12.5
|
||||
#LAKESHORE336=/usr/local/epics/support/lakeshore336
|
||||
BUSY=/opt/epics/modules/busy/1.6.0/3.14.12.5
|
||||
#OXINSTCRYOJET=/usr/local/epics/support/OxInstCryojet-2-18-3
|
||||
PCRE=/opt/epics/modules/pcre/8.36.0/3.14.12.5
|
||||
|
61
essst.cmd
Executable file
61
essst.cmd
Executable file
@ -0,0 +1,61 @@
|
||||
###!/opt/epics/modules/environment/1.8.0/3.14.12.5/bin/centos7-x86_64/iocsh
|
||||
|
||||
var requireDebug 2
|
||||
|
||||
require sinq, local
|
||||
|
||||
|
||||
#---------- connect to controllers
|
||||
drvAsynIPPortConfigure("serial1", "localhost:60001",0,0,0)
|
||||
drvAsynIPPortConfigure("serial2", "localhost:60002",0,0,0)
|
||||
drvAsynIPPortConfigure("serial3", "localhost:60003",0,0,0)
|
||||
EL734CreateController("mota","serial1",12);
|
||||
EL734CreateController("motb","serial2",12);
|
||||
EL734CreateController("motc","serial3",12);
|
||||
|
||||
### Motors
|
||||
|
||||
dbLoadRecords("asynRecord.db","P=SQ:AMOR:,R=serial1,PORT=serial1,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("asynRecord.db","P=SQ:AMOR:,R=serial2,PORT=serial1,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("asynRecord.db","P=SQ:AMOR:,R=serial3,PORT=serial1,ADDR=0,OMAX=80,IMAX=80")
|
||||
|
||||
dbLoadTemplate "mota.substitutions"
|
||||
dbLoadTemplate "motb.substitutions"
|
||||
dbLoadTemplate "motc.substitutions"
|
||||
|
||||
|
||||
#--------- load EL737 counter box
|
||||
drvAsynIPPortConfigure("cter1","localhost:62000",0,0,0)
|
||||
dbLoadRecords("asynRecord.db","P=SQ:AMOR:,R=cter1,PORT=cter1,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("el737Record.db")
|
||||
|
||||
#asynSetTraceIOMask("cter1",0,2)
|
||||
|
||||
#----------- load Magnets
|
||||
drvAsynIPPortConfigure("slsvme", "localhost:60066",0,0,0)
|
||||
#drvAsynIPPortConfigure("slsvme", "localhost:8080",0,0,0)
|
||||
|
||||
dbLoadRecords("asynRecord.db","P=SQ:AMOR:,R=slsvme,PORT=slsvme,ADDR=0,OMAX=80,IMAX=80")
|
||||
|
||||
epicsEnvSet ("STREAM_PROTOCOL_PATH", "$(TOP)/db:.")
|
||||
|
||||
dbLoadRecords("slsvme.db","PREFIX=SQ:AMOR:PBY:,NO=1")
|
||||
dbLoadRecords("slsvme.db","PREFIX=SQ:AMOR:FMA:,NO=2")
|
||||
dbLoadRecords("slsvme.db","PREFIX=SQ:AMOR:ABY:,NO=3")
|
||||
|
||||
#-------------- load SPS
|
||||
drvAsynIPPortConfigure("sps1", "localhost:60077",0,0,0)
|
||||
dbLoadRecords("asynRecord.db","P=SQ:AMOR:,R=spsdirect,PORT=sps1,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("spsamor.db","PREFIX=SQ:AMOR:SPS1:")
|
||||
|
||||
#------------- Load dimetix distance measurement device
|
||||
drvAsynIPPortConfigure("dimetix", "localhost:60088",0,0,0)
|
||||
dbLoadRecords("asynRecord.db","P=SQ:AMOR:,R=dimetixdirect,PORT=dimetix,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("dimetix.db","PREFIX=SQ:AMOR:DIMETIX:")
|
||||
|
||||
|
||||
|
||||
iocInit
|
||||
|
||||
## Start any sequence programs
|
||||
#seq sncxxx,"user=koenneckeHost"
|
@ -1,8 +0,0 @@
|
||||
epicsEnvSet("ARCH","linux-x86-debug")
|
||||
epicsEnvSet("IOC","iocsinqEPICS")
|
||||
epicsEnvSet("TOP","/afs/psi.ch/project/sinqdev/sinqepicsapp")
|
||||
epicsEnvSet("EPICS_BASE","/usr/local/epics")
|
||||
epicsEnvSet("ASYN","/usr/local/epics/support/asyn-4-18")
|
||||
epicsEnvSet("MOTOR","/usr/local/epics/support/motor-6-7")
|
||||
epicsEnvSet("LAKESHORE336","/usr/local/epics/support/lakeshore336")
|
||||
epicsEnvSet("OXINSTCRYOJET","/usr/local/epics/support/OxInstCryojet-2-18-3")
|
@ -1,10 +1,21 @@
|
||||
file "$(MOTOR)/db/basic_asyn_motor.db"
|
||||
{
|
||||
pattern
|
||||
{P, N, M, DTYP, PORT, ADDR, DESC, EGU, DIR, VELO, VBAS, ACCL, BDST, BVEL, BACC, MRES, PREC, DHLM, DLLM, INIT}
|
||||
{P, N, M, DTYP, PORT, ADDR, DESC, EGU, DIR, VELO, VBAS, ACCL, BDST, BVEL, BACC, MRES, PREC, DHLM, DLLM, INIT}
|
||||
{NZ:mota:, 1, "m$(N)", "asynMotor", mota, 1, "sgu", degree, Pos, 2.0, 0.1, .2, 0, 1, .2, 1., 3, 20, -20, ""}
|
||||
{NZ:mota:, 2, "m$(N)", "asynMotor", mota, 2, "sgl", degree, Pos, 2.0, 0.1, .2, 0, 1, .2, 1., 3, 20, -20, ""}
|
||||
{NZ:mota:, 3, "m$(N)", "asynMotor", mota, 3, "sgd", degree, Pos, 2.0, 0.1, .2, 0, 1, .2, 1., 3, 20, -20, ""}
|
||||
{NZ:mota:, 4, "m$(N)", "asynMotor", mota, 4, "som", degree, Pos, 2.0, 0.1, .2, 0, 1, .2, 0.001, 3, 37, -37, ""}
|
||||
{NZ:mota:, 5, "m$(N)", "asynMotor", mota, 5, "sty", degree, Pos, 2.0, 0.1, .2, 0, 1, .2, 0.001, 3, 150, -149, ""}
|
||||
}
|
||||
|
||||
file "$(SINQ)/Db/motorMessage.db"
|
||||
{
|
||||
pattern
|
||||
{P,N, M,PORT}
|
||||
{NZ:mota:, 1, "m$(N)",mota}
|
||||
{NZ:mota:, 2, "m$(N)",mota}
|
||||
{NZ:mota:, 3, "m$(N)",mota}
|
||||
{NZ:mota:, 4, "m$(N)",mota}
|
||||
{NZ:mota:, 5, "m$(N)",mota}
|
||||
}
|
@ -1,41 +1,42 @@
|
||||
#!../../bin/linux-x86/sinqEPICS
|
||||
#!../../bin/linux-x86-debug/sinqEPICS
|
||||
|
||||
## You may have to change sinqEPICS to something else
|
||||
## everywhere it appears in this file
|
||||
|
||||
cd /opt/amor/epics
|
||||
|
||||
< envPaths
|
||||
|
||||
cd ${TOP}
|
||||
|
||||
## Register all support components
|
||||
dbLoadDatabase "dbd/sinqEPICS.dbd"
|
||||
dbLoadDatabase "dbd/sinq.dbd"
|
||||
sinqEPICS_registerRecordDeviceDriver pdbbase
|
||||
|
||||
## Load record instances
|
||||
#dbLoadRecords("db/xxx.db","user=koenneckeHost")
|
||||
|
||||
|
||||
#---------- load EL734 motor controller
|
||||
drvAsynIPPortConfigure("serial1", "narziss-ts:3002",0,0,0)
|
||||
#drvAsynIPPortConfigure("serial1", "localhost:8080",0,0,0)
|
||||
EL734CreateController("mota","serial1",6);
|
||||
#---------- connect to controllers
|
||||
drvAsynIPPortConfigure("serial1", "localhost:60001",0,0,0)
|
||||
drvAsynIPPortConfigure("serial2", "localhost:60002",0,0,0)
|
||||
drvAsynIPPortConfigure("serial3", "localhost:60003",0,0,0)
|
||||
EL734CreateController("mota","serial1",12);
|
||||
EL734CreateController("motb","serial2",12);
|
||||
EL734CreateController("motc","serial3",12);
|
||||
|
||||
### Motors
|
||||
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=NZ:,R=serial1,PORT=serial1,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=SQ:AMOR:,R=serial1,PORT=serial1,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=SQ:AMOR:,R=serial2,PORT=serial1,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=SQ:AMOR:,R=serial3,PORT=serial1,ADDR=0,OMAX=80,IMAX=80")
|
||||
|
||||
|
||||
cd ${TOP}/iocBoot/${IOC}
|
||||
dbLoadTemplate "motor.substitutions.el734"
|
||||
dbLoadTemplate "mota.substitutions"
|
||||
dbLoadTemplate "motb.substitutions"
|
||||
dbLoadTemplate "motc.substitutions"
|
||||
|
||||
|
||||
#--------- load EL737 counter box
|
||||
drvAsynIPPortConfigure("cter1","narziss-ts:3003",0,0,0)
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=NZ:,R=cter1,PORT=cter1,ADDR=0,OMAX=80,IMAX=80")
|
||||
drvAsynIPPortConfigure("cter1","localhost:62000",0,0,0)
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=SQ:AMOR:,R=cter1,PORT=cter1,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("${TOP}/db/el737Record.db")
|
||||
|
||||
asynSetTraceIOMask("cter1",0,2)
|
||||
#asynSetTraceIOMask("cter1",0,2)
|
||||
|
||||
iocInit
|
||||
|
||||
|
34
iocBoot/iocsinqEPICS/stdimetix.cmd
Executable file
34
iocBoot/iocsinqEPICS/stdimetix.cmd
Executable file
@ -0,0 +1,34 @@
|
||||
#!../../bin/centos7-x86_64/sinqEPICS
|
||||
# for debugging..................
|
||||
## You may have to change sinqEPICS to something else
|
||||
## everywhere it appears in this file
|
||||
|
||||
< envPaths
|
||||
|
||||
cd ${TOP}
|
||||
|
||||
## Register all support components
|
||||
dbLoadDatabase "dbd/sinqEPICS.dbd"
|
||||
dbLoadDatabase "dbd/sinq.dbd"
|
||||
sinqEPICS_registerRecordDeviceDriver pdbbase
|
||||
|
||||
## Load record instances
|
||||
#dbLoadRecords("db/xxx.db","user=koenneckeHost")
|
||||
|
||||
|
||||
#---------- Install SPS
|
||||
drvAsynIPPortConfigure("dimetix", "localhost:64000",0,0,0)
|
||||
#drvAsynIPPortConfigure("slsvme", "localhost:8080",0,0,0)
|
||||
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=SQ:AMOR:,R=dimetix,PORT=dimetix,ADDR=0,OMAX=80,IMAX=80")
|
||||
|
||||
epicsEnvSet ("STREAM_PROTOCOL_PATH", "$(TOP)/sinqEPICSApp/Db:.")
|
||||
|
||||
cd ${TOP}/iocBoot/iocsinqEPICS
|
||||
dbLoadRecords("$(TOP)/sinqEPICSApp/Db/dimetix.db","PREFIX=SQ:AMOR:DIMETIX:")
|
||||
|
||||
|
||||
iocInit
|
||||
|
||||
## Start any sequence programs
|
||||
#seq sncxxx,"user=koenneckeHost"
|
34
iocBoot/iocsinqEPICS/stel755.cmd
Executable file
34
iocBoot/iocsinqEPICS/stel755.cmd
Executable file
@ -0,0 +1,34 @@
|
||||
#!../../bin/linux-x86-debug/sinqEPICS
|
||||
# for debugging..................
|
||||
## You may have to change sinqEPICS to something else
|
||||
## everywhere it appears in this file
|
||||
|
||||
< envPaths
|
||||
|
||||
cd ${TOP}
|
||||
|
||||
## Register all support components
|
||||
dbLoadDatabase "$(TOP)/dbd/sinqEPICS.dbd"
|
||||
dbLoadDatabase "$(TOP)/sinqEPICSApp/src/sinq.dbd"
|
||||
sinqEPICS_registerRecordDeviceDriver pdbbase
|
||||
|
||||
## Load record instances
|
||||
#dbLoadRecords("db/xxx.db","user=koenneckeHost")
|
||||
|
||||
|
||||
#---------- Install SLSVME
|
||||
drvAsynIPPortConfigure("el755", "narziss-ts:3004",0,0,0)
|
||||
#drvAsynIPPortConfigure("slsvme", "localhost:8080",0,0,0)
|
||||
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=SQ:NZ:,R=el755,PORT=el755,ADDR=0,OMAX=80,IMAX=80")
|
||||
|
||||
epicsEnvSet ("STREAM_PROTOCOL_PATH", "$(TOP)/sinqEPICSApp/Db:.")
|
||||
|
||||
cd ${TOP}/iocBoot/iocsinqEPICS
|
||||
dbLoadRecords("$(TOP)/sinqEPICSApp/Db/el755.db","PREFIX=SQ:NZ:AMAG:,NO=2")
|
||||
|
||||
|
||||
iocInit
|
||||
|
||||
## Start any sequence programs
|
||||
#seq sncxxx,"user=koenneckeHost"
|
34
iocBoot/iocsinqEPICS/stslsvme.cmd
Executable file
34
iocBoot/iocsinqEPICS/stslsvme.cmd
Executable file
@ -0,0 +1,34 @@
|
||||
#!../../bin/centos7-x86_64/sinqEPICS
|
||||
# for debugging..................
|
||||
## You may have to change sinqEPICS to something else
|
||||
## everywhere it appears in this file
|
||||
|
||||
< envPaths
|
||||
|
||||
cd ${TOP}
|
||||
|
||||
## Register all support components
|
||||
dbLoadDatabase "dbd/sinqEPICS.dbd"
|
||||
dbLoadDatabase "dbd/sinq.dbd"
|
||||
sinqEPICS_registerRecordDeviceDriver pdbbase
|
||||
|
||||
## Load record instances
|
||||
#dbLoadRecords("db/xxx.db","user=koenneckeHost")
|
||||
|
||||
|
||||
#---------- Install SLSVME
|
||||
drvAsynIPPortConfigure("slsvme", "mpc2084:60066",0,0,0)
|
||||
#drvAsynIPPortConfigure("slsvme", "localhost:8080",0,0,0)
|
||||
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=SQ:AMOR:,R=slsvme,PORT=slsvme,ADDR=0,OMAX=80,IMAX=80")
|
||||
|
||||
epicsEnvSet ("STREAM_PROTOCOL_PATH", "$(TOP)/sinqEPICSApp/Db:.")
|
||||
|
||||
cd ${TOP}/iocBoot/iocsinqEPICS
|
||||
dbLoadRecords("slsvme.db","PREFIX=SQ:AMOR:PBY:,NO=1")
|
||||
|
||||
|
||||
iocInit
|
||||
|
||||
## Start any sequence programs
|
||||
#seq sncxxx,"user=koenneckeHost"
|
34
iocBoot/iocsinqEPICS/stsps.cmd
Executable file
34
iocBoot/iocsinqEPICS/stsps.cmd
Executable file
@ -0,0 +1,34 @@
|
||||
#!../../bin/centos7-x86_64/sinqEPICS
|
||||
# for debugging..................
|
||||
## You may have to change sinqEPICS to something else
|
||||
## everywhere it appears in this file
|
||||
|
||||
< envPaths
|
||||
|
||||
cd ${TOP}
|
||||
|
||||
## Register all support components
|
||||
dbLoadDatabase "dbd/sinqEPICS.dbd"
|
||||
dbLoadDatabase "dbd/sinq.dbd"
|
||||
sinqEPICS_registerRecordDeviceDriver pdbbase
|
||||
|
||||
## Load record instances
|
||||
#dbLoadRecords("db/xxx.db","user=koenneckeHost")
|
||||
|
||||
|
||||
#---------- Install SPS
|
||||
drvAsynIPPortConfigure("spss5", "localhost:63000",0,0,0)
|
||||
#drvAsynIPPortConfigure("slsvme", "localhost:8080",0,0,0)
|
||||
|
||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=SQ:AMOR:,R=spss5,PORT=spss5,ADDR=0,OMAX=80,IMAX=80")
|
||||
|
||||
epicsEnvSet ("STREAM_PROTOCOL_PATH", "$(TOP)/sinqEPICSApp/Db:.")
|
||||
|
||||
cd ${TOP}/iocBoot/iocsinqEPICS
|
||||
dbLoadRecords("$(TOP)/sinqEPICSApp/Db/spsamor.db","PREFIX=SQ:AMOR:SPSS5:")
|
||||
|
||||
|
||||
iocInit
|
||||
|
||||
## Start any sequence programs
|
||||
#seq sncxxx,"user=koenneckeHost"
|
7
makesinqtar
Executable file
7
makesinqtar
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/tclsh
|
||||
|
||||
set dir [pwd]
|
||||
|
||||
cd /usr/local/ioc
|
||||
|
||||
exec /usr/bin/tar czvf $dir/sinqepics.tgz modules/scaler modules/sinq modules/anc350
|
@ -10,7 +10,7 @@ include $(TOP)/configure/CONFIG
|
||||
#----------------------------------------------------
|
||||
# Create and install (or just install) into <top>/db
|
||||
# databases, templates, substitutions like this
|
||||
#DB += xxx.db
|
||||
DB_INSTALL += slsvme.proto
|
||||
|
||||
#----------------------------------------------------
|
||||
# If <anyname>.db template is not named <anyname>*.template add
|
||||
|
40
sinqEPICSApp/Db/dimetix.db
Normal file
40
sinqEPICSApp/Db/dimetix.db
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
# DB file for dimetix laser distance measurement device
|
||||
|
||||
##
|
||||
## Switch the laser
|
||||
##
|
||||
record(bo, "$(PREFIX)LASER") {
|
||||
field(DESC, "Switch laser on and off")
|
||||
field(DTYP,"stream")
|
||||
field(OUT,"@dimetix.proto setlaser() dimetix 0")
|
||||
field(PINI, "YES")
|
||||
field(VAL, "0")
|
||||
field(ZNAM, "OFF")
|
||||
field(ONAM, "ON")
|
||||
}
|
||||
|
||||
##
|
||||
## Read the distance
|
||||
##
|
||||
record(ai, "$(PREFIX)DIST") {
|
||||
field(DTYP, "stream")
|
||||
field(DESC, "Distance")
|
||||
field(INP, "@dimetix.proto read() dimetix 0")
|
||||
field(SCAN, "1 second")
|
||||
field(PREC, "1")
|
||||
field(EGU, "mm")
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## Set the readback (for simulation purposes only)
|
||||
##
|
||||
record(ao, "$(PREFIX)SimVal") {
|
||||
field(DTYP, "stream")
|
||||
field(DESC, "Set readback for simulation")
|
||||
field(OUT, "@dimetix.proto setreadback() dimetix 0")
|
||||
field(PREC, "1")
|
||||
field(EGU, "mm")
|
||||
}
|
||||
|
23
sinqEPICSApp/Db/dimetix.proto
Normal file
23
sinqEPICSApp/Db/dimetix.proto
Normal file
@ -0,0 +1,23 @@
|
||||
# Streamdevice protocol file for a Dimetix distance measuring device as used at
|
||||
# AMOR
|
||||
|
||||
InTerminator = "\n";
|
||||
OutTerminator = "\r\n";
|
||||
ExtraInput = Ignore;
|
||||
|
||||
setlaser {
|
||||
out "%{s0p|s0o}";
|
||||
in "g0?";
|
||||
}
|
||||
|
||||
setreadback {
|
||||
out "setval %d";
|
||||
in "g0?";
|
||||
}
|
||||
|
||||
read {
|
||||
out "s0g";
|
||||
in "g0g+%d";
|
||||
@mismatch {in "@E213"}
|
||||
}
|
||||
|
27
sinqEPICSApp/Db/el737Record.db
Normal file
27
sinqEPICSApp/Db/el737Record.db
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
record(bo,"$(P):Pause")
|
||||
{
|
||||
field(DTYP,"Soft Channel")
|
||||
}
|
||||
record(longin,"$(P):Status")
|
||||
{
|
||||
field(DTYP,"Soft Channel")
|
||||
}
|
||||
record(stringin,"$(P):MsgTxt")
|
||||
{
|
||||
field(DTYP,"Soft Channel")
|
||||
}
|
||||
record(longout,"$(P):ThresholdCounter")
|
||||
{
|
||||
field(DTYP,"Soft Channel")
|
||||
}
|
||||
record(longout,"$(P):Threshold")
|
||||
{
|
||||
field(DTYP,"Soft Channel")
|
||||
}
|
||||
record(scaler,"$(P)")
|
||||
{
|
||||
field(DESC,"$(DESC)")
|
||||
field(DTYP,"asynScalerEL737")
|
||||
field(OUT,"INST_IO @asyn($(PORT),0)")
|
||||
}
|
22
sinqEPICSApp/Db/el755.db
Normal file
22
sinqEPICSApp/Db/el755.db
Normal file
@ -0,0 +1,22 @@
|
||||
##
|
||||
## Read the Current
|
||||
##
|
||||
record(ai, "$(PREFIX)CurRBV") {
|
||||
field(DTYP, "stream")
|
||||
field(DESC, "Current Readback")
|
||||
field(INP, "@el755.proto read($(NO)) el755 0")
|
||||
field(SCAN, "1 second")
|
||||
field(PREC, "3")
|
||||
field(EGU, "A")
|
||||
}
|
||||
|
||||
##
|
||||
## Set the current
|
||||
##
|
||||
record(ao, "$(PREFIX)CurSet") {
|
||||
field(DTYP, "stream")
|
||||
field(DESC, "Setpoint current")
|
||||
field(OUT, "@el755.proto write($(NO)) el755 0")
|
||||
field(PREC, "3")
|
||||
field(EGU, "A")
|
||||
}
|
22
sinqEPICSApp/Db/el755.proto
Normal file
22
sinqEPICSApp/Db/el755.proto
Normal file
@ -0,0 +1,22 @@
|
||||
# Streamdevice protocol file for the PSI EL755 Magnet Controller
|
||||
|
||||
InTerminator = "\r";
|
||||
OutTerminator = "\r";
|
||||
#ExtraInput = Ignore;
|
||||
|
||||
read {
|
||||
out "I \$1";
|
||||
in "%*f %f";
|
||||
@mismatch {out "RMT 1";
|
||||
in "";
|
||||
out "ECHO 0";
|
||||
in "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
write {
|
||||
out "I \$1 %f";
|
||||
in "";
|
||||
}
|
||||
|
9
sinqEPICSApp/Db/motorMessage.db
Normal file
9
sinqEPICSApp/Db/motorMessage.db
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
# The message text
|
||||
record(waveform, "$(P)$(M)-MsgTxt") {
|
||||
field(DTYP, "asynOctetRead")
|
||||
field(INP, "@asyn($(PORT),$(N),1) MOTOR_MESSAGE_TEXT")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "80")
|
||||
field(SCAN, "I/O Intr")
|
||||
}
|
94
sinqEPICSApp/Db/slsvme.db
Normal file
94
sinqEPICSApp/Db/slsvme.db
Normal file
@ -0,0 +1,94 @@
|
||||
# Database definition for the SLS VME magnets as installed at AMOR
|
||||
|
||||
##
|
||||
## Read the High Limit
|
||||
##
|
||||
record(ai, "$(PREFIX)HighLim") {
|
||||
field(DTYP, "stream")
|
||||
field(DESC, "High Current Limit")
|
||||
field(INP, "@slsvme.proto read($(NO),hl) slsvme 0")
|
||||
field(SCAN, "1 second")
|
||||
field(PREC, "3")
|
||||
field(EGU, "A")
|
||||
}
|
||||
|
||||
##
|
||||
## Read the High Limit
|
||||
##
|
||||
record(ai, "$(PREFIX)LowLim") {
|
||||
field(DTYP, "stream")
|
||||
field(DESC, "Low Current Limit")
|
||||
field(INP, "@slsvme.proto read($(NO),ll) slsvme 0")
|
||||
field(SCAN, "1 second")
|
||||
field(PREC, "3")
|
||||
field(EGU, "A")
|
||||
}
|
||||
|
||||
##
|
||||
## Read the Error code
|
||||
##
|
||||
record(ai, "$(PREFIX)ErrCode") {
|
||||
field(DTYP, "stream")
|
||||
field(DESC, "Error Code")
|
||||
field(INP, "@slsvme.proto read($(NO),err) slsvme 0")
|
||||
field(SCAN, "1 second")
|
||||
field(PREC, "3")
|
||||
field(EGU, "A")
|
||||
}
|
||||
|
||||
##
|
||||
## Read the textual representation of the error.
|
||||
##
|
||||
record(stringin, "$(PREFIX)ErrText") {
|
||||
field(DTYP, "stream")
|
||||
field(INP, "@slsvme.proto readErrTxt($(NO)) slsvme 0")
|
||||
field(SCAN, "1 second")
|
||||
field(PINI, "YES")
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## Read the Current
|
||||
##
|
||||
record(ai, "$(PREFIX)CurRBV") {
|
||||
field(DTYP, "stream")
|
||||
field(DESC, "Low Current Limit")
|
||||
field(INP, "@slsvme.proto read($(NO),cur) slsvme 0")
|
||||
field(SCAN, "1 second")
|
||||
field(PREC, "3")
|
||||
field(EGU, "A")
|
||||
}
|
||||
|
||||
##
|
||||
## Set the current
|
||||
##
|
||||
record(ao, "$(PREFIX)CurSet") {
|
||||
field(DTYP, "stream")
|
||||
field(DESC, "Setpoint current")
|
||||
field(OUT, "@slsvme.proto write($(NO),cur) slsvme 0")
|
||||
field(PREC, "3")
|
||||
field(EGU, "A")
|
||||
}
|
||||
|
||||
##
|
||||
## Read power status of the magnet
|
||||
##
|
||||
record(bi, "$(PREFIX)PowerStatusRBV") {
|
||||
field(DESC, "Readback of the power status")
|
||||
field(DTYP, "stream")
|
||||
field(INP, "@slsvme.proto readonoff($(NO)) slsvme 0")
|
||||
field(SCAN, "1 second")
|
||||
field(ZNAM, "off")
|
||||
field(ONAM, "on")
|
||||
}
|
||||
|
||||
##
|
||||
## Set the power status
|
||||
##
|
||||
record(bo, "$(PREFIX)PowerStatus") {
|
||||
field(DESC, "Set the power status")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@slsvme.proto setpower($(NO)) slsvme 0")
|
||||
field(ZNAM, "on")
|
||||
field(ONAM, "off")
|
||||
}
|
31
sinqEPICSApp/Db/slsvme.proto
Normal file
31
sinqEPICSApp/Db/slsvme.proto
Normal file
@ -0,0 +1,31 @@
|
||||
# Streamdevice protocol file for the PSI SLS VME magnet controller used at AMOR
|
||||
|
||||
InTerminator = "\n";
|
||||
OutTerminator = "\r\n";
|
||||
#ExtraInput = Ignore;
|
||||
|
||||
read {
|
||||
out "r \$1 \$2";
|
||||
in "\$1 \$2 %f";
|
||||
}
|
||||
|
||||
readErrTxt {
|
||||
out "r \$1 errtext";
|
||||
in "\$1 errtext %s";
|
||||
}
|
||||
|
||||
|
||||
write {
|
||||
out "w \$1 \$2 %f";
|
||||
in "OK";
|
||||
}
|
||||
|
||||
readonoff {
|
||||
out "r \$1 onoff";
|
||||
in "\$1 onoff %{off|on}";
|
||||
}
|
||||
|
||||
setpower {
|
||||
out "w \$1 %{on|off}";
|
||||
in "OK";
|
||||
}
|
32
sinqEPICSApp/Db/spsamor.db
Normal file
32
sinqEPICSApp/Db/spsamor.db
Normal file
@ -0,0 +1,32 @@
|
||||
# DB definition for a SPS-S5 with the custom RS232 interface as used at SINQ.
|
||||
|
||||
#The digital inputs. Ignore the first one, which is the response character R
|
||||
|
||||
record(waveform, "$(PREFIX)DigitalInput") {
|
||||
field(DTYP, "stream")
|
||||
field(INP, "@spss5.proto readDigital() spss5 0")
|
||||
field(SCAN, "5 second")
|
||||
field(NELM, "16")
|
||||
field(FTVL, "LONG")
|
||||
field(PREC, "1")
|
||||
}
|
||||
|
||||
# The analog inputs, again ignore the first one as it is the response character A
|
||||
record(waveform, "$(PREFIX)AnalogInput") {
|
||||
field(DTYP, "stream")
|
||||
field(INP, "@spss5.proto readAnalog() spss5 0")
|
||||
field(SCAN, "5 second")
|
||||
field(NELM, "8")
|
||||
field(FTVL, "LONG")
|
||||
field(PREC, "1")
|
||||
}
|
||||
|
||||
# This is forwarding the S0001 style strings to the hardware. This is the easiest solution but requires
|
||||
# Hardware knowledge upstream. Which is required anyway. The syntax is: SBBBI with 3 characters for the byte
|
||||
# to set and one character for the bit in the byte. The Byte must always be filled with 0 to the left.
|
||||
record(stringout, "$(PREFIX)Push") {
|
||||
field(DESC, "String for pushing buttons")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@spss5.proto push() spss5 0")
|
||||
}
|
||||
|
25
sinqEPICSApp/Db/spss5.proto
Normal file
25
sinqEPICSApp/Db/spss5.proto
Normal file
@ -0,0 +1,25 @@
|
||||
# Streamdevice protocol file for the Siemens SPS-S5 with the custom RS232 interface as used at
|
||||
# AMOR
|
||||
|
||||
InTerminator = "\n";
|
||||
OutTerminator = "\r\n";
|
||||
ExtraInput = Ignore;
|
||||
|
||||
|
||||
readDigital {
|
||||
out "R";
|
||||
separator="";
|
||||
in "\?%d";
|
||||
}
|
||||
|
||||
readAnalog {
|
||||
out "A";
|
||||
separator="";
|
||||
in "\?%d";
|
||||
}
|
||||
|
||||
|
||||
push {
|
||||
out "%s";
|
||||
}
|
||||
|
@ -5,6 +5,10 @@ USAGE... Motor driver support for the PSI EL734 controller.
|
||||
Mark Koennecke
|
||||
February 2013
|
||||
|
||||
Updated to have an MsgTxt field through SINQAxis, error handling
|
||||
|
||||
Mark Koennecke, May, August 2017
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@ -33,18 +37,14 @@ February 2013
|
||||
* \param[in] numAxes The number of axes that this controller supports
|
||||
*/
|
||||
EL734Controller::EL734Controller(const char *portName, const char *EL734PortName, int numAxes)
|
||||
: asynMotorController(portName, numAxes+1, 0,
|
||||
0, // No additional interfaces beyond those in base class
|
||||
0, // No additional callback interfaces beyond those in base class
|
||||
ASYN_CANBLOCK | ASYN_MULTIDEVICE,
|
||||
1, // autoconnect
|
||||
0, 0) // Default priority and stack size
|
||||
: SINQController(portName, EL734PortName, numAxes)
|
||||
{
|
||||
int axis;
|
||||
asynStatus status;
|
||||
EL734Axis *pAxis;
|
||||
static const char *functionName = "EL734Controller::EL734Controller";
|
||||
|
||||
|
||||
/* Connect to EL734 controller */
|
||||
status = pasynOctetSyncIO->connect(EL734PortName, 0, &pasynUserController_, NULL);
|
||||
if (status) {
|
||||
@ -138,18 +138,22 @@ void EL734Controller::switchRemote()
|
||||
* \param[out] reply The controllers reply
|
||||
*/
|
||||
|
||||
asynStatus EL734Controller::transactController(char command[COMLEN], char reply[COMLEN])
|
||||
asynStatus EL734Controller::transactController(int axisNo,char command[COMLEN], char reply[COMLEN])
|
||||
{
|
||||
asynStatus status;
|
||||
size_t in, out, i;
|
||||
int reason;
|
||||
char myReply[COMLEN];
|
||||
char myReply[COMLEN], errTxt[256];
|
||||
SINQAxis *axis = getAxis(axisNo);
|
||||
|
||||
pasynOctetSyncIO->flush(pasynUserController_);
|
||||
|
||||
status = pasynOctetSyncIO->writeRead(pasynUserController_, command, strlen(command),
|
||||
reply,COMLEN, 1.,&out,&in,&reason);
|
||||
if(status != asynSuccess){
|
||||
if(axis!= NULL){
|
||||
axis->updateMsgTxtFromDriver("Lost connection to motor controller");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -178,13 +182,25 @@ asynStatus EL734Controller::transactController(char command[COMLEN], char reply[
|
||||
myReply[i] = (char)tolower((int)reply[i]);
|
||||
}
|
||||
if(strstr(myReply,"?cmd") != NULL){
|
||||
errlogSevPrintf(errlogMajor, "Bad command %s", command);
|
||||
snprintf(errTxt,sizeof(errTxt), "Bad command %s at axis %d", command, axisNo);
|
||||
errlogSevPrintf(errlogMajor, errTxt);
|
||||
if(axis!= NULL){
|
||||
axis->updateMsgTxtFromDriver(errTxt);
|
||||
}
|
||||
return asynError;
|
||||
} else if(strstr(myReply,"?par") != NULL){
|
||||
errlogSevPrintf(errlogMajor, "Bad parameter in command %s", command);
|
||||
snprintf(errTxt,sizeof(errTxt), "Bad parameter in command %s", command);
|
||||
errlogSevPrintf(errlogMajor, errTxt);
|
||||
if(axis!= NULL){
|
||||
axis->updateMsgTxtFromDriver(errTxt);
|
||||
}
|
||||
return asynError;
|
||||
} else if(strstr(myReply,"?rng") != NULL){
|
||||
errlogSevPrintf(errlogMajor, "Parameter out of range in command %s", command);
|
||||
snprintf(errTxt,sizeof(errTxt), "Parameter out of range in command %s", command);
|
||||
errlogSevPrintf(errlogMajor, errTxt);
|
||||
if(axis!= NULL){
|
||||
axis->updateMsgTxtFromDriver(errTxt);
|
||||
}
|
||||
return asynError;
|
||||
}
|
||||
|
||||
@ -200,8 +216,7 @@ asynStatus EL734Controller::transactController(char command[COMLEN], char reply[
|
||||
* Initializes register numbers, etc.
|
||||
*/
|
||||
EL734Axis::EL734Axis(EL734Controller *pC, int axisNo)
|
||||
: asynMotorAxis(pC, axisNo),
|
||||
pC_(pC)
|
||||
: SINQAxis(pC, axisNo), pC_(pC)
|
||||
{
|
||||
}
|
||||
|
||||
@ -239,7 +254,7 @@ asynStatus EL734Axis::move(double position, int relative, double minVelocity, do
|
||||
oredMSR = 0;
|
||||
homing = 0;
|
||||
sprintf(command, "p %d %.3f", axisNo_, position/1000.);
|
||||
status = pC_->transactController(command,reply);
|
||||
status = pC_->transactController(axisNo_,command,reply);
|
||||
next_poll = -1;
|
||||
return status;
|
||||
}
|
||||
@ -255,7 +270,7 @@ asynStatus EL734Axis::home(double minVelocity, double maxVelocity, double accele
|
||||
sprintf(command, "R %d", axisNo_);
|
||||
homing = 1;
|
||||
next_poll= -1;
|
||||
status = pC_->transactController(command,reply);
|
||||
status = pC_->transactController(axisNo_,command,reply);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -277,7 +292,7 @@ asynStatus EL734Axis::moveVelocity(double minVelocity, double maxVelocity, doubl
|
||||
/* This is a negative move */
|
||||
sprintf(command, "FB %d", axisNo_);
|
||||
}
|
||||
status = pC_->transactController(command,reply);
|
||||
status = pC_->transactController(axisNo_,command,reply);
|
||||
next_poll = -1;
|
||||
return status;
|
||||
}
|
||||
@ -289,8 +304,9 @@ asynStatus EL734Axis::stop(double acceleration )
|
||||
char command[COMLEN], reply[COMLEN];
|
||||
|
||||
sprintf(command, "S %d", axisNo_);
|
||||
status = pC_->transactController(command,reply);
|
||||
status = pC_->transactController(axisNo_,command,reply);
|
||||
errlogPrintf("Sent STOP on Axis %d\n", axisNo_);
|
||||
updateMsgTxtFromDriver("Axis interrupted");
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -302,7 +318,7 @@ asynStatus EL734Axis::setPosition(double position)
|
||||
char command[COMLEN], reply[COMLEN];
|
||||
|
||||
sprintf(command, "P %d %f", axisNo_, position/1000.);
|
||||
status = pC_->transactController(command,reply);
|
||||
status = pC_->transactController(axisNo_,command,reply);
|
||||
next_poll = -1;
|
||||
|
||||
return status;
|
||||
@ -328,9 +344,10 @@ asynStatus EL734Axis::setClosedLoop(bool closedLoop)
|
||||
* \param[out] moving A flag that is set indicating that the axis is moving (true) or done (false). */
|
||||
asynStatus EL734Axis::poll(bool *moving)
|
||||
{
|
||||
int msr;
|
||||
int msr, count;
|
||||
asynStatus comStatus;
|
||||
char command[COMLEN], reply[COMLEN];
|
||||
char command[COMLEN], reply[COMLEN], errTxt[256];
|
||||
int driverError = 0;
|
||||
|
||||
|
||||
// protect against excessive polling
|
||||
@ -341,19 +358,32 @@ asynStatus EL734Axis::poll(bool *moving)
|
||||
|
||||
// Read the current motor position
|
||||
sprintf(command,"u %d", axisNo_);
|
||||
comStatus = pC_->transactController(command,reply);
|
||||
comStatus = pC_->transactController(axisNo_,command,reply);
|
||||
if(comStatus == asynError){
|
||||
driverError = 1;
|
||||
}
|
||||
if(comStatus) goto skip;
|
||||
if(strstr(reply,"*ES") != NULL){
|
||||
*moving = false;
|
||||
setIntegerParam(pC_->motorStatusDone_, true);
|
||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||
updateMsgTxtFromDriver("Emergency Stop Engaged");
|
||||
driverError = 1;
|
||||
goto skip;
|
||||
} else if(strstr(reply,"?BSY") != NULL){
|
||||
*moving = true;
|
||||
setIntegerParam(pC_->motorStatusDone_, false);
|
||||
updateMsgTxtFromDriver(NULL);
|
||||
goto skip;
|
||||
}
|
||||
count = sscanf(reply,"%lf", &position);
|
||||
if(count != 1) {
|
||||
snprintf(errTxt,sizeof(errTxt),"Bad reply %s when reading position for %d", reply, axisNo_);
|
||||
updateMsgTxtFromDriver(errTxt);
|
||||
comStatus = asynError;
|
||||
driverError =1;
|
||||
goto skip;
|
||||
}
|
||||
sscanf(reply,"%lf", &position);
|
||||
//errlogPrintf("Axis %d, reply %s, position %lf\n", axisNo_, reply, position);
|
||||
setDoubleParam(pC_->motorPosition_, position*1000);
|
||||
//setDoubleParam(pC_->motorEncoderPosition_, position);
|
||||
@ -361,7 +391,7 @@ asynStatus EL734Axis::poll(bool *moving)
|
||||
|
||||
// Read the moving status of this motor
|
||||
sprintf(command,"msr %d",axisNo_);
|
||||
comStatus = pC_->transactController(command,reply);
|
||||
comStatus = pC_->transactController(axisNo_,command,reply);
|
||||
if(comStatus) goto skip;
|
||||
sscanf(reply,"%x",&msr);
|
||||
// errlogPrintf("Axis %d, reply %s, msr %d, position = %lf\n",
|
||||
@ -373,11 +403,15 @@ asynStatus EL734Axis::poll(bool *moving)
|
||||
next_poll = time(NULL)+IDLEPOLL;
|
||||
if(oredMSR & 0x10){
|
||||
setIntegerParam(pC_->motorStatusLowLimit_, true);
|
||||
updateMsgTxtFromDriver("Lower Limit Hit");
|
||||
driverError = 1;
|
||||
} else {
|
||||
setIntegerParam(pC_->motorStatusLowLimit_, false);
|
||||
}
|
||||
if(oredMSR & 0x20){
|
||||
setIntegerParam(pC_->motorStatusHighLimit_, true);
|
||||
updateMsgTxtFromDriver("Upper Limit Hit");
|
||||
driverError = 1;
|
||||
} else {
|
||||
setIntegerParam(pC_->motorStatusHighLimit_, false);
|
||||
}
|
||||
@ -388,20 +422,29 @@ asynStatus EL734Axis::poll(bool *moving)
|
||||
if(oredMSR &0x1000){
|
||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||
errlogSevPrintf(errlogMajor, "Air cushion problem on %d", axisNo_);
|
||||
updateMsgTxtFromDriver("Air cushion error");
|
||||
driverError = 1;
|
||||
}
|
||||
if(oredMSR &0x80){
|
||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||
errlogSevPrintf(errlogMajor, "Positioning fault at %d", axisNo_);
|
||||
updateMsgTxtFromDriver("Positioning fault");
|
||||
driverError = 1;
|
||||
}
|
||||
*moving = false;
|
||||
setIntegerParam(pC_->motorStatusDone_, true);
|
||||
//updateMsgTxtFromDriver("Believed to be on position");
|
||||
} else {
|
||||
*moving = true;
|
||||
next_poll = -1;
|
||||
setIntegerParam(pC_->motorStatusDone_, false);
|
||||
//updateMsgTxtFromDriver("Creeping");
|
||||
}
|
||||
|
||||
skip:
|
||||
if(driverError == 0){
|
||||
updateMsgTxtFromDriver(NULL);
|
||||
}
|
||||
setIntegerParam(pC_->motorStatusProblem_, comStatus ? 1:0);
|
||||
callParamCallbacks();
|
||||
return comStatus ? asynError : asynSuccess;
|
||||
|
@ -7,13 +7,13 @@ February 2013
|
||||
|
||||
*/
|
||||
|
||||
#include "asynMotorController.h"
|
||||
#include "asynMotorAxis.h"
|
||||
#include "SINQController.h"
|
||||
#include "SINQAxis.h"
|
||||
|
||||
#define MAX_EL734_AXES 12
|
||||
#define COMLEN 80
|
||||
|
||||
class EL734Axis : public asynMotorAxis
|
||||
class EL734Axis : public SINQAxis
|
||||
{
|
||||
public:
|
||||
/* These are the methods we override from the base class */
|
||||
@ -34,11 +34,14 @@ private:
|
||||
double position;
|
||||
int homing;
|
||||
time_t next_poll;
|
||||
int ErrTxtIdx;
|
||||
|
||||
void forwardErrorTxt(EL734Axis *axis);
|
||||
|
||||
friend class EL734Controller;
|
||||
};
|
||||
|
||||
class EL734Controller : public asynMotorController {
|
||||
class EL734Controller : public SINQController {
|
||||
public:
|
||||
EL734Controller(const char *portName, const char *EL734PortName, int numAxes);
|
||||
|
||||
@ -50,7 +53,7 @@ friend class EL734Axis;
|
||||
private:
|
||||
asynUser *pasynUserController_;
|
||||
|
||||
asynStatus transactController(char command[COMLEN], char reply[COMLEN]);
|
||||
asynStatus transactController(int axis, char command[COMLEN], char reply[COMLEN]);
|
||||
|
||||
void switchRemote();
|
||||
|
||||
|
@ -17,14 +17,14 @@ sinqEPICS_DBD += base.dbd
|
||||
|
||||
# Include dbd files from all support applications:
|
||||
sinqEPICS_DBD += sinq.dbd
|
||||
sinqEPICS_DBD += pmacAsynIPPort.dbd pmacAsynMotorPort.dbd
|
||||
#sinqEPICS_DBD += pmacAsynIPPort.dbd pmacAsynMotorPort.dbd
|
||||
|
||||
# Add all the support libraries needed by this IOC
|
||||
sinqEPICS_LIBS += motor asyn std anc350 anc350AsynMotor stream busy
|
||||
sinqEPICS_LIBS += motor asyn busy synAppsStd streamdevice pcre
|
||||
|
||||
# sinqEPICS_registerRecordDeviceDriver.cpp derives from sinqEPICS.dbd
|
||||
sinqEPICS_SRCS += sinqEPICS_registerRecordDeviceDriver.cpp
|
||||
sinqEPICS_SRCS += EL734Driver.cpp devScalerEL737.c pmacAsynIPPort.c
|
||||
sinqEPICS_SRCS += EL734Driver.cpp devScalerEL737.c pmacAsynIPPort.c SINQAxis.cpp SINQController.cpp
|
||||
sinqEPICS_SRCS += pmacController.cpp pmacAxis.cpp
|
||||
sinqEPICS_SRCS += NanotecDriver.cpp stptok.cpp
|
||||
sinqEPICS_SRCS += PhytronDriver.cpp
|
||||
|
36
sinqEPICSApp/src/SINQAxis.cpp
Normal file
36
sinqEPICSApp/src/SINQAxis.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
This is a version of the motor axis record which adds code for having an
|
||||
text field with an error message to go with the motor. The code is
|
||||
courtesey Torsten Boergershausen from ESS and from the axisRecord.
|
||||
|
||||
Mark Koennecke, March 2017
|
||||
*/
|
||||
#include "SINQAxis.h"
|
||||
#include "SINQController.h"
|
||||
|
||||
SINQAxis::SINQAxis(class SINQController *pC, int axis)
|
||||
: asynMotorAxis((asynMotorController *)pC, axis),
|
||||
pC_(pC)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SINQAxis::updateMsgTxtFromDriver(const char *value)
|
||||
{
|
||||
if (value && value[0]) {
|
||||
pC_->setIntegerParam(axisNo_,pC_->motorMessageIsFromDriver_, 1);
|
||||
setStringParam(pC_->motorMessageText_,value);
|
||||
} else {
|
||||
pC_->setIntegerParam(axisNo_,pC_->motorMessageIsFromDriver_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for a string for this axis in the parameter library.
|
||||
* \param[in] function The function (parameter) number
|
||||
* \param[in] value Value to set */
|
||||
asynStatus SINQAxis::setStringParam(int function, const char *value)
|
||||
{
|
||||
// Call the base class method
|
||||
return pC_->setStringParam(axisNo_, function, value);
|
||||
}
|
30
sinqEPICSApp/src/SINQAxis.h
Normal file
30
sinqEPICSApp/src/SINQAxis.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
This is a version of the motor axis record which adds code for having an
|
||||
text field with an error message to go with the motor. The code is
|
||||
courtesey Torsten Boergershausen from ESS and from the axisRecord.
|
||||
|
||||
Mark Koennecke, March 2017
|
||||
*/
|
||||
#ifndef __SINQDRIVER
|
||||
#define __SINQDRIVER
|
||||
#include "asynMotorAxis.h"
|
||||
|
||||
class epicsShareClass SINQAxis : public asynMotorAxis
|
||||
{
|
||||
public:
|
||||
SINQAxis(class SINQController *pC_, int axis);
|
||||
asynStatus setStringParam(int function, const char *value);
|
||||
|
||||
friend class SINQController;
|
||||
void updateMsgTxtFromDriver(const char *value);
|
||||
|
||||
protected:
|
||||
private:
|
||||
SINQController *pC_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
25
sinqEPICSApp/src/SINQController.cpp
Normal file
25
sinqEPICSApp/src/SINQController.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
This class contains the necessary changes to have an additional text fields for messages
|
||||
with each axis.
|
||||
|
||||
Code lifted from Torsten Boegershausen ESS code.
|
||||
|
||||
Mark Koennecke, March 2017
|
||||
*/
|
||||
|
||||
#include "SINQController.h"
|
||||
#include "asynMotorController.h"
|
||||
|
||||
SINQController::SINQController(const char *portName, const char *SINQPortName, int numAxes)
|
||||
: asynMotorController(portName, numAxes+1, NUM_MOTOR_DRIVER_PARAMS+2,
|
||||
0, // No additional interfaces beyond those in base class
|
||||
0, // No additional callback interfaces beyond those in base class
|
||||
ASYN_CANBLOCK | ASYN_MULTIDEVICE,
|
||||
1, // autoconnect
|
||||
0, 0) // Default priority and stack size
|
||||
{
|
||||
createParam(motorMessageIsFromDriverString, asynParamInt32, &motorMessageIsFromDriver_);
|
||||
createParam(motorMessageTextString, asynParamOctet, &motorMessageText_);
|
||||
}
|
||||
|
||||
|
30
sinqEPICSApp/src/SINQController.h
Normal file
30
sinqEPICSApp/src/SINQController.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
This class contains the necessary changes to have an additional text fields for messages
|
||||
with each axis.
|
||||
|
||||
Code lifted from Torsten Boegershausens ESS code.
|
||||
|
||||
Mark Koennecke, March 2017
|
||||
*/
|
||||
|
||||
#ifndef __SINQCONTROLLER
|
||||
#define __SINQCONTROLLER
|
||||
#include "asynMotorController.h"
|
||||
|
||||
#define motorMessageIsFromDriverString "MOTOR_MESSAGE_DRIVER"
|
||||
#define motorMessageTextString "MOTOR_MESSAGE_TEXT"
|
||||
|
||||
class epicsShareClass SINQController : public asynMotorController
|
||||
{
|
||||
public:
|
||||
SINQController(const char *portName, const char *SINQPortName, int numAxes);
|
||||
|
||||
friend class SINQAxis;
|
||||
protected:
|
||||
int motorMessageIsFromDriver_;
|
||||
int motorMessageText_;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,7 @@
|
||||
* - Thresholding
|
||||
* - two count modes
|
||||
* A better solution would be to extend the scalar record to have a proper status and count
|
||||
* mode field. And threshold control fileds too. But this is much more work, breaks
|
||||
* mode field. And threshold control fields too. But this is much more work, breaks
|
||||
* compatability with the scalar record completely and thus was not done for now.
|
||||
*
|
||||
* The driver will run a separate thread which does all the
|
||||
@ -27,6 +27,16 @@
|
||||
*
|
||||
* Mark Koennecke, February 2013
|
||||
*
|
||||
* Enhanced by adding an addtional external pause and status flag in the databse and code in here
|
||||
* to handle this. Moreover an external MsgTxt field in the DB can be filled with an error message.
|
||||
*
|
||||
* Mark Koennecke, July 2017
|
||||
*
|
||||
* Enhanced with a separate thresholdCounter and threshold field in order to replace the
|
||||
* hack for threshold handling. If these fields are present, the hack with presets 2 and
|
||||
* 3 as described above is ignored.
|
||||
*
|
||||
* Mark Koennecke, August 2017
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -40,6 +50,10 @@
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <cantProceed.h>
|
||||
#include <dbDefs.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <dbAccess.h>
|
||||
#include <errlog.h>
|
||||
|
||||
#include <scalerRecord.h>
|
||||
#include <devScaler.h>
|
||||
@ -49,7 +63,7 @@
|
||||
/* dset functions */
|
||||
static long el737_init_record(struct scalerRecord *psr, CALLBACK *pcallback);
|
||||
static long el737_reset(scalerRecord *psr);
|
||||
static long el737_read(scalerRecord *psr, unsigned long *val);
|
||||
static long el737_read(scalerRecord *psr, epicsUInt32 *val);
|
||||
static long el737_write_preset(scalerRecord *psr, int signal, unsigned long val);
|
||||
static long el737_arm(scalerRecord *psr, int val);
|
||||
static long el737_done(scalerRecord *psr);
|
||||
@ -84,17 +98,87 @@ typedef struct {
|
||||
unsigned long values[NCOUNT];
|
||||
unsigned int countCommand;
|
||||
unsigned int counting;
|
||||
unsigned long thresholdValue;
|
||||
unsigned int sendThreshold;
|
||||
scalerRecord *psr;
|
||||
epicsEventId wakeUp;
|
||||
asynUser *asynContext;
|
||||
CALLBACK *pcallback;
|
||||
DBADDR pause;
|
||||
DBADDR status;
|
||||
DBADDR msgTxt;
|
||||
DBADDR threshCounter;
|
||||
DBADDR threshold;
|
||||
unsigned int dbInit;
|
||||
}EL737priv;
|
||||
|
||||
static void dummyAsynCallback(asynUser *pasynUser)
|
||||
{
|
||||
}
|
||||
|
||||
static void connectSlaveRecords(EL737priv *priv)
|
||||
{
|
||||
char slaveName[PVNAME_SZ], errName[256];
|
||||
long status;
|
||||
|
||||
priv->dbInit = 1;
|
||||
snprintf(slaveName,sizeof(slaveName),"%s:Pause", priv->psr->name);
|
||||
errlogPrintf("Name of pause variable: %s\n", slaveName);
|
||||
status = dbNameToAddr(slaveName,&priv->pause);
|
||||
if(status!= 0){
|
||||
errSymLookup(status,errName,sizeof(errName));
|
||||
errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, errName);
|
||||
priv->dbInit = 0;
|
||||
} else {
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",slaveName, priv->pause.precord->name);
|
||||
}
|
||||
|
||||
snprintf(slaveName,sizeof(slaveName),"%s:MsgTxt", priv->psr->name);
|
||||
errlogPrintf("Name of MsgTxt variable: %s\n", slaveName);
|
||||
status = dbNameToAddr(slaveName,&priv->msgTxt);
|
||||
if(status!= 0){
|
||||
errSymLookup(status,errName,sizeof(errName));
|
||||
errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, errName);
|
||||
priv->dbInit = 0;
|
||||
} else {
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",slaveName, priv->msgTxt.precord->name);
|
||||
}
|
||||
|
||||
snprintf(slaveName,sizeof(slaveName),"%s:Status", priv->psr->name);
|
||||
errlogPrintf("Name of status variable: %s\n", slaveName);
|
||||
status = dbNameToAddr(slaveName,&priv->status);
|
||||
if(status!= 0){
|
||||
errSymLookup(status,errName,sizeof(errName));
|
||||
errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, errName);
|
||||
priv->dbInit = 0;
|
||||
} else {
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",slaveName, priv->status.precord->name);
|
||||
}
|
||||
|
||||
snprintf(slaveName,sizeof(slaveName),"%s:ThresholdCounter", priv->psr->name);
|
||||
errlogPrintf("Name of thresholdCounter variable: %s\n", slaveName);
|
||||
status = dbNameToAddr(slaveName,&priv->threshCounter);
|
||||
if(status!= 0){
|
||||
errSymLookup(status,errName,sizeof(errName));
|
||||
errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, errName);
|
||||
priv->dbInit = 0;
|
||||
} else {
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",slaveName, priv->status.precord->name);
|
||||
}
|
||||
|
||||
snprintf(slaveName,sizeof(slaveName),"%s:Threshold", priv->psr->name);
|
||||
errlogPrintf("Name of thresholdCounter variable: %s\n", slaveName);
|
||||
status = dbNameToAddr(slaveName,&priv->threshold);
|
||||
if(status!= 0){
|
||||
errSymLookup(status,errName,sizeof(errName));
|
||||
errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, errName);
|
||||
priv->dbInit = 0;
|
||||
} else {
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",slaveName, priv->status.precord->name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
||||
{
|
||||
EL737priv *priv = NULL;
|
||||
@ -122,7 +206,9 @@ static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
||||
priv->psr = psr;
|
||||
priv->wakeUp = epicsEventCreate(epicsEventEmpty);
|
||||
priv->pcallback = pcallback;
|
||||
priv->dbInit = 0;
|
||||
psr->dpvt = priv;
|
||||
|
||||
|
||||
/*
|
||||
* Hook up with device
|
||||
@ -148,6 +234,8 @@ static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
||||
pasynOctetSyncIO->setInputEos(priv->asynContext,"\r",strlen("\r"));
|
||||
priv->asynContext->timeout = 1.0;
|
||||
strcpy(command,"RMT 1");
|
||||
pasynOctetSyncIO->writeRead(priv->asynContext, command, strlen(command),
|
||||
reply,sizeof(reply), 1.,&out,&in,&reason);
|
||||
pasynOctetSyncIO->writeRead(priv->asynContext, command, strlen(command),
|
||||
reply,sizeof(reply), 1.,&out,&in,&reason);
|
||||
strcpy(command,"ECHO 2");
|
||||
@ -155,6 +243,7 @@ static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
||||
reply,sizeof(reply), 1.,&out,&in,&reason);
|
||||
pasynManager->freeAsynUser(dummyUser);
|
||||
|
||||
connectSlaveRecords(priv);
|
||||
|
||||
/*
|
||||
start the thread which actually runs the device
|
||||
@ -181,14 +270,14 @@ static long el737_reset(scalerRecord *psr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long el737_read(scalerRecord *psr, unsigned long *val)
|
||||
static long el737_read(scalerRecord *psr, epicsUInt32 *val)
|
||||
{
|
||||
unsigned int i;
|
||||
EL737priv *priv;
|
||||
|
||||
priv = (EL737priv *)psr->dpvt;
|
||||
for(i = 0; i < NCOUNT; i++){
|
||||
val[i] = priv->values[i];
|
||||
val[i] = (epicsUInt32)priv->values[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -245,27 +334,63 @@ static long el737_done(scalerRecord *psr)
|
||||
}
|
||||
}
|
||||
|
||||
static asynStatus el737_transactCommand(asynUser *asynContext, char command[COMLEN],char reply[COMLEN])
|
||||
static asynStatus el737_transactCommand(EL737priv *priv,char command[COMLEN],char reply[COMLEN])
|
||||
{
|
||||
asynStatus status;
|
||||
size_t in, out;
|
||||
int reason;
|
||||
char myCommand[COMLEN];
|
||||
int reason, dbStatus;
|
||||
char myCommand[COMLEN], message[40];
|
||||
|
||||
pasynOctetSyncIO->flush(asynContext);
|
||||
pasynOctetSyncIO->flush(priv->asynContext);
|
||||
|
||||
status = pasynOctetSyncIO->writeRead(asynContext, command, strlen(command),
|
||||
strcpy(message,"OK");
|
||||
status = pasynOctetSyncIO->writeRead(priv->asynContext, command, strlen(command),
|
||||
reply,COMLEN, 1.,&out,&in,&reason);
|
||||
if(status == asynSuccess){
|
||||
if(strstr(reply,"?OF") != NULL){
|
||||
strcpy(myCommand,"RMT 1");
|
||||
status = pasynOctetSyncIO->writeRead(asynContext, myCommand, strlen(myCommand),
|
||||
status = pasynOctetSyncIO->writeRead(priv->asynContext, myCommand, strlen(myCommand),
|
||||
reply,COMLEN, 1.,&out,&in,&reason);
|
||||
strcpy(myCommand,"ECHO 2");
|
||||
status = pasynOctetSyncIO->writeRead(asynContext, myCommand, strlen(myCommand),
|
||||
status = pasynOctetSyncIO->writeRead(priv->asynContext, myCommand, strlen(myCommand),
|
||||
reply,COMLEN, 1.,&out,&in,&reason);
|
||||
return pasynOctetSyncIO->writeRead(asynContext, command, strlen(command),
|
||||
return pasynOctetSyncIO->writeRead(priv->asynContext, command, strlen(command),
|
||||
reply,COMLEN, 1.,&out,&in,&reason);
|
||||
} else {
|
||||
if(strstr(reply,"?OV") != NULL){
|
||||
strncpy(message,"Overflow",sizeof(message));
|
||||
} else if(strstr(reply,"?1") != NULL) {
|
||||
strncpy(message,"Par out of range",sizeof(message));
|
||||
} else if(strstr(reply,"?2") != NULL){
|
||||
strncpy(message,"Bad command",sizeof(message));
|
||||
} else if(strstr(reply,"?3") != NULL){
|
||||
strncpy(message,"Bad parameter",sizeof(message));
|
||||
} else if(strstr(reply,"?4") != NULL){
|
||||
strncpy(message,"Bad counter",sizeof(message));
|
||||
} else if(strstr(reply,"?5") != NULL){
|
||||
strncpy(message,"Parameter missing",sizeof(message));
|
||||
} else if(strstr(reply,"?6") != NULL){
|
||||
strncpy(message,"to many counts",sizeof(message));
|
||||
} else if(strstr(reply,"?91") != NULL){
|
||||
strncpy(message,"Start Failure",sizeof(message));
|
||||
} else if(strstr(reply,"?92") != NULL){
|
||||
strncpy(message,"Failure while counting",sizeof(message));
|
||||
} else if(strstr(reply,"?93") != NULL){
|
||||
strncpy(message,"Read Failure",sizeof(message));
|
||||
} else {
|
||||
if(strstr(reply,"?") != NULL) {
|
||||
snprintf(message,sizeof(message),"HW error: %s", reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
strncpy(message,"Lost communication",sizeof(message));
|
||||
}
|
||||
if(priv->dbInit){
|
||||
dbStatus = dbPutField(&priv->msgTxt, DBR_STRING,message, 1);
|
||||
if(dbStatus!= 0){
|
||||
errSymLookup(dbStatus,message,sizeof(message));
|
||||
errlogPrintf("Setting external count message failed with %s\n", message);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@ -276,21 +401,56 @@ static asynStatus sendStop(EL737priv *priv)
|
||||
char command[COMLEN], reply[COMLEN];
|
||||
//errlogPrintf("Sending stop\n");
|
||||
strcpy(command,"S");
|
||||
return el737_transactCommand(priv->asynContext,command,reply);
|
||||
return el737_transactCommand(priv,command,reply);
|
||||
}
|
||||
|
||||
static void runEvents(EL737priv *priv)
|
||||
{
|
||||
char command[COMLEN], reply[COMLEN];
|
||||
char command[COMLEN], reply[COMLEN], errName[256];
|
||||
int status;
|
||||
long dbStatus, myThreshold, nElements = 1, options = 0, threshCounter;
|
||||
|
||||
/*
|
||||
This is the better way to set the threshold rather then the old way below which uses
|
||||
presets for that function. This one uses separate fields.
|
||||
*/
|
||||
if(priv->dbInit == 1) {
|
||||
dbStatus = dbGetField(&priv->threshold,DBR_LONG,&myThreshold,&options, &nElements,NULL);
|
||||
if(dbStatus != 0){
|
||||
errSymLookup(dbStatus,errName,sizeof(errName));
|
||||
errlogPrintf("Reading threshold failed with %s\n", errName);
|
||||
} else {
|
||||
if(myThreshold != priv->thresholdValue){
|
||||
/*
|
||||
we have to set the threshold
|
||||
*/
|
||||
dbStatus = dbGetField(&priv->threshCounter,DBR_LONG,&threshCounter, &options, &nElements,NULL);
|
||||
if(dbStatus != 0){
|
||||
errSymLookup(dbStatus,errName,sizeof(errName));
|
||||
errlogPrintf("Reading thresholdCounter failed with %s\n", errName);
|
||||
} else {
|
||||
sprintf(command,"DL %d %d", (int)threshCounter,
|
||||
(int)myThreshold);
|
||||
//errlogPrintf("Sending threshold command %s\n", command);
|
||||
status = el737_transactCommand(priv,command,reply);
|
||||
sprintf(command,"DR %d", (int)threshCounter);
|
||||
status = el737_transactCommand(priv, command,reply);
|
||||
if(status == asynSuccess){
|
||||
priv->sendThreshold = 0;
|
||||
priv->thresholdValue = myThreshold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(priv->sendThreshold == 1){
|
||||
sprintf(command,"DL %d %d", (int)priv->presets[THRESHMON],
|
||||
(int)priv->presets[THRESHVAL]);
|
||||
//errlogPrintf("Sending threshold command %s\n", command);
|
||||
status = el737_transactCommand(priv->asynContext,command,reply);
|
||||
status = el737_transactCommand(priv,command,reply);
|
||||
sprintf(command,"DR %d", (int)priv->presets[THRESHMON]);
|
||||
status = el737_transactCommand(priv->asynContext,command,reply);
|
||||
status = el737_transactCommand(priv, command,reply);
|
||||
if(status == asynSuccess){
|
||||
priv->sendThreshold = 0;
|
||||
}
|
||||
@ -307,7 +467,7 @@ static void runEvents(EL737priv *priv)
|
||||
sprintf(command,"TP %f", priv->presets[TIMER]/1000.);
|
||||
//errlogPrintf("Starting preset timer\n");
|
||||
}
|
||||
status = el737_transactCommand(priv->asynContext,command,reply);
|
||||
status = el737_transactCommand(priv,command,reply);
|
||||
if(status == asynSuccess){
|
||||
priv->counting = 1;
|
||||
}
|
||||
@ -335,7 +495,7 @@ static void updateValues(EL737priv *priv)
|
||||
long m1, m2 ,m3, m4, m5, m6 ,m7, m8;
|
||||
|
||||
strcpy(command,"RA");
|
||||
status = el737_transactCommand(priv->asynContext,command,reply);
|
||||
status = el737_transactCommand(priv,command,reply);
|
||||
if(status != asynSuccess){
|
||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
||||
priv->asynContext->errorMessage);
|
||||
@ -371,9 +531,10 @@ static void el737Thread(void *param)
|
||||
EL737priv *priv = (EL737priv *)param;
|
||||
epicsEventWaitStatus evStatus;
|
||||
double timeout = 60.;
|
||||
char command[COMLEN], reply[COMLEN];
|
||||
char command[COMLEN], reply[COMLEN], errName[256];
|
||||
asynStatus status;
|
||||
int rs;
|
||||
int rs, ctStatus;
|
||||
long dbStatus, options, nElements = 1, pauseFlag = 0;
|
||||
|
||||
//errlogPrintf("Within EL737 thread \n");
|
||||
|
||||
@ -381,6 +542,7 @@ static void el737Thread(void *param)
|
||||
evStatus = epicsEventWaitWithTimeout(priv->wakeUp,timeout);
|
||||
//errlogPrintf("EL737 thread woke up with %d\n", evStatus);
|
||||
|
||||
|
||||
if(evStatus == epicsEventWaitOK) {
|
||||
/*
|
||||
FEAR: we received a command!!!!
|
||||
@ -402,7 +564,7 @@ static void el737Thread(void *param)
|
||||
|
||||
if(priv->counting) {
|
||||
strcpy(command,"RS");
|
||||
status = el737_transactCommand(priv->asynContext,command,reply);
|
||||
status = el737_transactCommand(priv, command,reply);
|
||||
if(status != asynSuccess){
|
||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
||||
priv->asynContext->errorMessage);
|
||||
@ -414,15 +576,57 @@ static void el737Thread(void *param)
|
||||
priv->counting = 0;
|
||||
timeout = 60.;
|
||||
priv->values[9] = 0;
|
||||
ctStatus = 0;
|
||||
} else if(rs == 1 || rs == 2){
|
||||
/* counting */
|
||||
priv->values[9] = 1;
|
||||
ctStatus = 1;
|
||||
} else if(rs == 5 || rs == 6){
|
||||
/* low rate */
|
||||
priv->values[9] = 2;
|
||||
ctStatus = 2;
|
||||
} else if(rs == 9 || rs == 13 || rs == 10 || rs == 14){
|
||||
/* low rate */
|
||||
priv->values[9] = 2;
|
||||
/* paused states */
|
||||
priv->values[9] = 3;
|
||||
ctStatus = 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(priv->dbInit){
|
||||
/*
|
||||
update the external status field
|
||||
*/
|
||||
dbStatus = dbPutField(&priv->status, DBR_LONG,&ctStatus, 1);
|
||||
if(dbStatus!= 0){
|
||||
errSymLookup(dbStatus,errName,sizeof(errName));
|
||||
errlogPrintf("Setting external count status failed with %s\n", errName);
|
||||
}
|
||||
|
||||
/*
|
||||
check and handle pause flag
|
||||
*/
|
||||
dbStatus = dbGetField(&priv->pause, DBR_LONG,&pauseFlag,&options, &nElements, NULL);
|
||||
if(dbStatus!= 0){
|
||||
errSymLookup(dbStatus,errName,sizeof(errName));
|
||||
errlogPrintf("Reading pauseFlag failed with %s\n", errName);
|
||||
}
|
||||
/* errlogPrintf("Successfully read %ld pause flags as %d\n",nElements, pauseFlag); */
|
||||
if(pauseFlag == 1 && ctStatus == 1){
|
||||
strcpy(command,"PS");
|
||||
status = el737_transactCommand(priv, command,reply);
|
||||
if(status != asynSuccess){
|
||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
||||
priv->asynContext->errorMessage);
|
||||
break;
|
||||
}
|
||||
} else if(pauseFlag == 0 && ctStatus == 3){
|
||||
strcpy(command,"CO");
|
||||
status = el737_transactCommand(priv,command,reply);
|
||||
if(status != asynSuccess){
|
||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
||||
priv->asynContext->errorMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,19 @@
|
||||
|
||||
record(scaler,"")
|
||||
record(bo,"$(P):Pause")
|
||||
{
|
||||
field(NAME,"NZ:counter")
|
||||
field(DESC,"NARZIS EL737 counter")
|
||||
field(DTYP,"asynScalerEL737")
|
||||
field(OUT,"INST_IO @asyn(cter1,0)"
|
||||
field(DTYP,"Soft Channel")
|
||||
}
|
||||
record(longin,"$(P):Status")
|
||||
{
|
||||
field(DTYP,"Soft Channel")
|
||||
}
|
||||
record(stringin,"$(P):MsgTxt")
|
||||
{
|
||||
field(DTYP,"Soft Channel")
|
||||
}
|
||||
record(scaler,"$(P)")
|
||||
{
|
||||
field(DESC,"$(DESC)")
|
||||
field(DTYP,"asynScalerEL737")
|
||||
field(OUT,"INST_IO @asyn($(PORT),0)")
|
||||
}
|
||||
|
||||
|
@ -2,23 +2,21 @@
|
||||
# SINQ specific DB definitions
|
||||
#---------------------------------------------
|
||||
registrar(EL734Register)
|
||||
registrar(PhytronRegister)
|
||||
registrar(NanotecRegister)
|
||||
addpath "/usr/local/epics/support/asyn-4-18/dbd"
|
||||
addpath "/usr/local/epics/dbd"
|
||||
addpath "/usr/local/epics/support/motor-6-7/dbd"
|
||||
addpath "/usr/local/epics/support/std-3-1/dbd"
|
||||
addpath "/usr/local/epics/anc350v17/dbd"
|
||||
include "drvAsynIPPort.dbd"
|
||||
include "motorRecord.dbd"
|
||||
include "motorSupport.dbd"
|
||||
include "anc350AsynMotor.dbd"
|
||||
addpath "/opt/epics/modules/asyn/4.27.0/3.14.12.5/dbd"
|
||||
addpath "/opt/epics/bases/base-3.14.12.5/dbd"
|
||||
addpath "/opt/epics/modules/motor/6.10.0/3.14.12.5/dbd"
|
||||
#addpath "/usr/local/epics/support/std-3-1/dbd"
|
||||
addpath "/opt/epics/modules/synAppsStd/3.4.1/3.14.12.5/dbd"
|
||||
include "asyn.dbd"
|
||||
include "motor.dbd"
|
||||
#include "motorSupport.dbd"
|
||||
|
||||
include "scalerRecord.dbd"
|
||||
include "synAppsStd.dbd"
|
||||
device(scaler,INST_IO,devScalerEL737,"asynScalerEL737")
|
||||
|
||||
#--------- For lakeshore
|
||||
addpath "/usr/local/epics/support/StreamDevice-2-6/dbd"
|
||||
include "stream.dbd"
|
||||
addpath "/usr/local/epics/support/busy-1-4/dbd"
|
||||
include "busySupport.dbd"
|
||||
addpath "/opt/epics/modules/streamdevice/2.6.0/3.14.12.5/dbd"
|
||||
include "streamdevice.dbd"
|
||||
addpath "/opt/epics/modules/busy/1.6.0/3.14.12.5/dbd"
|
||||
include "busy.dbd"
|
||||
|
7
testcter/startcter.cmd
Normal file
7
testcter/startcter.cmd
Normal file
@ -0,0 +1,7 @@
|
||||
require sinq,koennecke
|
||||
|
||||
epicsEnvSet("TOP","/afs/psi.ch/project/sinqdev/sinqepicsapp")
|
||||
|
||||
drvAsynIPPortConfigure("cter1","localhost:62000",0,0,0)
|
||||
dbLoadRecords("asynRecord.db","P=KM36:,R=cter1,PORT=cter1,ADDR=0,OMAX=80,IMAX=80")
|
||||
dbLoadRecords("${TOP}/sinqEPICSApp/Db/el737Record.db","P=KM36:counter,PORT=cter1,DESC=KM36Counter")
|
Reference in New Issue
Block a user