# EPICS Database for streamdevice support with SinqDAQ Systems # # Macros # INSTR - Prefix # NAME - the device name, e.g. EL737 # PROTO - Stream device protocol file # ASYN_PORT - Low level Asyn IP Port to EL737 # Send initial initialisation commands record(bo, "$(INSTR)$(NAME):INIT-CONF") { field(DESC, "Initialises the DAQ") field(OUT, "@$(PROTO) initialise($(INSTR)$(NAME):) $(ASYN_PORT)") field(PINI, "YES") # Run at init field(DTYP, "stream") } record(longout, "$(INSTR)$(NAME):FULL-RESET") { field(DESC, "Reset the DAQ") field(OUT, "@$(PROTO) fullReset($(INSTR)$(NAME):) $(ASYN_PORT)") field(DTYP, "stream") } ################################################################################ # Status Variables record(stringin, "$(INSTR)$(NAME):MsgTxt") { field(DESC, "Unexpected received response") field(DTYP, "devDAQStringError") field(FLNK, "$(INSTR)$(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 DAQ off and # on again or running a full reset record(scalcout, "$(INSTR)$(NAME):INVALID-CONFIG") { field(DESC, "Has the DAQ been configured?") field(CALC, "AA[0,2] == '?OF'") field(INAA, "$(INSTR)$(NAME):MsgTxt") field(FLNK, "$(INSTR)$(NAME):REINIT-CONF") } record(seq, "$(INSTR)$(NAME):REINIT-CONF") { field(LNK1, "$(INSTR)$(NAME):INIT-CONF PP") field(DO1, 1) field(SELM, "Specified") field(SELL, "$(INSTR)$(NAME):INVALID-CONFIG.VAL") } # Important! The "$(INSTR)$(NAME):READALL" isn't configure with a SCAN. Instead, # it must always be triggered after the value of $(INSTR)$(NAME):RAW-STATUS is # updated, so that it can't be the case that the status changes back from # counting to idle, without having updated the time and count values. record(longin, "$(INSTR)$(NAME):RAW-STATUS") { field(DESC, "Raw returned status value") field(DTYP, "stream") field(SCAN, ".5 second") field(INP, "@$(PROTO) readStatus($(INSTR)$(NAME):) $(ASYN_PORT)") field(FLNK, "$(INSTR)$(NAME):READALL") } record(calc, "$(INSTR)$(NAME):MAP-STATUS") { field(DESC, "Maps Raw Status to State") field(INPA, "$(INSTR)$(NAME):RAW-STATUS NPP") field(INPB, "$(INSTR)$(NAME):INVALID-CONFIG NPP") field(INPC, "$(INSTR)$(NAME):RAW-STATUS.UDF NPP") # should also be invalid if can't read the status field(CALC, "(B=1||C==1)?4:A=0?0:(A=1||A=2)?1:(A=5||A=6)?2:(A=9||A=13||A=10||A=14)?3:4") field(FLNK, "$(INSTR)$(NAME):STATUS") } record(mbbi, "$(INSTR)$(NAME):STATUS") { field(DESC, "DAQ Status") field(INP, "$(INSTR)$(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 DAQ reports undocumented statusbits field(FRVL, "4") field(FRST, "INVALID") } record(longin, "$(INSTR)$(NAME):CHANNELS") { field(DESC, "Total Supported Channels") field(VAL, $(CHANNELS)) field(DISP, 1) } # Trigger a change in status as clearing record(bo, "$(INSTR)$(NAME):ETT") { field(DESC, "Trigger Clearing Status") field(VAL, 1) field(OUT, "$(INSTR)$(NAME):ETS PP") } # 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 Channel, i.e. is it ready to count? record(bi, "$(INSTR)$(NAME):ETS") { field(DESC, "Channel Status") field(VAL, 0) field(ZNAM, "OK") field(ONAM, "CLEARING") } ################################################################################ # Count Commands record(ao,"$(INSTR)$(NAME):PRESET-COUNT") { field(DESC, "Count until preset reached") field(DTYP, "stream") field(OUT, "@$(PROTO) startWithCountPreset$(CHANNELS)($(INSTR)$(NAME):) $(ASYN_PORT)") field(VAL, 0) field(PREC, 2) field(FLNK, "$(INSTR)$(NAME):RAW-STATUS") } record(ao,"$(INSTR)$(NAME):PRESET-TIME") { field(DESC, "Count for specified time") field(DTYP, "stream") field(OUT, "@$(PROTO) startWithTimePreset$(CHANNELS)($(INSTR)$(NAME):) $(ASYN_PORT)") field(VAL, 0) field(PREC, 2) field(EGU, "seconds") field(FLNK, "$(INSTR)$(NAME):RAW-STATUS") } record(bo,"$(INSTR)$(NAME):PAUSE") { field(DESC, "Pause the current count") field(DTYP, "stream") field(OUT, "@$(PROTO) pauseCount($(INSTR)$(NAME):) $(ASYN_PORT)") field(VAL, "0") field(FLNK, "$(INSTR)$(NAME):RAW-STATUS") } record(bo,"$(INSTR)$(NAME):CONTINUE") { field(DESC, "Continue with a count that was paused") field(DTYP, "stream") field(OUT, "@$(PROTO) continueCount($(INSTR)$(NAME):) $(ASYN_PORT)") field(VAL, "0") field(FLNK, "$(INSTR)$(NAME):RAW-STATUS") } record(longout, "$(INSTR)$(NAME):STOP") { field(DESC, "Stop the current counting operation") field(DTYP, "stream") field(OUT, "@$(PROTO) stopCount($(INSTR)$(NAME):) $(ASYN_PORT)") field(FLNK, "$(INSTR)$(NAME):RAW-STATUS") } record(ao,"$(INSTR)$(NAME):THRESHOLD") { field(DESC, "Minimum rate for counting to proceed") field(VAL, "1") # Default Rate # Could perhaps still be improved. # It seems to only accept whole counts? field(DRVL, "1") # Minimum Rate field(DRVH, "100000") # Maximum Rate field(OMSL, "supervisory") field(OROC, "0") field(OUT, "$(INSTR)$(NAME):THRESHOLD-F PP") } record(ai,"$(INSTR)$(NAME):THRESHOLD_RBV") { field(DESC, "Minimum rate for counting to proceed") field(INP, "@$(PROTO) readMinRate($(INSTR)$(NAME):) $(ASYN_PORT)") field(DTYP, "stream") field(SCAN, "1 second") field(EGU, "cts/sec") } record(longout,"$(INSTR)$(NAME):THRESHOLD-MONITOR") { field(DESC, "Channel monitored for minimum rate") field(VAL, "1") # Monitor field(DRVL, "0") # Smallest Threshold Channel (0 is off) field(DRVH, "$(CHANNELS)") # Largest Threshold Channel field(OUT, "@$(PROTO) setRateMonitor($(INSTR)$(NAME):) $(ASYN_PORT)") field(DTYP, "stream") } record(longin,"$(INSTR)$(NAME):THRESHOLD-MONITOR_RBV") { field(DESC, "Channel monitored for minimum rate") field(INP, "@$(PROTO) readRateMonitor($(INSTR)$(NAME):) $(ASYN_PORT)") field(DTYP, "stream") field(SCAN, "1 second") field(EGU, "CH") } record(longout, "$(INSTR)$(NAME):CT") { field(DESC, "Clear the timer") field(DTYP, "stream") field(OUT, "@$(PROTO) clearTimer($(INSTR)$(NAME):) $(ASYN_PORT)") field(FLNK, "$(INSTR)$(NAME):ETT") } ################################################################################ # Read all monitors values record(ai, "$(INSTR)$(NAME):READALL") { field(DESC, "Reads monitors and elapsed time") field(INP, "@$(PROTO) readAll$(CHANNELS)($(INSTR)$(NAME):) $(ASYN_PORT)") field(DTYP, "stream") field(FLNK, "$(INSTR)$(NAME):MAP-STATUS") } record(ai,"$(INSTR)$(NAME):ELAPSED-TIME") { field(DESC, "DAQ Measured Time") field(EGU, "sec") field(FLNK, "$(INSTR)$(NAME):ETO") }