Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
7023f52336 | |||
83a995a16d | |||
124aa97cd6 | |||
bd3b808312 | |||
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
|
#Makefile at top of application tree
|
||||||
TOP = .
|
TOP = .
|
||||||
include $(TOP)/configure/CONFIG
|
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
|
# You must rebuild in the iocBoot directory for this to
|
||||||
# take effect.
|
# take effect.
|
||||||
#IOCS_APPL_TOP = </IOC/path/to/application/top>
|
#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
|
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
|
||||||
|
|
||||||
# EPICS_BASE usually appears last so other apps can override stuff:
|
# 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
|
# Set RULES here if you want to take build rules from somewhere
|
||||||
# other than EPICS_BASE:
|
# other than EPICS_BASE:
|
||||||
#RULES=/path/to/epics/support/module/rules/x-y
|
#RULES=/path/to/epics/support/module/rules/x-y
|
||||||
MOTOR=/usr/local/epics/support/motor-6-7
|
MOTOR=/opt/epics/modules/motor/6.10.0/3.14.12.5
|
||||||
ASYN=/usr/local/epics/support/asyn-4-18
|
ASYN=/opt/epics/modules/asyn/4.27.0/3.14.12.5
|
||||||
STD=/usr/local/epics/support/std-3-1
|
SYNAPPSSTD=/opt/epics/modules/synAppsStd/3.4.1/3.14.12.5/
|
||||||
ANC=/usr/local/epics/anc350v17
|
#ANC=/usr/local/epics/anc350v17
|
||||||
STREAMS=/usr/local/epics/support/StreamDevice-2-6
|
STREAMS=/opt/epics/modules/streamdevice/2.6.0/3.14.12.5
|
||||||
LAKESHORE336=/usr/local/epics/support/lakeshore336
|
#LAKESHORE336=/usr/local/epics/support/lakeshore336
|
||||||
BUSY=/usr/local/epics/support/busy-1-4
|
BUSY=/opt/epics/modules/busy/1.6.0/3.14.12.5
|
||||||
OXINSTCRYOJET=/usr/local/epics/support/OxInstCryojet-2-18-3
|
#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"
|
file "$(MOTOR)/db/basic_asyn_motor.db"
|
||||||
{
|
{
|
||||||
pattern
|
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:, 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:, 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:, 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:, 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, ""}
|
{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
|
< envPaths
|
||||||
|
|
||||||
cd ${TOP}
|
|
||||||
|
|
||||||
## Register all support components
|
## Register all support components
|
||||||
dbLoadDatabase "dbd/sinqEPICS.dbd"
|
dbLoadDatabase "dbd/sinqEPICS.dbd"
|
||||||
dbLoadDatabase "dbd/sinq.dbd"
|
dbLoadDatabase "dbd/sinq.dbd"
|
||||||
sinqEPICS_registerRecordDeviceDriver pdbbase
|
sinqEPICS_registerRecordDeviceDriver pdbbase
|
||||||
|
|
||||||
## Load record instances
|
|
||||||
#dbLoadRecords("db/xxx.db","user=koenneckeHost")
|
|
||||||
|
|
||||||
|
#---------- connect to controllers
|
||||||
#---------- load EL734 motor controller
|
drvAsynIPPortConfigure("serial1", "localhost:60001",0,0,0)
|
||||||
drvAsynIPPortConfigure("serial1", "narziss-ts:3002",0,0,0)
|
drvAsynIPPortConfigure("serial2", "localhost:60002",0,0,0)
|
||||||
#drvAsynIPPortConfigure("serial1", "localhost:8080",0,0,0)
|
drvAsynIPPortConfigure("serial3", "localhost:60003",0,0,0)
|
||||||
EL734CreateController("mota","serial1",6);
|
EL734CreateController("mota","serial1",12);
|
||||||
|
EL734CreateController("motb","serial2",12);
|
||||||
|
EL734CreateController("motc","serial3",12);
|
||||||
|
|
||||||
### Motors
|
### 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")
|
||||||
|
|
||||||
|
dbLoadTemplate "mota.substitutions"
|
||||||
cd ${TOP}/iocBoot/${IOC}
|
dbLoadTemplate "motb.substitutions"
|
||||||
dbLoadTemplate "motor.substitutions.el734"
|
dbLoadTemplate "motc.substitutions"
|
||||||
|
|
||||||
|
|
||||||
#--------- load EL737 counter box
|
#--------- load EL737 counter box
|
||||||
drvAsynIPPortConfigure("cter1","narziss-ts:3003",0,0,0)
|
drvAsynIPPortConfigure("cter1","localhost:62000",0,0,0)
|
||||||
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=NZ:,R=cter1,PORT=cter1,ADDR=0,OMAX=80,IMAX=80")
|
dbLoadRecords("$(ASYN)/db/asynRecord.db","P=SQ:AMOR:,R=cter1,PORT=cter1,ADDR=0,OMAX=80,IMAX=80")
|
||||||
dbLoadRecords("${TOP}/db/el737Record.db")
|
dbLoadRecords("${TOP}/db/el737Record.db")
|
||||||
|
|
||||||
asynSetTraceIOMask("cter1",0,2)
|
#asynSetTraceIOMask("cter1",0,2)
|
||||||
|
|
||||||
iocInit
|
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
|
# Create and install (or just install) into <top>/db
|
||||||
# databases, templates, substitutions like this
|
# databases, templates, substitutions like this
|
||||||
#DB += xxx.db
|
DB_INSTALL += slsvme.proto
|
||||||
|
|
||||||
#----------------------------------------------------
|
#----------------------------------------------------
|
||||||
# If <anyname>.db template is not named <anyname>*.template add
|
# 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
|
Mark Koennecke
|
||||||
February 2013
|
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
|
* \param[in] numAxes The number of axes that this controller supports
|
||||||
*/
|
*/
|
||||||
EL734Controller::EL734Controller(const char *portName, const char *EL734PortName, int numAxes)
|
EL734Controller::EL734Controller(const char *portName, const char *EL734PortName, int numAxes)
|
||||||
: asynMotorController(portName, numAxes+1, 0,
|
: SINQController(portName, EL734PortName, numAxes)
|
||||||
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
|
|
||||||
{
|
{
|
||||||
int axis;
|
int axis;
|
||||||
asynStatus status;
|
asynStatus status;
|
||||||
EL734Axis *pAxis;
|
EL734Axis *pAxis;
|
||||||
static const char *functionName = "EL734Controller::EL734Controller";
|
static const char *functionName = "EL734Controller::EL734Controller";
|
||||||
|
|
||||||
|
|
||||||
/* Connect to EL734 controller */
|
/* Connect to EL734 controller */
|
||||||
status = pasynOctetSyncIO->connect(EL734PortName, 0, &pasynUserController_, NULL);
|
status = pasynOctetSyncIO->connect(EL734PortName, 0, &pasynUserController_, NULL);
|
||||||
if (status) {
|
if (status) {
|
||||||
@ -138,18 +138,22 @@ void EL734Controller::switchRemote()
|
|||||||
* \param[out] reply The controllers reply
|
* \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;
|
asynStatus status;
|
||||||
size_t in, out, i;
|
size_t in, out, i;
|
||||||
int reason;
|
int reason;
|
||||||
char myReply[COMLEN];
|
char myReply[COMLEN], errTxt[256];
|
||||||
|
SINQAxis *axis = getAxis(axisNo);
|
||||||
|
|
||||||
pasynOctetSyncIO->flush(pasynUserController_);
|
pasynOctetSyncIO->flush(pasynUserController_);
|
||||||
|
|
||||||
status = pasynOctetSyncIO->writeRead(pasynUserController_, command, strlen(command),
|
status = pasynOctetSyncIO->writeRead(pasynUserController_, command, strlen(command),
|
||||||
reply,COMLEN, 1.,&out,&in,&reason);
|
reply,COMLEN, 1.,&out,&in,&reason);
|
||||||
if(status != asynSuccess){
|
if(status != asynSuccess){
|
||||||
|
if(axis!= NULL){
|
||||||
|
axis->updateMsgTxtFromDriver("Lost connection to motor controller");
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,13 +182,25 @@ asynStatus EL734Controller::transactController(char command[COMLEN], char reply[
|
|||||||
myReply[i] = (char)tolower((int)reply[i]);
|
myReply[i] = (char)tolower((int)reply[i]);
|
||||||
}
|
}
|
||||||
if(strstr(myReply,"?cmd") != NULL){
|
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;
|
return asynError;
|
||||||
} else if(strstr(myReply,"?par") != NULL){
|
} 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;
|
return asynError;
|
||||||
} else if(strstr(myReply,"?rng") != NULL){
|
} 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;
|
return asynError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,8 +216,7 @@ asynStatus EL734Controller::transactController(char command[COMLEN], char reply[
|
|||||||
* Initializes register numbers, etc.
|
* Initializes register numbers, etc.
|
||||||
*/
|
*/
|
||||||
EL734Axis::EL734Axis(EL734Controller *pC, int axisNo)
|
EL734Axis::EL734Axis(EL734Controller *pC, int axisNo)
|
||||||
: asynMotorAxis(pC, axisNo),
|
: SINQAxis(pC, axisNo), pC_(pC)
|
||||||
pC_(pC)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +254,7 @@ asynStatus EL734Axis::move(double position, int relative, double minVelocity, do
|
|||||||
oredMSR = 0;
|
oredMSR = 0;
|
||||||
homing = 0;
|
homing = 0;
|
||||||
sprintf(command, "p %d %.3f", axisNo_, position/1000.);
|
sprintf(command, "p %d %.3f", axisNo_, position/1000.);
|
||||||
status = pC_->transactController(command,reply);
|
status = pC_->transactController(axisNo_,command,reply);
|
||||||
next_poll = -1;
|
next_poll = -1;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -255,7 +270,7 @@ asynStatus EL734Axis::home(double minVelocity, double maxVelocity, double accele
|
|||||||
sprintf(command, "R %d", axisNo_);
|
sprintf(command, "R %d", axisNo_);
|
||||||
homing = 1;
|
homing = 1;
|
||||||
next_poll= -1;
|
next_poll= -1;
|
||||||
status = pC_->transactController(command,reply);
|
status = pC_->transactController(axisNo_,command,reply);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +292,7 @@ asynStatus EL734Axis::moveVelocity(double minVelocity, double maxVelocity, doubl
|
|||||||
/* This is a negative move */
|
/* This is a negative move */
|
||||||
sprintf(command, "FB %d", axisNo_);
|
sprintf(command, "FB %d", axisNo_);
|
||||||
}
|
}
|
||||||
status = pC_->transactController(command,reply);
|
status = pC_->transactController(axisNo_,command,reply);
|
||||||
next_poll = -1;
|
next_poll = -1;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -289,8 +304,9 @@ asynStatus EL734Axis::stop(double acceleration )
|
|||||||
char command[COMLEN], reply[COMLEN];
|
char command[COMLEN], reply[COMLEN];
|
||||||
|
|
||||||
sprintf(command, "S %d", axisNo_);
|
sprintf(command, "S %d", axisNo_);
|
||||||
status = pC_->transactController(command,reply);
|
status = pC_->transactController(axisNo_,command,reply);
|
||||||
errlogPrintf("Sent STOP on Axis %d\n", axisNo_);
|
errlogPrintf("Sent STOP on Axis %d\n", axisNo_);
|
||||||
|
updateMsgTxtFromDriver("Axis interrupted");
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -302,7 +318,7 @@ asynStatus EL734Axis::setPosition(double position)
|
|||||||
char command[COMLEN], reply[COMLEN];
|
char command[COMLEN], reply[COMLEN];
|
||||||
|
|
||||||
sprintf(command, "P %d %f", axisNo_, position/1000.);
|
sprintf(command, "P %d %f", axisNo_, position/1000.);
|
||||||
status = pC_->transactController(command,reply);
|
status = pC_->transactController(axisNo_,command,reply);
|
||||||
next_poll = -1;
|
next_poll = -1;
|
||||||
|
|
||||||
return status;
|
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). */
|
* \param[out] moving A flag that is set indicating that the axis is moving (true) or done (false). */
|
||||||
asynStatus EL734Axis::poll(bool *moving)
|
asynStatus EL734Axis::poll(bool *moving)
|
||||||
{
|
{
|
||||||
int msr;
|
int msr, count;
|
||||||
asynStatus comStatus;
|
asynStatus comStatus;
|
||||||
char command[COMLEN], reply[COMLEN];
|
char command[COMLEN], reply[COMLEN], errTxt[256];
|
||||||
|
int driverError = 0;
|
||||||
|
|
||||||
|
|
||||||
// protect against excessive polling
|
// protect against excessive polling
|
||||||
@ -341,19 +358,32 @@ asynStatus EL734Axis::poll(bool *moving)
|
|||||||
|
|
||||||
// Read the current motor position
|
// Read the current motor position
|
||||||
sprintf(command,"u %d", axisNo_);
|
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(comStatus) goto skip;
|
||||||
if(strstr(reply,"*ES") != NULL){
|
if(strstr(reply,"*ES") != NULL){
|
||||||
*moving = false;
|
*moving = false;
|
||||||
setIntegerParam(pC_->motorStatusDone_, true);
|
setIntegerParam(pC_->motorStatusDone_, true);
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
|
updateMsgTxtFromDriver("Emergency Stop Engaged");
|
||||||
|
driverError = 1;
|
||||||
goto skip;
|
goto skip;
|
||||||
} else if(strstr(reply,"?BSY") != NULL){
|
} else if(strstr(reply,"?BSY") != NULL){
|
||||||
*moving = true;
|
*moving = true;
|
||||||
setIntegerParam(pC_->motorStatusDone_, false);
|
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;
|
goto skip;
|
||||||
}
|
}
|
||||||
sscanf(reply,"%lf", &position);
|
|
||||||
//errlogPrintf("Axis %d, reply %s, position %lf\n", axisNo_, reply, position);
|
//errlogPrintf("Axis %d, reply %s, position %lf\n", axisNo_, reply, position);
|
||||||
setDoubleParam(pC_->motorPosition_, position*1000);
|
setDoubleParam(pC_->motorPosition_, position*1000);
|
||||||
//setDoubleParam(pC_->motorEncoderPosition_, position);
|
//setDoubleParam(pC_->motorEncoderPosition_, position);
|
||||||
@ -361,7 +391,7 @@ asynStatus EL734Axis::poll(bool *moving)
|
|||||||
|
|
||||||
// Read the moving status of this motor
|
// Read the moving status of this motor
|
||||||
sprintf(command,"msr %d",axisNo_);
|
sprintf(command,"msr %d",axisNo_);
|
||||||
comStatus = pC_->transactController(command,reply);
|
comStatus = pC_->transactController(axisNo_,command,reply);
|
||||||
if(comStatus) goto skip;
|
if(comStatus) goto skip;
|
||||||
sscanf(reply,"%x",&msr);
|
sscanf(reply,"%x",&msr);
|
||||||
// errlogPrintf("Axis %d, reply %s, msr %d, position = %lf\n",
|
// errlogPrintf("Axis %d, reply %s, msr %d, position = %lf\n",
|
||||||
@ -373,11 +403,15 @@ asynStatus EL734Axis::poll(bool *moving)
|
|||||||
next_poll = time(NULL)+IDLEPOLL;
|
next_poll = time(NULL)+IDLEPOLL;
|
||||||
if(oredMSR & 0x10){
|
if(oredMSR & 0x10){
|
||||||
setIntegerParam(pC_->motorStatusLowLimit_, true);
|
setIntegerParam(pC_->motorStatusLowLimit_, true);
|
||||||
|
updateMsgTxtFromDriver("Lower Limit Hit");
|
||||||
|
driverError = 1;
|
||||||
} else {
|
} else {
|
||||||
setIntegerParam(pC_->motorStatusLowLimit_, false);
|
setIntegerParam(pC_->motorStatusLowLimit_, false);
|
||||||
}
|
}
|
||||||
if(oredMSR & 0x20){
|
if(oredMSR & 0x20){
|
||||||
setIntegerParam(pC_->motorStatusHighLimit_, true);
|
setIntegerParam(pC_->motorStatusHighLimit_, true);
|
||||||
|
updateMsgTxtFromDriver("Upper Limit Hit");
|
||||||
|
driverError = 1;
|
||||||
} else {
|
} else {
|
||||||
setIntegerParam(pC_->motorStatusHighLimit_, false);
|
setIntegerParam(pC_->motorStatusHighLimit_, false);
|
||||||
}
|
}
|
||||||
@ -388,20 +422,29 @@ asynStatus EL734Axis::poll(bool *moving)
|
|||||||
if(oredMSR &0x1000){
|
if(oredMSR &0x1000){
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
errlogSevPrintf(errlogMajor, "Air cushion problem on %d", axisNo_);
|
errlogSevPrintf(errlogMajor, "Air cushion problem on %d", axisNo_);
|
||||||
|
updateMsgTxtFromDriver("Air cushion error");
|
||||||
|
driverError = 1;
|
||||||
}
|
}
|
||||||
if(oredMSR &0x80){
|
if(oredMSR &0x80){
|
||||||
setIntegerParam(pC_->motorStatusProblem_, true);
|
setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
errlogSevPrintf(errlogMajor, "Positioning fault at %d", axisNo_);
|
errlogSevPrintf(errlogMajor, "Positioning fault at %d", axisNo_);
|
||||||
|
updateMsgTxtFromDriver("Positioning fault");
|
||||||
|
driverError = 1;
|
||||||
}
|
}
|
||||||
*moving = false;
|
*moving = false;
|
||||||
setIntegerParam(pC_->motorStatusDone_, true);
|
setIntegerParam(pC_->motorStatusDone_, true);
|
||||||
|
//updateMsgTxtFromDriver("Believed to be on position");
|
||||||
} else {
|
} else {
|
||||||
*moving = true;
|
*moving = true;
|
||||||
next_poll = -1;
|
next_poll = -1;
|
||||||
setIntegerParam(pC_->motorStatusDone_, false);
|
setIntegerParam(pC_->motorStatusDone_, false);
|
||||||
|
//updateMsgTxtFromDriver("Creeping");
|
||||||
}
|
}
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
|
if(driverError == 0){
|
||||||
|
updateMsgTxtFromDriver(NULL);
|
||||||
|
}
|
||||||
setIntegerParam(pC_->motorStatusProblem_, comStatus ? 1:0);
|
setIntegerParam(pC_->motorStatusProblem_, comStatus ? 1:0);
|
||||||
callParamCallbacks();
|
callParamCallbacks();
|
||||||
return comStatus ? asynError : asynSuccess;
|
return comStatus ? asynError : asynSuccess;
|
||||||
|
@ -7,13 +7,13 @@ February 2013
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "asynMotorController.h"
|
#include "SINQController.h"
|
||||||
#include "asynMotorAxis.h"
|
#include "SINQAxis.h"
|
||||||
|
|
||||||
#define MAX_EL734_AXES 12
|
#define MAX_EL734_AXES 12
|
||||||
#define COMLEN 80
|
#define COMLEN 80
|
||||||
|
|
||||||
class EL734Axis : public asynMotorAxis
|
class EL734Axis : public SINQAxis
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* These are the methods we override from the base class */
|
/* These are the methods we override from the base class */
|
||||||
@ -34,11 +34,14 @@ private:
|
|||||||
double position;
|
double position;
|
||||||
int homing;
|
int homing;
|
||||||
time_t next_poll;
|
time_t next_poll;
|
||||||
|
int ErrTxtIdx;
|
||||||
|
|
||||||
|
void forwardErrorTxt(EL734Axis *axis);
|
||||||
|
|
||||||
friend class EL734Controller;
|
friend class EL734Controller;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EL734Controller : public asynMotorController {
|
class EL734Controller : public SINQController {
|
||||||
public:
|
public:
|
||||||
EL734Controller(const char *portName, const char *EL734PortName, int numAxes);
|
EL734Controller(const char *portName, const char *EL734PortName, int numAxes);
|
||||||
|
|
||||||
@ -50,7 +53,7 @@ friend class EL734Axis;
|
|||||||
private:
|
private:
|
||||||
asynUser *pasynUserController_;
|
asynUser *pasynUserController_;
|
||||||
|
|
||||||
asynStatus transactController(char command[COMLEN], char reply[COMLEN]);
|
asynStatus transactController(int axis, char command[COMLEN], char reply[COMLEN]);
|
||||||
|
|
||||||
void switchRemote();
|
void switchRemote();
|
||||||
|
|
||||||
|
@ -17,14 +17,14 @@ sinqEPICS_DBD += base.dbd
|
|||||||
|
|
||||||
# Include dbd files from all support applications:
|
# Include dbd files from all support applications:
|
||||||
sinqEPICS_DBD += sinq.dbd
|
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
|
# 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_registerRecordDeviceDriver.cpp derives from sinqEPICS.dbd
|
||||||
sinqEPICS_SRCS += sinqEPICS_registerRecordDeviceDriver.cpp
|
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 += pmacController.cpp pmacAxis.cpp
|
||||||
sinqEPICS_SRCS += NanotecDriver.cpp stptok.cpp
|
sinqEPICS_SRCS += NanotecDriver.cpp stptok.cpp
|
||||||
sinqEPICS_SRCS += PhytronDriver.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
|
* - Thresholding
|
||||||
* - two count modes
|
* - two count modes
|
||||||
* A better solution would be to extend the scalar record to have a proper status and count
|
* 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.
|
* compatability with the scalar record completely and thus was not done for now.
|
||||||
*
|
*
|
||||||
* The driver will run a separate thread which does all the
|
* The driver will run a separate thread which does all the
|
||||||
@ -27,6 +27,16 @@
|
|||||||
*
|
*
|
||||||
* Mark Koennecke, February 2013
|
* 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>
|
#include <string.h>
|
||||||
@ -40,6 +50,10 @@
|
|||||||
#include <recSup.h>
|
#include <recSup.h>
|
||||||
#include <devSup.h>
|
#include <devSup.h>
|
||||||
#include <cantProceed.h>
|
#include <cantProceed.h>
|
||||||
|
#include <dbDefs.h>
|
||||||
|
#include <dbFldTypes.h>
|
||||||
|
#include <dbAccess.h>
|
||||||
|
#include <errlog.h>
|
||||||
|
|
||||||
#include <scalerRecord.h>
|
#include <scalerRecord.h>
|
||||||
#include <devScaler.h>
|
#include <devScaler.h>
|
||||||
@ -49,7 +63,7 @@
|
|||||||
/* dset functions */
|
/* dset functions */
|
||||||
static long el737_init_record(struct scalerRecord *psr, CALLBACK *pcallback);
|
static long el737_init_record(struct scalerRecord *psr, CALLBACK *pcallback);
|
||||||
static long el737_reset(scalerRecord *psr);
|
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_write_preset(scalerRecord *psr, int signal, unsigned long val);
|
||||||
static long el737_arm(scalerRecord *psr, int val);
|
static long el737_arm(scalerRecord *psr, int val);
|
||||||
static long el737_done(scalerRecord *psr);
|
static long el737_done(scalerRecord *psr);
|
||||||
@ -84,17 +98,87 @@ typedef struct {
|
|||||||
unsigned long values[NCOUNT];
|
unsigned long values[NCOUNT];
|
||||||
unsigned int countCommand;
|
unsigned int countCommand;
|
||||||
unsigned int counting;
|
unsigned int counting;
|
||||||
|
unsigned long thresholdValue;
|
||||||
unsigned int sendThreshold;
|
unsigned int sendThreshold;
|
||||||
scalerRecord *psr;
|
scalerRecord *psr;
|
||||||
epicsEventId wakeUp;
|
epicsEventId wakeUp;
|
||||||
asynUser *asynContext;
|
asynUser *asynContext;
|
||||||
CALLBACK *pcallback;
|
CALLBACK *pcallback;
|
||||||
|
DBADDR pause;
|
||||||
|
DBADDR status;
|
||||||
|
DBADDR msgTxt;
|
||||||
|
DBADDR threshCounter;
|
||||||
|
DBADDR threshold;
|
||||||
|
unsigned int dbInit;
|
||||||
}EL737priv;
|
}EL737priv;
|
||||||
|
|
||||||
static void dummyAsynCallback(asynUser *pasynUser)
|
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)
|
static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
||||||
{
|
{
|
||||||
EL737priv *priv = NULL;
|
EL737priv *priv = NULL;
|
||||||
@ -122,7 +206,9 @@ static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
|||||||
priv->psr = psr;
|
priv->psr = psr;
|
||||||
priv->wakeUp = epicsEventCreate(epicsEventEmpty);
|
priv->wakeUp = epicsEventCreate(epicsEventEmpty);
|
||||||
priv->pcallback = pcallback;
|
priv->pcallback = pcallback;
|
||||||
|
priv->dbInit = 0;
|
||||||
psr->dpvt = priv;
|
psr->dpvt = priv;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hook up with device
|
* Hook up with device
|
||||||
@ -148,6 +234,8 @@ static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
|||||||
pasynOctetSyncIO->setInputEos(priv->asynContext,"\r",strlen("\r"));
|
pasynOctetSyncIO->setInputEos(priv->asynContext,"\r",strlen("\r"));
|
||||||
priv->asynContext->timeout = 1.0;
|
priv->asynContext->timeout = 1.0;
|
||||||
strcpy(command,"RMT 1");
|
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),
|
pasynOctetSyncIO->writeRead(priv->asynContext, command, strlen(command),
|
||||||
reply,sizeof(reply), 1.,&out,&in,&reason);
|
reply,sizeof(reply), 1.,&out,&in,&reason);
|
||||||
strcpy(command,"ECHO 2");
|
strcpy(command,"ECHO 2");
|
||||||
@ -155,6 +243,7 @@ static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
|||||||
reply,sizeof(reply), 1.,&out,&in,&reason);
|
reply,sizeof(reply), 1.,&out,&in,&reason);
|
||||||
pasynManager->freeAsynUser(dummyUser);
|
pasynManager->freeAsynUser(dummyUser);
|
||||||
|
|
||||||
|
connectSlaveRecords(priv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
start the thread which actually runs the device
|
start the thread which actually runs the device
|
||||||
@ -181,14 +270,14 @@ static long el737_reset(scalerRecord *psr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long el737_read(scalerRecord *psr, unsigned long *val)
|
static long el737_read(scalerRecord *psr, epicsUInt32 *val)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
EL737priv *priv;
|
EL737priv *priv;
|
||||||
|
|
||||||
priv = (EL737priv *)psr->dpvt;
|
priv = (EL737priv *)psr->dpvt;
|
||||||
for(i = 0; i < NCOUNT; i++){
|
for(i = 0; i < NCOUNT; i++){
|
||||||
val[i] = priv->values[i];
|
val[i] = (epicsUInt32)priv->values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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;
|
asynStatus status;
|
||||||
size_t in, out;
|
size_t in, out;
|
||||||
int reason;
|
int reason, dbStatus;
|
||||||
char myCommand[COMLEN];
|
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);
|
reply,COMLEN, 1.,&out,&in,&reason);
|
||||||
if(status == asynSuccess){
|
if(status == asynSuccess){
|
||||||
if(strstr(reply,"?OF") != NULL){
|
if(strstr(reply,"?OF") != NULL){
|
||||||
strcpy(myCommand,"RMT 1");
|
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);
|
reply,COMLEN, 1.,&out,&in,&reason);
|
||||||
strcpy(myCommand,"ECHO 2");
|
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);
|
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);
|
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;
|
return status;
|
||||||
@ -276,21 +401,56 @@ static asynStatus sendStop(EL737priv *priv)
|
|||||||
char command[COMLEN], reply[COMLEN];
|
char command[COMLEN], reply[COMLEN];
|
||||||
//errlogPrintf("Sending stop\n");
|
//errlogPrintf("Sending stop\n");
|
||||||
strcpy(command,"S");
|
strcpy(command,"S");
|
||||||
return el737_transactCommand(priv->asynContext,command,reply);
|
return el737_transactCommand(priv,command,reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void runEvents(EL737priv *priv)
|
static void runEvents(EL737priv *priv)
|
||||||
{
|
{
|
||||||
char command[COMLEN], reply[COMLEN];
|
char command[COMLEN], reply[COMLEN], errName[256];
|
||||||
int status;
|
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){
|
if(priv->sendThreshold == 1){
|
||||||
sprintf(command,"DL %d %d", (int)priv->presets[THRESHMON],
|
sprintf(command,"DL %d %d", (int)priv->presets[THRESHMON],
|
||||||
(int)priv->presets[THRESHVAL]);
|
(int)priv->presets[THRESHVAL]);
|
||||||
//errlogPrintf("Sending threshold command %s\n", command);
|
//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]);
|
sprintf(command,"DR %d", (int)priv->presets[THRESHMON]);
|
||||||
status = el737_transactCommand(priv->asynContext,command,reply);
|
status = el737_transactCommand(priv, command,reply);
|
||||||
if(status == asynSuccess){
|
if(status == asynSuccess){
|
||||||
priv->sendThreshold = 0;
|
priv->sendThreshold = 0;
|
||||||
}
|
}
|
||||||
@ -307,7 +467,7 @@ static void runEvents(EL737priv *priv)
|
|||||||
sprintf(command,"TP %f", priv->presets[TIMER]/1000.);
|
sprintf(command,"TP %f", priv->presets[TIMER]/1000.);
|
||||||
//errlogPrintf("Starting preset timer\n");
|
//errlogPrintf("Starting preset timer\n");
|
||||||
}
|
}
|
||||||
status = el737_transactCommand(priv->asynContext,command,reply);
|
status = el737_transactCommand(priv,command,reply);
|
||||||
if(status == asynSuccess){
|
if(status == asynSuccess){
|
||||||
priv->counting = 1;
|
priv->counting = 1;
|
||||||
}
|
}
|
||||||
@ -335,7 +495,7 @@ static void updateValues(EL737priv *priv)
|
|||||||
long m1, m2 ,m3, m4, m5, m6 ,m7, m8;
|
long m1, m2 ,m3, m4, m5, m6 ,m7, m8;
|
||||||
|
|
||||||
strcpy(command,"RA");
|
strcpy(command,"RA");
|
||||||
status = el737_transactCommand(priv->asynContext,command,reply);
|
status = el737_transactCommand(priv,command,reply);
|
||||||
if(status != asynSuccess){
|
if(status != asynSuccess){
|
||||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
||||||
priv->asynContext->errorMessage);
|
priv->asynContext->errorMessage);
|
||||||
@ -371,9 +531,10 @@ static void el737Thread(void *param)
|
|||||||
EL737priv *priv = (EL737priv *)param;
|
EL737priv *priv = (EL737priv *)param;
|
||||||
epicsEventWaitStatus evStatus;
|
epicsEventWaitStatus evStatus;
|
||||||
double timeout = 60.;
|
double timeout = 60.;
|
||||||
char command[COMLEN], reply[COMLEN];
|
char command[COMLEN], reply[COMLEN], errName[256];
|
||||||
asynStatus status;
|
asynStatus status;
|
||||||
int rs;
|
int rs, ctStatus;
|
||||||
|
long dbStatus, options, nElements = 1, pauseFlag = 0;
|
||||||
|
|
||||||
//errlogPrintf("Within EL737 thread \n");
|
//errlogPrintf("Within EL737 thread \n");
|
||||||
|
|
||||||
@ -381,6 +542,7 @@ static void el737Thread(void *param)
|
|||||||
evStatus = epicsEventWaitWithTimeout(priv->wakeUp,timeout);
|
evStatus = epicsEventWaitWithTimeout(priv->wakeUp,timeout);
|
||||||
//errlogPrintf("EL737 thread woke up with %d\n", evStatus);
|
//errlogPrintf("EL737 thread woke up with %d\n", evStatus);
|
||||||
|
|
||||||
|
|
||||||
if(evStatus == epicsEventWaitOK) {
|
if(evStatus == epicsEventWaitOK) {
|
||||||
/*
|
/*
|
||||||
FEAR: we received a command!!!!
|
FEAR: we received a command!!!!
|
||||||
@ -402,7 +564,7 @@ static void el737Thread(void *param)
|
|||||||
|
|
||||||
if(priv->counting) {
|
if(priv->counting) {
|
||||||
strcpy(command,"RS");
|
strcpy(command,"RS");
|
||||||
status = el737_transactCommand(priv->asynContext,command,reply);
|
status = el737_transactCommand(priv, command,reply);
|
||||||
if(status != asynSuccess){
|
if(status != asynSuccess){
|
||||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
||||||
priv->asynContext->errorMessage);
|
priv->asynContext->errorMessage);
|
||||||
@ -414,15 +576,57 @@ static void el737Thread(void *param)
|
|||||||
priv->counting = 0;
|
priv->counting = 0;
|
||||||
timeout = 60.;
|
timeout = 60.;
|
||||||
priv->values[9] = 0;
|
priv->values[9] = 0;
|
||||||
|
ctStatus = 0;
|
||||||
} else if(rs == 1 || rs == 2){
|
} else if(rs == 1 || rs == 2){
|
||||||
/* counting */
|
/* counting */
|
||||||
priv->values[9] = 1;
|
priv->values[9] = 1;
|
||||||
|
ctStatus = 1;
|
||||||
} else if(rs == 5 || rs == 6){
|
} else if(rs == 5 || rs == 6){
|
||||||
/* low rate */
|
/* low rate */
|
||||||
priv->values[9] = 2;
|
priv->values[9] = 2;
|
||||||
|
ctStatus = 2;
|
||||||
} else if(rs == 9 || rs == 13 || rs == 10 || rs == 14){
|
} else if(rs == 9 || rs == 13 || rs == 10 || rs == 14){
|
||||||
/* low rate */
|
/* paused states */
|
||||||
priv->values[9] = 2;
|
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(DTYP,"Soft Channel")
|
||||||
field(DESC,"NARZIS EL737 counter")
|
}
|
||||||
field(DTYP,"asynScalerEL737")
|
record(longin,"$(P):Status")
|
||||||
field(OUT,"INST_IO @asyn(cter1,0)"
|
{
|
||||||
|
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)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,21 +4,19 @@
|
|||||||
registrar(EL734Register)
|
registrar(EL734Register)
|
||||||
registrar(PhytronRegister)
|
registrar(PhytronRegister)
|
||||||
registrar(NanotecRegister)
|
registrar(NanotecRegister)
|
||||||
addpath "/usr/local/epics/support/asyn-4-18/dbd"
|
registrar(pmacControllerRegister)
|
||||||
addpath "/usr/local/epics/dbd"
|
|
||||||
addpath "/usr/local/epics/support/motor-6-7/dbd"
|
#--------------------------------------------------------
|
||||||
addpath "/usr/local/epics/support/std-3-1/dbd"
|
# With the PSI module build system, including these items actually
|
||||||
addpath "/usr/local/epics/anc350v17/dbd"
|
# hurts. It causes missing symbols when loading the shared lib.
|
||||||
include "drvAsynIPPort.dbd"
|
#------------------------------------------------------------------
|
||||||
include "motorRecord.dbd"
|
#include "/ioc/modules/asyn/427.0.1/R3.14.12/dbd/asyn.dbd"
|
||||||
include "motorSupport.dbd"
|
#include "/ioc/modules/motorBase/6.9.12/R3.14.12/dbd/motorBase.dbd"
|
||||||
include "anc350AsynMotor.dbd"
|
#include "/ioc/modules/SynApps/1.13.0/R3.14.12/dbd/SynApps.dbd"
|
||||||
|
#include "/ioc/modules/scaler/koennecke/R3.14.12/dbd/scaler.dbd"
|
||||||
|
|
||||||
include "scalerRecord.dbd"
|
|
||||||
device(scaler,INST_IO,devScalerEL737,"asynScalerEL737")
|
device(scaler,INST_IO,devScalerEL737,"asynScalerEL737")
|
||||||
|
|
||||||
#--------- For lakeshore
|
#--------- For lakeshore and magnets
|
||||||
addpath "/usr/local/epics/support/StreamDevice-2-6/dbd"
|
#include "/ioc/modules/stream/2.7.9/R3.14.12/dbd/stream.dbd"
|
||||||
include "stream.dbd"
|
#include "busy.dbd"
|
||||||
addpath "/usr/local/epics/support/busy-1-4/dbd"
|
|
||||||
include "busySupport.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