# 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)_STS_RAW.PROC") field(OUTC, "$(INSTR)$(NAME):CH$(CHANNEL)_REACHED.PROC") } ################################################################################ # Clearing Channel Counts record(bi, "$(INSTR)$(NAME):CH$(CHANNEL)_CLEARED") { field(DESC, "are hw counts being 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)_STS_RAW") { field(DESC, "Raw 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, "(0 < A && A < 4) || 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)_STS_RAW 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, "is preset being configured") 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") }