Files
sinqDAQ/db/daq_soft_proton.db

340 lines
8.8 KiB
Plaintext

# as retrieved via network from HIPA.
#
# This is created to be able reuse the SinqDAQ interface
# in Nicos, to avoid having more code to maintain there.
#
# This requires following macros to specified:
# INSTR: Instrument prefix, e.g. "SQAMOR:"
# NAME: Name of the DAQ, e.g. "PROTONDAQ"
# SHUTTER1_PV: PV of a shutter state will be taken as a gate signal for the protoon current
# SHUTTER1_CLOSED_VAL: Value of the shutter PV when the shutter is closed
# SHUTTER2_PV: PV of a second shutter state will be taken as a gate signal for the protoon current
# SHUTTER2_CLOSED_VAL: Value of the shutter PV when the shutter is closed
record(mbbi, "$(INSTR)$(NAME):STATUS")
{
field(DESC, "DAQ Status")
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 DAQ reports undocumented statusbits
field(FRVL, "4")
field(FRST, "INVALID")
# We start in idle
field(VAL, 0)
}
record(longin, "$(INSTR)$(NAME):CHANNELS")
{
field(DESC, "Total Supported Channels")
field(VAL, 1)
field(DISP, 1)
}
record(stringin, "$(INSTR)$(NAME):MsgTxt")
{
field(DESC, "Miscellanous messages")
}
record(bi, "$(INSTR)$(NAME):IS_LOWRATE")
{
field(ZNAM, "LOW RATE")
field(ONAM, "GOOD RATE")
}
################################################################################
# Commands
################################################################################
record(ao, "$(INSTR)$(NAME):PRESET-COUNT")
{
field(DESC, "Count until preset reached")
field(VAL, 0)
field(PREC, 2)
field(FLNK, "$(INSTR)$(NAME):PRESET-COUNT-TRIG")
}
record(longout, "$(INSTR)$(NAME):PRESET-COUNT-TRIG")
{
field(DESC, "Count until preset reached")
# Signal count preset as command
field(VAL, 1)
field(OUT, "$(INSTR)$(NAME):COMMAND-TRIG PP")
field(FLNK, "$(INSTR)$(NAME):COUNT-TYPE")
}
record(ao, "$(INSTR)$(NAME):PRESET-TIME")
{
field(DESC, "Count for specified time")
field(VAL, 0)
field(PREC, 2)
field(EGU, "seconds")
field(FLNK, "$(INSTR)$(NAME):PRESET-TIME-TRIG")
}
record(longout, "$(INSTR)$(NAME):PRESET-TIME-TRIG")
{
field(DESC, "Count until preset time reached")
# Signal count preset as command
field(VAL, 2)
field(OUT, "$(INSTR)$(NAME):COMMAND-TRIG PP")
field(FLNK, "$(INSTR)$(NAME):COUNT-TYPE")
}
record(longout, "$(INSTR)$(NAME):PAUSE")
{
field(DESC, "Pause the current count")
field(VAL, 3)
field(DRVL, 3)
field(DRVH, 3)
field(OUT, "$(INSTR)$(NAME):COMMAND-TRIG PP")
}
record(longout, "$(INSTR)$(NAME):CONTINUE")
{
field(DESC, "Continue with a count that was paused")
field(VAL, 4)
field(DRVL, 4)
field(DRVH, 4)
field(OUT, "$(INSTR)$(NAME):COMMAND-TRIG PP")
}
record(longout, "$(INSTR)$(NAME):STOP")
{
field(DESC, "Stop the current counting operation")
field(VAL, 5)
field(DRVL, 5)
field(DRVH, 5)
field(OUT, "$(INSTR)$(NAME):COMMAND-TRIG PP")
}
record(longout, "$(INSTR)$(NAME):FULL-RESET")
{
field(DESC, "Perform full reset")
field(VAL, 6)
field(DRVL, 6)
field(DRVH, 6)
field(OUT, "$(INSTR)$(NAME):COMMAND-TRIG PP")
}
# Emulate Reset elapsed time
# 0. set status to busy
# 1. set elapsed time to 0
# 2. set status to OK
record(seq, "$(INSTR)$(NAME):CT")
{
field(SELM, "All")
field(LNK0, "$(INSTR)$(NAME):ETS PP")
field(DO0, 1)
field(LNK1, "$(INSTR)$(NAME):ELAPSED-TIME PP")
field(DO1, 0)
field(LNK2, "$(INSTR)$(NAME):ETS PP")
field(DO2, 0)
}
# Record is to signal command given by the client to the emulated counter.
# It's set back to no command from the emulated counter subroutine record
record(mbbi, "$(INSTR)$(NAME):COMMAND-TRIG")
{
field(DESC, "Command type")
field(VAL, 0)
field(ZRST, "No command")
field(ZRVL, 0)
field(ONST, "Count preset command")
field(ONVL, 1)
field(TWST, "Time preset command")
field(TWVL, 2)
field(THST, "Pause command")
field(THVL, 3)
field(FRST, "Continue command")
field(FRVL, 4)
field(FVST, "Stop command")
field(FVVL, 5)
field(SXST, "Full reset command")
field(SXVL, 6)
}
# Copy COMMAND-TRIG to memorize what type of count is on-going
record(longin, "$(INSTR)$(NAME):COUNT-TYPE") {
field(INP, "$(INSTR)$(NAME):COMMAND-TRIG.VAL NPP")
field(VAL, 0)
}
record(longout,"$(INSTR)$(NAME):THRESHOLD-MONITOR")
{
# Alias to RBV to be compatible with higher level interface
alias("$(INSTR)$(NAME):THRESHOLD-MONITOR_RBV")
field(DESC, "Channel monitored for minimum rate")
field(VAL, "1") # Monitor
field(DRVL, "0") # Smallest Threshold Channel (0 is off)
field(DRVH, "1") # Largest Threshold Channel
}
record(ao,"$(INSTR)$(NAME):THRESHOLD")
{
# Alias to RBV to be compatible with higher level interface
alias("$(INSTR)$(NAME):THRESHOLD_RBV")
field(DESC, "Minimum rate for counting to proceed")
field(VAL, "1") # Default Rate
field(DRVL, "1") # Minimum Rate
field(DRVH, "100000") # Maximum Rate
field(OMSL, "supervisory")
}
record(ai,"$(INSTR)$(NAME):ELAPSED-TIME")
{
field(DESC, "DAQ Measured Time")
field(EGU, "sec")
# We need to process ETS to signal to client
# field(FLNK, "$(INSTR)$(NAME):ETO")
}
# Trigger a change in status as value returned to 0
#record(seq, "$(INSTR)$(NAME):ETO")
#{
# field(DESC, "Trigger Returned to 0 Status")
# field(LNK0, "$(INSTR)$(NAME):ETS PP")
# field(DO0, 0)
# field(SELM, "Specified")
# field(SELL, "$(INSTR)$(NAME):ELAPSED-TIME.VAL")
#}
# Current Status of elapsed time
# This is only to satify the interface.
record(bi, "$(INSTR)$(NAME):ETS")
{
field(DESC, "Channel Status")
field(VAL, 0)
field(ZNAM, "OK")
field(ONAM, "CLEARING")
}
record(longout, "$(INSTR)$(NAME):MONITOR-CHANNEL")
{
alias("$(INSTR)$(NAME):MONITOR-CHANNEL_RBV")
field(DESC, "PRESET-COUNT Monitors this channel")
field(VAL, 1)
}
# Array Subroutine record which emulates the counterbox functionality
# Use an aSub because it allows specifying the type.
record(aSub, "$(INSTR)$(NAME):EMULATION")
{
# Scan rate determines how often we sample the rate
# and how often the counter value updates.
field(SCAN, ".1 second")
field(SNAM, "processEmulatedCounter")
# The first 4 inputs are also mapped as the first 4 outputs
field(INPA, "$(INSTR)$(NAME):STATUS")
field(FTA, "ULONG")
field(INPB, "$(INSTR)$(NAME):M1")
field(FTB, "INT64")
field(INPC, "$(INSTR)$(NAME):ELAPSED-TIME")
field(FTC, "DOUBLE")
field(INPD, "$(INSTR)$(NAME):COMMAND-TRIG")
field(FTD, "ULONG")
field(INPE, "$(INSTR)$(NAME):THRESHOLD")
field(FTE, "DOUBLE")
# Address the PV which are mapped as input backwards
field(INPF, "$(INSTR)$(NAME):COUNT-TYPE")
field(FTF, "ULONG")
field(INPG, "$(INSTR)$(NAME):PRESET-COUNT")
field(FTG, "DOUBLE")
field(INPH, "$(INSTR)$(NAME):PRESET-TIME")
field(FTH, "DOUBLE")
# L is last input before EPICS 7.0.10
field(INPJ, "$(INSTR)$(NAME):R1-PREV")
field(FTJ, "DOUBLE")
field(INPL, "$(INSTR)$(NAME):R1 PP")
field(FTL, "DOUBLE")
# The first 4 outputs are also mapped as the first 4 inputs
field(OUTA, "$(INSTR)$(NAME):STATUS PP")
field(FTVA, "ULONG")
field(OUTB, "$(INSTR)$(NAME):M1 PP")
field(FTVB, "INT64")
field(OUTC, "$(INSTR)$(NAME):ELAPSED-TIME PP")
field(FTVC, "DOUBLE")
field(OUTD, "$(INSTR)$(NAME):COMMAND-TRIG PP")
field(FTVD, "ULONG")
field(OUTE, "$(INSTR)$(NAME):R1-PREV PP")
field(FTVE, "DOUBLE")
field(OUTF, "$(INSTR)$(NAME):IS_LOWRATE PP")
field(FTVF, "ULONG")
field(OUTF, "$(INSTR)$(NAME):MsgTxt PP")
field(FTVF, "CHAR")
field(NEVF, 40)
}
#######################
# Channel interface
#######################
record(int64in, "$(INSTR)$(NAME):M1")
{
field(DESC, "DAQ CH0, proton current")
field(EGU, "cts")
}
# The proton rate take by a PV over the network, PV named indicated by $(REMOTE_RATE_PV) macro
# It emulates Zero rate if either shutter is closed.
record(calc, "$(INSTR)$(NAME):R1")
{
field(DESC, "Rate of DAQ CH0 proton current")
#field(INPA, "$(REMOTE_RATE_PV) CA")
field(INPA, "$(INSTR)$(NAME):PROTON_CURR")
field(INPB, "$(SHUTTER1_PV=0)")
field(INPC, "$(SHUTTER1_CLOSED_VAL=1)")
field(INPD, "$(SHUTTER2_PV=0)")
field(INPE, "$(SHUTTER2_CLOSED_VAL=1)")
# If either shutter is closed we have no rate
field(CALC, "B != C && D != E ? A : 0")
field(EGU, "cts/sec")
}
# Store previous rate value, so we can average over the period
record(ai, "$(INSTR)$(NAME):R1-PREV") {
field(DESC, "Previous rate of DAQ CH0 proton current")
}
# Emulate clearing channel
# 0. set status to busy
# 1. set elapsed time to 0
# 2. set status to OK
record(seq, "$(INSTR)$(NAME):C1")
{
field(SELM, "All")
field(LNK0, "$(INSTR)$(NAME):S1 PP")
field(DO0, 1)
field(LNK1, "$(INSTR)$(NAME):M1 PP")
field(DO1, 0)
field(LNK2, "$(INSTR)$(NAME):S1 PP")
field(DO2, 0)
}
# Current Status of Channel
# This is only to satify the interface.
record(bi, "$(INSTR)$(NAME):S1")
{
field(DESC, "Channel Status")
field(VAL, 0)
field(ZNAM, "OK")
field(ONAM, "CLEARING")
}
record(calc, "$(INSTR)$(NAME):PROTON_CURR") {
field(SCAN, ".1 second")
field(CALC, "1500 + 101 * SIN(A)")
field(INPA, "$(INSTR)$(NAME):PROTON_CURR_VAR PP")
}
record(calc, "$(INSTR)$(NAME):PROTON_CURR_VAR") {
field(CALC, "VAL + 0.001")
}