Compare commits
2 Commits
SINQSW-107
...
SINQSW-107
Author | SHA1 | Date | |
---|---|---|---|
d44dbaaf0f | |||
501c5badea |
@ -11,16 +11,11 @@ REQUIRED+=SynApps
|
||||
REQUIRED+=stream
|
||||
REQUIRED+=scaler
|
||||
REQUIRED+=asynMotor
|
||||
REQUIRED+=calc
|
||||
|
||||
# Release version
|
||||
LIBVERSION=2024-ed-dev
|
||||
LIBVERSION=2024-ed-dev2
|
||||
|
||||
# DB files to include in the release
|
||||
TEMPLATES += sinqEPICSApp/Db/counterbox_common.db
|
||||
TEMPLATES += sinqEPICSApp/Db/counterbox.db
|
||||
TEMPLATES += sinqEPICSApp/Db/counterbox_v2.db
|
||||
TEMPLATES += sinqEPICSApp/Db/counterbox.proto
|
||||
TEMPLATES += sinqEPICSApp/Db/dimetix.db
|
||||
TEMPLATES += sinqEPICSApp/Db/slsvme.db
|
||||
TEMPLATES += sinqEPICSApp/Db/spsamor.db
|
||||
@ -29,22 +24,18 @@ TEMPLATES += sinqEPICSApp/Db/spsamor.db
|
||||
DBDS += sinqEPICSApp/src/sinq.dbd
|
||||
|
||||
# Source files to build
|
||||
SOURCES += sinqEPICSApp/src/EL734Driver.cpp
|
||||
SOURCES += sinqEPICSApp/src/EuroMoveDriver.cpp
|
||||
SOURCES += sinqEPICSApp/src/MasterMACSDriver.cpp
|
||||
SOURCES += sinqEPICSApp/src/NanotecDriver.cpp
|
||||
SOURCES += sinqEPICSApp/src/PhytronDriver.cpp
|
||||
SOURCES += sinqEPICSApp/src/SINQAxis.cpp
|
||||
SOURCES += sinqEPICSApp/src/SINQController.cpp
|
||||
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/EuroMoveDriver.cpp
|
||||
SOURCES += sinqEPICSApp/src/pmacAsynIPPort.c
|
||||
SOURCES += sinqEPICSApp/src/pmacAxis.cpp
|
||||
SOURCES += sinqEPICSApp/src/pmacController.cpp
|
||||
SOURCES += sinqEPICSApp/src/stptok.cpp
|
||||
SOURCES += sinqEPICSApp/src/CounterBox.cpp
|
||||
|
||||
SCRIPTS += sinqEPICSApp/scripts/counterbox.cmd
|
||||
SCRIPTS += sinqEPICSApp/scripts/counterbox_v2.cmd
|
||||
SOURCES += sinqEPICSApp/src/MasterMACSDriver.cpp
|
||||
|
||||
USR_CFLAGS += -Wall -Wextra # -Werror
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
# EL737 EPICS Database for streamdevice support
|
||||
# Macros
|
||||
# P - Prefix
|
||||
# NAME - just a name, e.g. EL737
|
||||
# PROTO - Stream device protocol file
|
||||
# ASYN_PORT - Low level Asyn IP Port to EL737
|
||||
|
||||
################################################################################
|
||||
# Status Variables
|
||||
|
||||
record(longin, "$(P):$(NAME):MONITOR-CHANNEL")
|
||||
{
|
||||
field(DESC, "PRESET-COUNT Monitors this channel")
|
||||
field(VAL, 1)
|
||||
field(DISP, 1)
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):MONITOR-CHANNEL_RBV")
|
||||
{
|
||||
field(DESC, "PRESET-COUNT Monitors this channel")
|
||||
field(VAL, 1)
|
||||
field(DISP, 1)
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Count Commands
|
||||
|
||||
record(longout,"$(P):$(NAME):THRESHOLD-MONITOR")
|
||||
{
|
||||
field(DESC, "Channel monitored for minimum rate")
|
||||
field(VAL, "1") # Monitor
|
||||
field(DRVL, "1") # Smallest Threshold Channel
|
||||
field(DRVL, "8") # Largest Threshold Channel
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Read all monitors values
|
||||
|
||||
record(ai, "$(P):$(NAME):READALL")
|
||||
{
|
||||
field(DESC, "Reads monitors and elapsed time")
|
||||
field(INP, "@$(PROTO) readAll8($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(SCAN, ".2 second")
|
||||
field(DTYP, "stream")
|
||||
field(FLNK, "$(P):$(NAME):UNSET-COUNTING")
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
#
|
||||
# Counterbox Protocol File
|
||||
#
|
||||
OutTerminator = CR;
|
||||
InTerminator = CR;
|
||||
ReadTimeout = 100;
|
||||
WriteTimeout = 100;
|
||||
ReplyTimeout = 200;
|
||||
LockTimeout = 450;
|
||||
|
||||
initialise {
|
||||
out "RMT 1";
|
||||
in;
|
||||
out "ECHO 2";
|
||||
in "%(\$1MsgTxt)s"; # Clear MsgTxt on Init
|
||||
@mismatch{
|
||||
exec 'echo "Failed to configure counterbox" && exit(1)';
|
||||
}
|
||||
}
|
||||
|
||||
fullReset {
|
||||
out "\%";
|
||||
wait 5000;
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Status Variables
|
||||
|
||||
readStatus {
|
||||
out "RS";
|
||||
in "%d";
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
readPresetMonitor {
|
||||
out "PC";
|
||||
in "%d";
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
writePresetMonitor {
|
||||
out "PC %d";
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Count Commands
|
||||
|
||||
startWithCountPreset {
|
||||
out "MP %d";
|
||||
in;
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
startWithTimePreset {
|
||||
out "TP %#.2f";
|
||||
in;
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
pauseCount {
|
||||
out "PS";
|
||||
in;
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
continueCount {
|
||||
out "CO";
|
||||
in;
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
stopCount {
|
||||
out "S";
|
||||
in;
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
setMinRate{
|
||||
out "DL %(\$1THRESHOLD-MONITOR)d %(\$1THRESHOLD)d";
|
||||
in;
|
||||
out "DR %(\$1THRESHOLD-MONITOR)d";
|
||||
in;
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
readMinRate{
|
||||
out "DR";
|
||||
in "%(\$1THRESHOLD-MONITOR_RBV)d";
|
||||
out "DL %(\$1THRESHOLD-MONITOR_RBV)d";
|
||||
in "%(\$1THRESHOLD_RBV)d";
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Read Values From Monitors
|
||||
|
||||
readAll8 {
|
||||
out "RA";
|
||||
in "%(\$1ELAPSED-TIME)f %(\$1M1)d %(\$1M2)d %(\$1M3)d %(\$1M4)d %(\$1M5)d %(\$1M6)d %(\$1M7)d %(\$1M8)d";
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
readAll10 {
|
||||
out "RA";
|
||||
in "%(\$1ELAPSED-TIME)f %(\$1M1)d %(\$1M2)d %(\$1M3)d %(\$1M4)d %(\$1M5)d %(\$1M6)d %(\$1M7)d %(\$1M8)d %(\$1M9)d %(\$1M10)d";
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
readRate {
|
||||
out "RR \$2";
|
||||
in "%(\$1R\$2)f";
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Testing Commands
|
||||
|
||||
switchTestgenOnOff {
|
||||
out "TG %{off|on}";
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
||||
|
||||
# Only suppporting test channel 1 at the moment. (The first argument to TG)
|
||||
setTestSignal {
|
||||
out "TG 1 %(\$1TESTGEN-HIGHRATE)d %(\$1TESTGEN-LOWRATE)d";
|
||||
@mismatch{in "%(\$1MsgTxt)s";}
|
||||
}
|
@ -1,259 +0,0 @@
|
||||
# EL737 EPICS Database for streamdevice support
|
||||
# Macros
|
||||
# P - Prefix
|
||||
# NAME - just a name, e.g. EL737
|
||||
# PROTO - Stream device protocol file
|
||||
# ASYN_PORT - Low level Asyn IP Port to EL737
|
||||
|
||||
# Send initial initialisation commands
|
||||
record(bo, "$(P):$(NAME):INIT-CONF")
|
||||
{
|
||||
field(DESC, "Initialises the Counterbox")
|
||||
field(OUT, "@$(PROTO) initialise($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(PINI, "YES") # Run at init
|
||||
field(DTYP, "stream")
|
||||
field(FLNK, "$(P):$(NAME):INIT-BOX")
|
||||
}
|
||||
|
||||
# As we aren't certain of the order that PINI exectutes PVs, we only set it to
|
||||
# true on INIT-CONF to make sure the box is ready to receive commands, and then
|
||||
# let INIT-CONF trigger the initialisation of other necessary records
|
||||
record(fanout, "$(P):$(NAME):INIT-BOX")
|
||||
{
|
||||
field(DESC, "Rewrite PVs to Box")
|
||||
field(SELM, "All")
|
||||
field(LNK0, "$(P):$(NAME):MONITOR-CHANNEL_RBV PP")
|
||||
field(LNK1, "$(P):$(NAME):READALL PP")
|
||||
field(LNK2, "$(P):$(NAME):THRESHOLD_RBV PP")
|
||||
}
|
||||
|
||||
record(longout, "$(P):$(NAME):FULL-RESET")
|
||||
{
|
||||
field(DESC, "Reset the Counterbox")
|
||||
field(OUT, "@$(PROTO) fullReset($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(DTYP, "stream")
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Status Variables
|
||||
|
||||
record(stringin, "$(P):$(NAME):MsgTxt")
|
||||
{
|
||||
field(DESC, "Unexpected received response")
|
||||
field(DTYP, "devCounterBoxStringError")
|
||||
field(FLNK, "$(P):$(NAME):INVALID-CONFIG")
|
||||
}
|
||||
|
||||
# We want to recognise the invalid config error message, so that we can rerun
|
||||
# the init if it occurs. This should only happen after turning the box off and
|
||||
# on again or running a full reset
|
||||
record(scalcout, "$(P):$(NAME):INVALID-CONFIG")
|
||||
{
|
||||
field(DESC, "Has the counterbox been configured?")
|
||||
field(CALC, "AA[0,2] == '?OF'")
|
||||
field(INAA, "$(P):$(NAME):MsgTxt")
|
||||
field(FLNK, "$(P):$(NAME):REINIT-CONF")
|
||||
}
|
||||
|
||||
record(seq, "$(P):$(NAME):REINIT-CONF")
|
||||
{
|
||||
field(LNK1, "$(P):$(NAME):INIT-CONF PP")
|
||||
field(DO1, 1)
|
||||
field(SELM, "Specified")
|
||||
field(SELL, "$(P):$(NAME):INVALID-CONFIG.VAL")
|
||||
}
|
||||
|
||||
# The COUNTING PV stays True until Counterbox has switched back to idle mode
|
||||
# and the monitor counts have been read. Therefore, we know that the monitor
|
||||
# values have been updated to represent their final values, when this switches
|
||||
# back to False.
|
||||
#
|
||||
# This is accomplished via the explicit SET-COUNTING and UNSET-COUNTING seq
|
||||
# records, that are triggered by a switch to the counting status
|
||||
# (RAW-STATUS == 1 || 2) and a read of the monitors respectively.
|
||||
record(bi, "$(P):$(NAME):COUNTING")
|
||||
{
|
||||
field(DESC, "Counterbox is Counting")
|
||||
field(VAL, 0)
|
||||
}
|
||||
|
||||
record(seq, "$(P):$(NAME):SET-COUNTING")
|
||||
{
|
||||
field(LNK1, "$(P):$(NAME):COUNTING PP")
|
||||
field(DO1, 1)
|
||||
field(SELM, "Specified")
|
||||
field(SELL, "$(P):$(NAME):MAP-STATUS.VAL")
|
||||
field(FLNK, "$(P):$(NAME):STATUS")
|
||||
}
|
||||
|
||||
record(seq, "$(P):$(NAME):UNSET-COUNTING")
|
||||
{
|
||||
field(LNK0, "$(P):$(NAME):COUNTING PP")
|
||||
field(DO0, 0)
|
||||
field(SELM, "Specified")
|
||||
field(SELL, "$(P):$(NAME):RAW-STATUS.VAL")
|
||||
field(FLNK, "$(P):$(NAME):MAP-STATUS")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):RAW-STATUS")
|
||||
{
|
||||
field(DESC, "Raw returned status value")
|
||||
field(DTYP, "stream")
|
||||
field(SCAN, ".2 second")
|
||||
field(INP, "@$(PROTO) readStatus($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(FLNK, "$(P):$(NAME):MAP-STATUS")
|
||||
}
|
||||
|
||||
record(calc, "$(P):$(NAME):MAP-STATUS")
|
||||
{
|
||||
field(DESC, "Maps Raw Status to State")
|
||||
field(INPA, "$(P):$(NAME):RAW-STATUS NPP")
|
||||
field(INPB, "$(P):$(NAME):INVALID-CONFIG NPP")
|
||||
field(INPC, "$(P):$(NAME):COUNTING NPP")
|
||||
field(CALC, "B=1?4:(C=1&&A=0)||A=1||A=2?1:A=0?0:A=5||A=6?2:A=9||A=13||A=10||A=14?3:4")
|
||||
field(FLNK, "$(P):$(NAME):SET-COUNTING")
|
||||
}
|
||||
|
||||
record(mbbi, "$(P):$(NAME):STATUS")
|
||||
{
|
||||
field(DESC, "Counterbox Status")
|
||||
field(INP, "$(P):$(NAME):MAP-STATUS NPP")
|
||||
field(ZRVL, "0")
|
||||
field(ZRST, "Idle")
|
||||
field(ONVL, "1")
|
||||
field(ONST, "Counting")
|
||||
field(TWVL, "2")
|
||||
field(TWST, "Low rate")
|
||||
field(THVL, "3")
|
||||
field(THST, "Paused")
|
||||
# 4 should never happen, if it does it means the counter box reports undocumented statusbits
|
||||
field(FRVL, "4")
|
||||
field(FRST, "INVALID")
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Count Commands
|
||||
|
||||
record(ao,"$(P):$(NAME):PRESET-COUNT")
|
||||
{
|
||||
field(DESC, "Count until preset reached")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) startWithCountPreset($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(VAL, 0)
|
||||
field(PREC, 2)
|
||||
}
|
||||
|
||||
record(ao,"$(P):$(NAME):PRESET-TIME")
|
||||
{
|
||||
field(DESC, "Count for specified time")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) startWithTimePreset($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(VAL, 0)
|
||||
field(PREC, 2)
|
||||
field(EGU, "seconds")
|
||||
}
|
||||
|
||||
record(bo,"$(P):$(NAME):PAUSE")
|
||||
{
|
||||
field(DESC, "Pause the current count")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) pauseCount($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(VAL, "0")
|
||||
}
|
||||
|
||||
record(bo,"$(P):$(NAME):CONTINUE")
|
||||
{
|
||||
field(DESC, "Continue with a count that was paused")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) continueCount($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(VAL, "0")
|
||||
}
|
||||
|
||||
record(bo, "$(P):$(NAME):STOP")
|
||||
{
|
||||
field(DESC, "Stop the current counting operation")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) stopCount($(P):$(NAME):) $(ASYN_PORT)")
|
||||
}
|
||||
|
||||
# TODO should changing the monitor also set things?
|
||||
# or only when actually setting a threshold?
|
||||
record(longout,"$(P):$(NAME):THRESHOLD")
|
||||
{
|
||||
field(DESC, "Minimum rate for counting to proceed")
|
||||
field(VAL, "0") # Rate
|
||||
field(DRVL, "0") # Minimum Rate
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) setMinRate($(P):$(NAME):) $(ASYN_PORT)")
|
||||
}
|
||||
|
||||
record(longin,"$(P):$(NAME):THRESHOLD_RBV")
|
||||
{
|
||||
field(DESC, "Minimum rate for counting to proceed")
|
||||
field(DTYP, "stream")
|
||||
field(INP, "@$(PROTO) readMinRate($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(SCAN, "2 second")
|
||||
}
|
||||
|
||||
record(longin,"$(P):$(NAME):THRESHOLD-MONITOR_RBV")
|
||||
{
|
||||
field(DESC, "Channel monitored for minimum rate")
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Read all monitors values
|
||||
|
||||
record(ai,"$(P):$(NAME):ELAPSED-TIME")
|
||||
{
|
||||
field(DESC, "Counterbox Measured Time")
|
||||
field(EGU, "seconds")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M1")
|
||||
{
|
||||
field(DESC, "Counterbox CH1")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M2")
|
||||
{
|
||||
field(DESC, "Counterbox CH2")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M3")
|
||||
{
|
||||
field(DESC, "Counterbox CH3")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M4")
|
||||
{
|
||||
field(DESC, "Counterbox CH4")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M5")
|
||||
{
|
||||
field(DESC, "Counterbox CH5")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M6")
|
||||
{
|
||||
field(DESC, "Counterbox CH6")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M7")
|
||||
{
|
||||
field(DESC, "Counterbox CH7")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M8")
|
||||
{
|
||||
field(DESC, "Counterbox CH8")
|
||||
}
|
||||
|
||||
# Not yet sure whether we want to support this
|
||||
# record(longin, "$(P):$(NAME):R1")
|
||||
# {
|
||||
# field(DESC, "Counterbox Rate CH1")
|
||||
# field(INP, "@$(PROTO) readRate($(P):$(NAME):, 1) $(ASYN_PORT)")
|
||||
# field(SCAN, ".2 second")
|
||||
# field(DTYP, "stream")
|
||||
# }
|
@ -1,88 +0,0 @@
|
||||
# EL737 EPICS Database for streamdevice support
|
||||
# Macros
|
||||
# P - Prefix
|
||||
# NAME - just a name, e.g. DAQV2
|
||||
# PROTO - Stream device protocol file
|
||||
# ASYN_PORT - Low level Asyn IP Port to Counterbox
|
||||
|
||||
################################################################################
|
||||
# Status Variables
|
||||
|
||||
record(longout, "$(P):$(NAME):MONITOR-CHANNEL")
|
||||
{
|
||||
field(DESC, "PRESET-COUNT Monitors this channel")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) writePresetMonitor($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(FLNK, "$(P):$(NAME):MONITOR-CHANNEL_RBV")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):MONITOR-CHANNEL_RBV")
|
||||
{
|
||||
field(DESC, "PRESET-COUNT Monitors this channel")
|
||||
field(DTYP, "stream")
|
||||
field(INP, "@$(PROTO) readPresetMonitor($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(SCAN, "5 second")
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Count Commands
|
||||
|
||||
record(longout,"$(P):$(NAME):THRESHOLD-MONITOR")
|
||||
{
|
||||
field(DESC, "Channel monitored for minimum rate")
|
||||
field(VAL, "1") # Monitor
|
||||
field(DRVL, "1") # Smallest Threshold Channel
|
||||
field(DRVL, "10") # Largest Threshold Channel
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Read all monitors values
|
||||
|
||||
record(ai, "$(P):$(NAME):READALL")
|
||||
{
|
||||
field(DESC, "Reads monitors and elapsed time")
|
||||
field(INP, "@$(PROTO) readAll10($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(SCAN, ".2 second")
|
||||
field(DTYP, "stream")
|
||||
field(FLNK, "$(P):$(NAME):UNSET-COUNTING")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M9")
|
||||
{
|
||||
field(DESC, "Counterbox CH9")
|
||||
}
|
||||
|
||||
record(longin, "$(P):$(NAME):M10")
|
||||
{
|
||||
field(DESC, "Counterbox CH10")
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Testing Commands
|
||||
|
||||
# These won't match the values on the machine after a full restart But I chose
|
||||
# not to force their intialisation as they are only important for testing
|
||||
|
||||
record(bo, "$(P):$(NAME):TESTGEN")
|
||||
{
|
||||
field(DESC, "Turn on/off Testgen Signal")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) switchTestgenOnOff($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(VAL, 0)
|
||||
}
|
||||
|
||||
record(longout, "$(P):$(NAME):TESTGEN-LOWRATE")
|
||||
{
|
||||
field(DESC, "Set Minimum Testgen Rate")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) setTestSignal($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(VAL, 1000)
|
||||
}
|
||||
|
||||
record(longout, "$(P):$(NAME):TESTGEN-HIGHRATE")
|
||||
{
|
||||
field(DESC, "Set Maximum Testgen Rate")
|
||||
field(DTYP, "stream")
|
||||
field(OUT, "@$(PROTO) setTestSignal($(P):$(NAME):) $(ASYN_PORT)")
|
||||
field(VAL, 1000)
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
require asyn
|
||||
|
||||
# Need to be set by user
|
||||
# epicsEnvSet("CNTBOX_HOST", "testinst-daq1:2000")
|
||||
# epicsEnvSet("ASYN_PORT", "el737")
|
||||
# epicsEnvSet("PREFIX", "SQ:SINQTEST")
|
||||
# epicsEnvSet("NAME", "COUNTERBOX")
|
||||
|
||||
epicsEnvSet("PROTO", "$(sinq_DB)counterbox.proto")
|
||||
|
||||
drvAsynIPPortConfigure("$(ASYN_PORT)", "$(CNTBOX_HOST)", 0, 0, 0)
|
||||
dbLoadRecords("$(sinq_DB)counterbox_common.db", "P=$(PREFIX), NAME=$(NAME), PROTO=$(PROTO), ASYN_PORT=$(ASYN_PORT)")
|
||||
dbLoadRecords("$(sinq_DB)counterbox.db", "P=$(PREFIX), NAME=$(NAME), PROTO=$(PROTO), ASYN_PORT=$(ASYN_PORT)")
|
@ -1,13 +0,0 @@
|
||||
require asyn
|
||||
|
||||
# Need to be set by user
|
||||
# epicsEnvSet("CNTBOX_HOST", "testinst-daq1:2000")
|
||||
# epicsEnvSet("ASYN_PORT", "el737")
|
||||
# epicsEnvSet("PREFIX", "SQ:SINQTEST")
|
||||
# epicsEnvSet("NAME", "COUNTERBOX")
|
||||
|
||||
epicsEnvSet("PROTO", "$(sinq_DB)counterbox.proto")
|
||||
|
||||
drvAsynIPPortConfigure("$(ASYN_PORT)", "$(CNTBOX_HOST)", 0, 0, 0)
|
||||
dbLoadRecords("$(sinq_DB)counterbox_common.db", "P=$(PREFIX), NAME=$(NAME), PROTO=$(PROTO), ASYN_PORT=$(ASYN_PORT)")
|
||||
dbLoadRecords("$(sinq_DB)counterbox_v2.db", "P=$(PREFIX), NAME=$(NAME), PROTO=$(PROTO), ASYN_PORT=$(ASYN_PORT)")
|
@ -1,60 +0,0 @@
|
||||
#include <epicsExport.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <stringinRecord.h>
|
||||
|
||||
#define update_val(prec, new_val) \
|
||||
{ \
|
||||
static_assert(std::char_traits<char>::length((new_val)) < MAX_SIZE, \
|
||||
"New Val Exceeds Max String Length"); \
|
||||
strncpy((prec)->val, (new_val), MAX_SIZE); \
|
||||
}
|
||||
|
||||
static long map_raw_failure_message(struct stringinRecord *prec) {
|
||||
const uint8_t MAX_SIZE = 40; // including null terminator
|
||||
|
||||
if (strcmp(prec->val, "?OF") == 0) {
|
||||
update_val(prec, "?OF: Configuration Error");
|
||||
} else if (strcmp(prec->val, "?OV") == 0) {
|
||||
update_val(prec, "?OV: Overflow");
|
||||
} else if (strcmp(prec->val, "?1") == 0) {
|
||||
update_val(prec, "?1: Parameter out of range");
|
||||
} else if (strcmp(prec->val, "?2") == 0) {
|
||||
update_val(prec, "?2: Bad command");
|
||||
} else if (strcmp(prec->val, "?3") == 0) {
|
||||
update_val(prec, "?3: Bad parameter");
|
||||
} else if (strcmp(prec->val, "?4") == 0) {
|
||||
update_val(prec, "?4: Bad counter");
|
||||
} else if (strcmp(prec->val, "?5") == 0) {
|
||||
update_val(prec, "?5: Parameter missing");
|
||||
} else if (strcmp(prec->val, "?6") == 0) {
|
||||
update_val(prec, "?6: Too many counts");
|
||||
} else if (strcmp(prec->val, "?91") == 0) {
|
||||
update_val(prec, "?91: Start Failure");
|
||||
} else if (strcmp(prec->val, "?92") == 0) {
|
||||
update_val(prec, "?92: Failure while counting");
|
||||
} else if (strcmp(prec->val, "?93") == 0) {
|
||||
update_val(prec, "?93: Read Failure");
|
||||
} else if (strstr(prec->val, "?") != NULL) {
|
||||
char val_copy[40] = {0};
|
||||
strncpy(val_copy, prec->val, MAX_SIZE);
|
||||
snprintf(prec->val, MAX_SIZE - 1, "%s: HW error", val_copy);
|
||||
} else {
|
||||
// Leave the message as is
|
||||
}
|
||||
|
||||
return 0; // returns: (-1,0)=>(failure,success)
|
||||
}
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devCounterBoxStringError = {
|
||||
6, NULL, NULL, NULL, NULL, (DEVSUPFUN)map_raw_failure_message, NULL};
|
||||
|
||||
epicsExportAddress(dset, devCounterBoxStringError);
|
@ -29,7 +29,7 @@ sinqEPICS_SRCS += pmacController.cpp pmacAxis.cpp
|
||||
sinqEPICS_SRCS += NanotecDriver.cpp stptok.cpp
|
||||
sinqEPICS_SRCS += PhytronDriver.cpp
|
||||
sinqEPICS_SRCS += EuroMoveDriver.cpp
|
||||
sinqEPICS_SRCS += CounterBox.cpp
|
||||
|
||||
|
||||
# Build the main IOC entry point on workstation OSs.
|
||||
sinqEPICS_SRCS_DEFAULT += sinqEPICSMain.cpp
|
||||
|
@ -14,59 +14,59 @@
|
||||
* 2 = threshold monitor
|
||||
* 3 = threshold monitor count
|
||||
*
|
||||
* This is less then ideal. But it is a workaround for the fact that the scalar record
|
||||
* does not do all the tricks the EL737 knows:
|
||||
* This is less then ideal. But it is a workaround for the fact that the scalar
|
||||
* record does not do all the tricks the EL737 knows:
|
||||
* - 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 fields too. But this is much more work, breaks
|
||||
* compatability with the scalar record completely and thus was not done for now.
|
||||
* A better solution would be to extend the scalar record to have a proper
|
||||
* status and count 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
|
||||
* communication.
|
||||
*
|
||||
* Mark Koennecke, February 2013
|
||||
*
|
||||
* Enhanced by adding an addtional external pause and status flag in the database and code in here
|
||||
* to handle this. Moreover an external MsgTxt field in the DB can be filled with an error message.
|
||||
* Enhanced by adding an addtional external pause and status flag in the
|
||||
* database 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.
|
||||
* 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 <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <asynEpicsUtils.h>
|
||||
#include <asynOctetSyncIO.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsThread.h>
|
||||
#include <epicsTime.h>
|
||||
#include <epicsExport.h>
|
||||
#include <errlog.h>
|
||||
#include <callback.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <cantProceed.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbDefs.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <dbAccess.h>
|
||||
#include <errlog.h>
|
||||
|
||||
#include <scalerRecord.h>
|
||||
#include <devScaler.h>
|
||||
#include <asynEpicsUtils.h>
|
||||
|
||||
#include <devSup.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsExport.h>
|
||||
#include <epicsThread.h>
|
||||
#include <epicsTime.h>
|
||||
#include <errlog.h>
|
||||
#include <errno.h>
|
||||
#include <recSup.h>
|
||||
#include <scalerRecord.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* dset functions */
|
||||
static long el737_init_record(struct scalerRecord *psr, CALLBACK *pcallback);
|
||||
static long el737_reset(scalerRecord *psr);
|
||||
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_done(scalerRecord *psr);
|
||||
|
||||
@ -82,17 +82,9 @@ static void el737Thread(void *param);
|
||||
#define COMLEN 132
|
||||
|
||||
SCALERDSET devScalerEL737 = {
|
||||
7,
|
||||
NULL,
|
||||
NULL,
|
||||
el737_init_record,
|
||||
NULL,
|
||||
el737_reset,
|
||||
el737_read,
|
||||
el737_write_preset,
|
||||
el737_arm,
|
||||
el737_done
|
||||
};
|
||||
7, NULL, NULL, el737_init_record,
|
||||
NULL, el737_reset, el737_read, el737_write_preset,
|
||||
el737_arm, el737_done};
|
||||
epicsExportAddress(dset, devScalerEL737);
|
||||
|
||||
typedef struct {
|
||||
@ -114,12 +106,9 @@ typedef struct {
|
||||
unsigned int dbInit;
|
||||
} EL737priv;
|
||||
|
||||
static void dummyAsynCallback([[maybe_unused]] asynUser *pasynUser)
|
||||
{
|
||||
}
|
||||
static void dummyAsynCallback(asynUser *pasynUser) {}
|
||||
|
||||
static void connectSlaveRecords(EL737priv *priv)
|
||||
{
|
||||
static void connectSlaveRecords(EL737priv *priv) {
|
||||
char slaveName[PVNAME_SZ + 18], errName[256];
|
||||
long status;
|
||||
|
||||
@ -129,10 +118,12 @@ static void connectSlaveRecords(EL737priv *priv)
|
||||
status = dbNameToAddr(slaveName, &priv->pause);
|
||||
if (status != 0) {
|
||||
errSymLookup(status, errName, sizeof(errName));
|
||||
errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, 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);
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",
|
||||
slaveName, priv->pause.precord->name);
|
||||
}
|
||||
|
||||
snprintf(slaveName, sizeof(slaveName), "%s:MsgTxt", priv->psr->name);
|
||||
@ -140,10 +131,12 @@ static void connectSlaveRecords(EL737priv *priv)
|
||||
status = dbNameToAddr(slaveName, &priv->msgTxt);
|
||||
if (status != 0) {
|
||||
errSymLookup(status, errName, sizeof(errName));
|
||||
errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, 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);
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",
|
||||
slaveName, priv->msgTxt.precord->name);
|
||||
}
|
||||
|
||||
snprintf(slaveName, sizeof(slaveName), "%s:Status", priv->psr->name);
|
||||
@ -151,21 +144,26 @@ static void connectSlaveRecords(EL737priv *priv)
|
||||
status = dbNameToAddr(slaveName, &priv->status);
|
||||
if (status != 0) {
|
||||
errSymLookup(status, errName, sizeof(errName));
|
||||
errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, 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);
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",
|
||||
slaveName, priv->status.precord->name);
|
||||
}
|
||||
|
||||
snprintf(slaveName,sizeof(slaveName),"%s:ThresholdCounter", priv->psr->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);
|
||||
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->threshCounter.precord->name);
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",
|
||||
slaveName, priv->threshCounter.precord->name);
|
||||
}
|
||||
|
||||
snprintf(slaveName, sizeof(slaveName), "%s:Threshold", priv->psr->name);
|
||||
@ -173,16 +171,17 @@ static void connectSlaveRecords(EL737priv *priv)
|
||||
status = dbNameToAddr(slaveName, &priv->threshold);
|
||||
if (status != 0) {
|
||||
errSymLookup(status, errName, sizeof(errName));
|
||||
errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, 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->threshold.precord->name);
|
||||
errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",
|
||||
slaveName, priv->threshold.precord->name);
|
||||
}
|
||||
priv->thresholdValue = -999;
|
||||
}
|
||||
|
||||
static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
||||
{
|
||||
static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback) {
|
||||
EL737priv *priv = NULL;
|
||||
char *port, *userParam;
|
||||
int signal, status, reason;
|
||||
@ -204,23 +203,23 @@ static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
||||
/*
|
||||
* private data structure
|
||||
*/
|
||||
priv = callocMustSucceed(1,sizeof(EL737priv), "devScalerEL737 init_record()");
|
||||
priv =
|
||||
callocMustSucceed(1, sizeof(EL737priv), "devScalerEL737 init_record()");
|
||||
priv->psr = psr;
|
||||
priv->wakeUp = epicsEventCreate(epicsEventEmpty);
|
||||
priv->pcallback = pcallback;
|
||||
priv->dbInit = 0;
|
||||
psr->dpvt = priv;
|
||||
|
||||
|
||||
/*
|
||||
* Hook up with device
|
||||
*/
|
||||
dummyUser = pasynManager->createAsynUser(dummyAsynCallback, 0);
|
||||
status = pasynEpicsUtils->parseLink(dummyUser, &psr->out,
|
||||
&port, &signal, &userParam);
|
||||
status = pasynEpicsUtils->parseLink(dummyUser, &psr->out, &port, &signal,
|
||||
&userParam);
|
||||
if (status != asynSuccess) {
|
||||
errlogPrintf("devScalerEL737::init_record %s bad link %s\n",
|
||||
psr->name, dummyUser->errorMessage);
|
||||
errlogPrintf("devScalerEL737::init_record %s bad link %s\n", psr->name,
|
||||
dummyUser->errorMessage);
|
||||
psr->pact = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -251,18 +250,14 @@ static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback)
|
||||
/*
|
||||
start the thread which actually runs the device
|
||||
*/
|
||||
epicsThreadCreate("EL737",
|
||||
epicsThreadPriorityMedium,
|
||||
epicsThreadStackMedium,
|
||||
el737Thread,
|
||||
priv);
|
||||
epicsThreadCreate("EL737", epicsThreadPriorityMedium,
|
||||
epicsThreadStackMedium, el737Thread, priv);
|
||||
|
||||
// errlogPrintf("EL7373 thread started \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long el737_reset(scalerRecord *psr)
|
||||
{
|
||||
static long el737_reset(scalerRecord *psr) {
|
||||
unsigned int i;
|
||||
EL737priv *priv;
|
||||
|
||||
@ -273,8 +268,7 @@ static long el737_reset(scalerRecord *psr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long el737_read(scalerRecord *psr, epicsUInt32 *val)
|
||||
{
|
||||
static long el737_read(scalerRecord *psr, epicsUInt32 *val) {
|
||||
unsigned int i;
|
||||
EL737priv *priv;
|
||||
|
||||
@ -286,8 +280,8 @@ static long el737_read(scalerRecord *psr, epicsUInt32 *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long el737_write_preset(scalerRecord *psr, int signal, unsigned long val)
|
||||
{
|
||||
static long el737_write_preset(scalerRecord *psr, int signal,
|
||||
unsigned long val) {
|
||||
EL737priv *priv;
|
||||
|
||||
// errlogPrintf("EL737: Setting preset %d to %ld\n", signal, val);
|
||||
@ -300,13 +294,11 @@ static long el737_write_preset(scalerRecord *psr, int signal, unsigned long val)
|
||||
priv->sendThreshold = 1;
|
||||
epicsEventSignal(priv->wakeUp);
|
||||
// errlogPrintf("EL737: Setting threshold \n");
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long el737_arm(scalerRecord *psr, int val)
|
||||
{
|
||||
static long el737_arm(scalerRecord *psr, int val) {
|
||||
EL737priv *priv;
|
||||
|
||||
priv = (EL737priv *)psr->dpvt;
|
||||
@ -319,8 +311,7 @@ static long el737_arm(scalerRecord *psr, int val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long el737_done(scalerRecord *psr)
|
||||
{
|
||||
static long el737_done(scalerRecord *psr) {
|
||||
EL737priv *priv;
|
||||
priv = (EL737priv *)psr->dpvt;
|
||||
|
||||
@ -337,8 +328,8 @@ static long el737_done(scalerRecord *psr)
|
||||
}
|
||||
}
|
||||
|
||||
static asynStatus el737_transactCommand(EL737priv *priv,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, dbStatus;
|
||||
@ -349,18 +340,22 @@ static asynStatus el737_transactCommand(EL737priv *priv,char command[COMLEN],cha
|
||||
// errlogPrintf("EL737: sending command %s\n", command);
|
||||
|
||||
strcpy(message, "");
|
||||
status = pasynOctetSyncIO->writeRead(priv->asynContext, command, strlen(command),
|
||||
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(priv->asynContext, myCommand, strlen(myCommand),
|
||||
reply,COMLEN, 1.,&out,&in,&reason);
|
||||
status = pasynOctetSyncIO->writeRead(
|
||||
priv->asynContext, myCommand, strlen(myCommand), reply, COMLEN,
|
||||
1., &out, &in, &reason);
|
||||
strcpy(myCommand, "ECHO 2");
|
||||
status = pasynOctetSyncIO->writeRead(priv->asynContext, myCommand, strlen(myCommand),
|
||||
reply,COMLEN, 1.,&out,&in,&reason);
|
||||
return pasynOctetSyncIO->writeRead(priv->asynContext, command, strlen(command),
|
||||
reply,COMLEN, 1.,&out,&in,&reason);
|
||||
status = pasynOctetSyncIO->writeRead(
|
||||
priv->asynContext, myCommand, strlen(myCommand), reply, COMLEN,
|
||||
1., &out, &in, &reason);
|
||||
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));
|
||||
@ -392,7 +387,8 @@ static asynStatus el737_transactCommand(EL737priv *priv,char command[COMLEN],cha
|
||||
if (errno == EAGAIN) {
|
||||
errlogPrintf("Lost response to %s with EAGAIN\n", command);
|
||||
} else {
|
||||
snprintf(message,sizeof(message), "Lost communication with errno %d", errno);
|
||||
snprintf(message, sizeof(message),
|
||||
"Lost communication with errno %d", errno);
|
||||
/* force a reconnect */
|
||||
pasynOctetSyncIO->disconnect(priv->asynContext);
|
||||
}
|
||||
@ -401,33 +397,33 @@ static asynStatus el737_transactCommand(EL737priv *priv,char command[COMLEN],cha
|
||||
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);
|
||||
errlogPrintf("Setting external count message failed with %s\n",
|
||||
message);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static asynStatus sendStop(EL737priv *priv)
|
||||
{
|
||||
static asynStatus sendStop(EL737priv *priv) {
|
||||
char command[COMLEN], reply[COMLEN];
|
||||
// errlogPrintf("EL737: Sending stop\n");
|
||||
strcpy(command, "S");
|
||||
return el737_transactCommand(priv, command, reply);
|
||||
}
|
||||
|
||||
static void runEvents(EL737priv *priv)
|
||||
{
|
||||
static void runEvents(EL737priv *priv) {
|
||||
char command[COMLEN], reply[COMLEN], errName[256];
|
||||
int status;
|
||||
long dbStatus, nElements = 1, options = 0, threshCounter;
|
||||
long unsigned int myThreshold;
|
||||
|
||||
/*
|
||||
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.
|
||||
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 && priv->sendThreshold) {
|
||||
dbStatus = dbGetField(&priv->threshold,DBR_LONG,&myThreshold,&options, &nElements,NULL);
|
||||
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);
|
||||
@ -436,10 +432,13 @@ static void runEvents(EL737priv *priv)
|
||||
/*
|
||||
we have to set the threshold
|
||||
*/
|
||||
dbStatus = dbGetField(&priv->threshCounter,DBR_LONG,&threshCounter, &options, &nElements,NULL);
|
||||
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);
|
||||
errlogPrintf("Reading thresholdCounter failed with %s\n",
|
||||
errName);
|
||||
} else {
|
||||
if (threshCounter == 0) {
|
||||
threshCounter = 1;
|
||||
@ -460,11 +459,13 @@ static void runEvents(EL737priv *priv)
|
||||
}
|
||||
|
||||
if (priv->sendThreshold == 1) {
|
||||
// fallback when we do not have the DB fields or threshCounter is invalid
|
||||
// fallback when we do not have the DB fields or threshCounter is
|
||||
// invalid
|
||||
if (priv->presets[THRESHMON] > 0) {
|
||||
sprintf(command, "DL %d %d", (int)priv->presets[THRESHMON],
|
||||
(int)priv->presets[THRESHVAL]);
|
||||
// errlogPrintf("Sending threshold from presets, command %s\n", command);
|
||||
// errlogPrintf("Sending threshold from presets, command %s\n",
|
||||
// command);
|
||||
status = el737_transactCommand(priv, command, reply);
|
||||
sprintf(command, "DR %d", (int)priv->presets[THRESHMON]);
|
||||
status = el737_transactCommand(priv, command, reply);
|
||||
@ -496,15 +497,14 @@ static void runEvents(EL737priv *priv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (status != asynSuccess) {
|
||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n, errno =%d",
|
||||
errlogPrintf(
|
||||
"devScalerEL737::el737Thread communication problem %s\n, errno =%d",
|
||||
priv->asynContext->errorMessage, errno);
|
||||
}
|
||||
}
|
||||
|
||||
static void updateValues(EL737priv *priv)
|
||||
{
|
||||
static void updateValues(EL737priv *priv) {
|
||||
char command[COMLEN], reply[COMLEN];
|
||||
int status;
|
||||
float fTime;
|
||||
@ -514,20 +514,24 @@ static void updateValues(EL737priv *priv)
|
||||
status = el737_transactCommand(priv, command, reply);
|
||||
if (status != asynSuccess) {
|
||||
if (errno == EAGAIN) {
|
||||
errlogPrintf("devScalerEL737::el737Thread lost response to %s with EAGAIN\n", command);
|
||||
errlogPrintf(
|
||||
"devScalerEL737::el737Thread lost response to %s with EAGAIN\n",
|
||||
command);
|
||||
} else {
|
||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s, errno = %d\n",
|
||||
errlogPrintf("devScalerEL737::el737Thread communication problem "
|
||||
"%s, errno = %d\n",
|
||||
priv->asynContext->errorMessage, errno);
|
||||
}
|
||||
return;
|
||||
}
|
||||
status = sscanf(reply, "%f %ld %ld %ld %ld %ld %ld %ld %ld",
|
||||
&fTime, &m1, &m2, &m3, &m4, &m5, &m6, &m7, &m8);
|
||||
status = sscanf(reply, "%f %ld %ld %ld %ld %ld %ld %ld %ld", &fTime, &m1,
|
||||
&m2, &m3, &m4, &m5, &m6, &m7, &m8);
|
||||
if (status != 9) {
|
||||
/*
|
||||
old form with 4 monitors
|
||||
*/
|
||||
status = sscanf(reply, "%ld %ld %ld %ld %f", &m1, &m2, &m3, &m4, &fTime);
|
||||
status =
|
||||
sscanf(reply, "%ld %ld %ld %ld %f", &m1, &m2, &m3, &m4, &fTime);
|
||||
if (status != 5) {
|
||||
errlogPrintf("devScalerEL737::el737Thread bad RA reply %s\n",
|
||||
reply);
|
||||
@ -543,11 +547,9 @@ static void updateValues(EL737priv *priv)
|
||||
priv->values[6] = m6;
|
||||
priv->values[7] = m7;
|
||||
priv->values[8] = m8;
|
||||
|
||||
}
|
||||
|
||||
static void el737Thread(void *param)
|
||||
{
|
||||
static void el737Thread(void *param) {
|
||||
EL737priv *priv = (EL737priv *)param;
|
||||
epicsEventWaitStatus evStatus;
|
||||
double timeout = 60.;
|
||||
@ -581,12 +583,12 @@ static void el737Thread(void *param)
|
||||
status = sendStop(priv);
|
||||
}
|
||||
|
||||
|
||||
if (priv->counting) {
|
||||
strcpy(command, "RS");
|
||||
status = el737_transactCommand(priv, command, reply);
|
||||
if (status != asynSuccess) {
|
||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
||||
errlogPrintf("devScalerEL737::el737Thread communication "
|
||||
"problem %s\n",
|
||||
priv->asynContext->errorMessage);
|
||||
continue;
|
||||
}
|
||||
@ -619,23 +621,28 @@ static void el737Thread(void *param)
|
||||
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);
|
||||
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);
|
||||
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); */
|
||||
/* 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",
|
||||
errlogPrintf("devScalerEL737::el737Thread "
|
||||
"communication problem %s\n",
|
||||
priv->asynContext->errorMessage);
|
||||
continue;
|
||||
}
|
||||
@ -643,7 +650,8 @@ static void el737Thread(void *param)
|
||||
strcpy(command, "CO");
|
||||
status = el737_transactCommand(priv, command, reply);
|
||||
if (status != asynSuccess) {
|
||||
errlogPrintf("devScalerEL737::el737Thread communication problem %s\n",
|
||||
errlogPrintf("devScalerEL737::el737Thread "
|
||||
"communication problem %s\n",
|
||||
priv->asynContext->errorMessage);
|
||||
continue;
|
||||
}
|
||||
@ -658,4 +666,3 @@ static void el737Thread(void *param)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,18 @@
|
||||
|
||||
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(scaler,"$(P)")
|
||||
{
|
||||
field(DESC,"$(DESC)")
|
||||
|
@ -20,7 +20,6 @@ registrar(SINQControllerRegister)
|
||||
#include "/ioc/modules/scaler/koennecke/R3.14.12/dbd/scaler.dbd"
|
||||
|
||||
device(scaler,INST_IO,devScalerEL737,"asynScalerEL737")
|
||||
device(stringin,INST_IO,devCounterBoxStringError,"devCounterBoxStringError")
|
||||
|
||||
#--------- For lakeshore and magnets
|
||||
#include "/ioc/modules/stream/2.7.9/R3.14.12/dbd/stream.dbd"
|
||||
|
Reference in New Issue
Block a user