Files
sinqDAQ/db/channels.db
T
wall_e 0789462aed
Example Action / Lint (push) Successful in 10s
Example Action / BuildAndTest (push) Failing after 16s
rename/refactor channels.db
2026-06-03 16:49:47 +02:00

240 lines
7.1 KiB
Plaintext

# EPICS Database for streamdevice specific to measurement channels
#
# Macros
# INSTR - Prefix
# NAME - the device name, e.g. EL737
# PROTO - Stream device protocol file
# ASYN_PORT - Low level Asyn IP Port to DAQ
# CHANNEL - the number associated with the measurment channel
################################################################################
# Channel Specific
# Updated by READALL, at POLL_FREQ frequency
record(int64in, "$(INSTR)$(NAME):CH$(CHANNEL)")
{
field(DESC, "DAQ CH$(CHANNEL) Counts")
field(EGU, "cts")
field(FLNK, "$(INSTR)$(NAME):CH$(CHANNEL)_POLL")
}
record(ai, "$(INSTR)$(NAME):CH$(CHANNEL)_RATE")
{
field(DESC, "Rate of DAQ CH$(CHANNEL)")
field(INP, "@$(PROTO) readRate($(INSTR)$(NAME):, $(CHANNEL)) $(ASYN_PORT)")
field(DTYP, "stream")
field(EGU, "cts/sec")
field(SCAN, "1 second")
}
record(ao, "$(INSTR)$(NAME):CH$(CHANNEL)_THRESH")
{
# Rate for this channel only applies, if
# $(INSTR)$(NAME):THRESHOLD-MONITOR == $(CHANNEL)
field(DESC, "Sets min rate for counting to proceed")
field(OMSL, "supervisory")
field(OROC, "0")
field(OUT, "@$(PROTO) setMinRate($(INSTR)$(NAME):, $(CHANNEL)) $(ASYN_PORT)")
field(DTYP, "stream")
field(EGU, "cts/sec")
}
################################################################################
# Poll Loop
record(dfanout, "$(INSTR)$(NAME):CH$(CHANNEL)_POLL")
{
field(DESC, "Channel $(CHANNEL) poll sequence")
field(SELM, "All")
field(OMSL, "closed_loop")
field(DOL, 1)
field(OUTA, "$(INSTR)$(NAME):CH$(CHANNEL)_HWCS.PROC")
field(OUTB, "$(INSTR)$(NAME):CH$(CHANNEL)_STSRAW.PROC")
field(OUTC, "$(INSTR)$(NAME):CH$(CHANNEL)_REACHED.PROC")
}
################################################################################
# Clearing Channel Counts
record(bi, "$(INSTR)$(NAME):CH$(CHANNEL)_CLEARED")
{
field(VAL, 0)
field(ZNAM, "Cleared")
field(ONAM, "Clearing")
}
# Trigger a change in status as value returned to 0
record(seq, "$(INSTR)$(NAME):CH$(CHANNEL)_HWCS")
{
field(DESC, "Trigger Returned to 0 Status")
field(SELM, "Specified")
field(SELL, "$(INSTR)$(NAME):CH$(CHANNEL).VAL")
field(DO0, 0)
field(LNK0, "$(INSTR)$(NAME):CH$(CHANNEL)_CLEARED PP")
}
record(dfanout, "$(INSTR)$(NAME):CH$(CHANNEL)_CLEAR")
{
field(DESC, "Clears the current channel count")
field(SELM, "All")
field(OMSL, "closed_loop")
field(DOL, 1)
field(OUTA, "$(INSTR)$(NAME):CH$(CHANNEL)_CLEARED PP PP")
field(OUTB, "$(INSTR)$(NAME):CH$(CHANNEL)_HWC.PROC PP")
}
record(longout, "$(INSTR)$(NAME):CH$(CHANNEL)_HWC")
{
field(DESC, "Clear in Hardware")
field(DTYP, "stream")
field(OMSL, "closed_loop")
field(DOL, "$(INSTR)$(NAME):CH$(CHANNEL)_BM NPP")
field(OUT, "@$(PROTO) clearChannel($(INSTR)$(NAME):) $(ASYN_PORT)")
}
################################################################################
# Determining Channel Status
record(calc, "$(INSTR)$(NAME):CH$(CHANNEL)_STSRAW")
{
field(DESC, "Channel Status")
field(INPA, "$(INSTR)$(NAME):STATUS NPP")
field(INPB, "$(INSTR)$(NAME):CH$(CHANNEL)_CLEARED NPP")
field(INPC, "$(INSTR)$(NAME):CH$(CHANNEL)_SET NPP")
field(CALC, "A == 1 || B || C")
field(FLNK, "$(INSTR)$(NAME):CH$(CHANNEL)_STS")
}
# Current Status of Channel, i.e. is it ready for a new operation?
record(mbbi, "$(INSTR)$(NAME):CH$(CHANNEL)_STS")
{
field(DESC, "Channel Status")
field(INP, "$(INSTR)$(NAME):CH$(CHANNEL)_STSRAW NPP MS")
field(ZRVL, "0")
field(ZRST, "Idle")
field(ONVL, "1")
field(ONST, "Busy")
}
################################################################################
# Channel Preset
# If set, stop count once preset reached
record(int64in, "$(INSTR)$(NAME):CH$(CHANNEL)_PRESET")
{
field(DESC, "Monitor Count Preset")
field(VAL, 0)
field(FLNK, "$(INSTR)$(NAME):CH$(CHANNEL)_SETTING")
}
record(calcout, "$(INSTR)$(NAME):CH$(CHANNEL)_REACHED")
{
field(DESC, "Stop if preset reached")
field(INPA, "$(INSTR)$(NAME):CH$(CHANNEL) NPP")
field(INPB, "$(INSTR)$(NAME):CH$(CHANNEL)_PRESET NPP")
field(CALC, "B > 0 && A >= B")
field(OOPT, "When Non-zero")
field(OUT, "$(INSTR)$(NAME):STOP.PROC")
}
################################################################################
# Setting Channel Preset
record(bi, "$(INSTR)$(NAME):CH$(CHANNEL)_SET")
{
field(DESC, "Channel Status")
field(VAL, 0)
field(ZNAM, "Set")
field(ONAM, "Setting")
}
record(calcout, "$(INSTR)$(NAME):CH$(CHANNEL)_CHECK_SET")
{
field(DESC, "Was preset fully configured")
field(SCAN, ".1 second")
field(INPA, "$(INSTR)$(NAME):CH$(CHANNEL)_SET NPP")
field(INPB, "$(INSTR)$(NAME):MONITOR-CHANNEL NPP")
field(INPC, "$(INSTR)$(NAME):MONITOR-CHANNEL_RBV NPP")
field(CALC, "A && ( ($(CHANNEL) # B) || (B = C) )")
field(OOPT, "When Non-zero")
field(DOPT, "Use OCAL")
field(OCAL, "0")
# This is just a delay, as otherwise, Nicos will not see
# the $(INSTR)$(NAME):CH$(CHANNEL)_SET state change
# when not changing which monitor channel the preset
# applies to. Is there a better way?
field(ODLY, .5)
field(OUT, "$(INSTR)$(NAME):CH$(CHANNEL)_SET PP")
}
record(dfanout, "$(INSTR)$(NAME):CH$(CHANNEL)_SETTING")
{
field(DESC, "Trigger setting HW preset")
field(SELM, "All")
field(OMSL, "closed_loop")
field(DOL, 1)
field(OUTA, "$(INSTR)$(NAME):CH$(CHANNEL)_SET PP")
field(OUTB, "$(INSTR)$(NAME):CH$(CHANNEL)_IN_HW.PROC PP")
}
record(calcout, "$(INSTR)$(NAME):CH$(CHANNEL)_IN_HW")
{
field(DESC, "Possible to configure in HW")
field(INPA, "$(INSTR)$(NAME):PRESET-TYPE NPP")
field(INPB, "$(INSTR)$(NAME):CH$(CHANNEL)_PRESET NPP")
field(INPC, "$(INSTR)$(NAME):MONITOR-CHANNEL.DRVH NPP")
field(CALC, "A=0 && B>0 && $(CHANNEL)<=C")
field(OOPT, "When Non-zero")
field(DOPT, "Use OCAL")
field(OCAL, "1")
field(OUT, "$(INSTR)$(NAME):CH$(CHANNEL)_HW_CONF.PROC")
}
record(ao, "$(INSTR)$(NAME):CH$(CHANNEL)_HW_CONF")
{
field(DESC, "Configure in HW")
field(OMSL, "closed_loop")
field(DOL, $(CHANNEL))
field(OUT, "$(INSTR)$(NAME):MONITOR-CHANNEL PP")
field(FLNK, "$(INSTR)$(NAME):CH$(CHANNEL)_SET_PTYPE PP")
}
record(ao, "$(INSTR)$(NAME):CH$(CHANNEL)_SET_PTYPE")
{
field(OMSL, "closed_loop")
field(DOL, 2)
field(OUT, "$(INSTR)$(NAME):PRESET-TYPE PP")
}
################################################################################
# Unfortunately, clearing the channels is somewhat complicated as a result of
# the addition of more channels over time and minimal changes to the underlying interface
#
# Urs Greuter provided the following explanation:
#
# bei den Befehlen CC r und HC r ist der Parameter r als bit-Maske zu verstehen:
#
# Bit0: Zähler Channel 1
# Bit2: Zähler Channel 2
# Bit3: Zähler Channel 3
# Bit4: Zähler Channel 4
# Bit5: Zähler Channel Timer
# Bit6: Zähler Channel 5
# Bit7: Zähler Channel 6
# Bit8: Zähler Channel 7
# Bit9: Zähler Channel 8
#
# Beispiele:
# CC 1 setzt den Zähler des Channels 1 zurück
# CC 4 setzt den Zähler des Channels 3 zurück
# CC 5 setzt gleichzeitig die Zähler der Channels 1 und 3 zurück
# CC 16 ist gleichbedeutend wie CT (Timer zurücksetzen)
# CC 511 setzt gleichzeitig die Zähler aller Kanäle (auch des Timers) zurück.
record(calc, "$(INSTR)$(NAME):CH$(CHANNEL)_BM")
{
field(DESC, "Bit Mask for Channel")
field(INPA, $(CHANNEL))
field(CALC, "A > 4 ? 2 ^ A : 2 ^ (A-1)")
field(PINI, "YES")
}