diff --git a/Makefile b/Makefile index 3772b5a..875c952 100644 --- a/Makefile +++ b/Makefile @@ -18,12 +18,14 @@ TEMPLATES += db/readstring.db TEMPLATES += db/writeusint.db TEMPLATES += db/readusint.db -# Specific devices to include in the release -TEMPLATES += db/shutter.db -TEMPLATES += templates/shutter.substitutions -SCRIPTS += scripts/shutter.cmd +# Shutter Specific +TEMPLATES += shutter/shutter.db +TEMPLATES += shutter/shutter.substitutions +SCRIPTS += shutter/shutter.cmd SCRIPTS += sim/shutter_sim.py -TEMPLATES += db/sans_llb_beamstop.db -TEMPLATES += templates/sans_llb_beamstop.substitutions -SCRIPTS += scripts/sans_llb_beamstop.cmd +# Beamstop Specific +TEMPLATES += beamstop/sans_llb_beamstop.db +TEMPLATES += beamstop/beamstop_motors.proto +TEMPLATES += beamstop/sans_llb_beamstop.substitutions +SCRIPTS += beamstop/sans_llb_beamstop.cmd diff --git a/beamstop/beamstop_motors.proto b/beamstop/beamstop_motors.proto new file mode 100644 index 0000000..667d31a --- /dev/null +++ b/beamstop/beamstop_motors.proto @@ -0,0 +1,20 @@ +ReplyTimeout = 1000; +ReadTimeout = 100; + +pmac_get { + InTerminator = CR ACK; + out "\$1"; + in "%d"; +} + +st { + InTerminator = CR ACK; + out "P553 Q401 Q501 P423 P523"; + in "%(A)d%*[ ]%(B)f%*[ ]%(C)f\r%(D)d\r%(E)d"; +} + +stop { + InTerminator = CR ACK; + out "M04=8 M05=8"; + in "%*s"; +} diff --git a/scripts/sans_llb_beamstop.cmd b/beamstop/sans_llb_beamstop.cmd similarity index 76% rename from scripts/sans_llb_beamstop.cmd rename to beamstop/sans_llb_beamstop.cmd index 42159de..5a1c1fc 100644 --- a/scripts/sans_llb_beamstop.cmd +++ b/beamstop/sans_llb_beamstop.cmd @@ -9,6 +9,8 @@ # # out IO Interrupt Delay (if 0 then only reacts on a change) # ) +# Expects as an argument, the PV's for the motors bsx and bsy. + epicsEnvSet("SPS_REGISTER_NAME", "SPS-BEAMSTOP") epicsEnvSet("SPS_FETCH_SIZE", "40") epicsEnvSet("SPS_WRITE_SIZE", "2") @@ -19,7 +21,7 @@ s7plcFWConfigure("$(SPS_REGISTER_NAME)", "$(SPS_IP)", "$(FETCH_PORT=2000),1,$(FE dbLoadRecords("$(sinqSPS_DB)/sps_status.db", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME)") # Shutter PVs -dbLoadTemplate("$(sinqSPS_DB)/sans_llb_beamstop.substitutions", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME)") +dbLoadTemplate("$(sinqSPS_DB)/sans_llb_beamstop.substitutions", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME), STATUS_FLNK=$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") # Additional Mapping PVs -dbLoadRecords("$(sinqSPS_DB)/sans_llb_beamstop.db", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME)") +dbLoadRecords("$(sinqSPS_DB)/sans_llb_beamstop.db", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME), BS_MCU=$(BS_MCU), BS_MCU_ASYN_PORT=$(BS_MCU_ASYN_PORT), PROTO=$(sinqSPS_DB)beamstop_motors.proto") diff --git a/beamstop/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db new file mode 100644 index 0000000..1964958 --- /dev/null +++ b/beamstop/sans_llb_beamstop.db @@ -0,0 +1,452 @@ +################################################################################ +# Beamstop Changer +################################################################################ + +record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-INIT") +{ + field(DESC, "Initialises BEAMSTOP PV") + field(DOL, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV NPP") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") + field(OMSL, "closed_loop") + field(PINI, "YES") +} + +record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP") +{ + field(DESC, "Select new Beamstop") + field(DRVL, 0) + field(DRVH, 3) + field(PINI, "NO") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY.PROC PP") +} + +# Reset status +record(seq, "$(INSTR)$(SPS_REGISTER_NAME):RESET") +{ + field(DESC, "Try to reset status") + # Set the beamstop setpoint to same as readback + # in case they are out of sync, i.e. retry error. + field(DOL0, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV NPP") + field(LNK0, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") + field(DOL1, 0) + field(LNK1, "$(INSTR)$(SPS_REGISTER_NAME):STATUS PP") + field(SELM, "All") +} + +record(bi, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") +{ + field(DESC, "Internal Busy State") + field(VAL, 0) + field(ZNAM, "Ready") + field(ONAM, "Busy") +} + +# Make sure to disable motors before actually triggering SPS so there can be no +# chance, that they switch to a busy state in Nicos before being disabled +record(seq, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY") +{ + field(DESC, "Trigger Internal Busy Status") + field(SELM, "All") + # This determines the number of max retry ticks + field(DOL0, 5) + field(LNK0, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") + field(DOL1, "$(INSTR)$(SPS_REGISTER_NAME):BSX-DISV PP") + field(LNK1, "$(BS_MCU):bsx.DISV PP") + field(DOL2, "$(INSTR)$(SPS_REGISTER_NAME):BSY-DISV PP") + field(LNK2, "$(BS_MCU):bsy.DISV PP") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-OUT") +} + +# Can be used to disable BSX and BSY during +# a beamstop change +record(calc, "$(INSTR)$(SPS_REGISTER_NAME):BSX-DISV") +{ + field(INPA, "$(BS_MCU):bsx.DISA NPP") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS NPP") + field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):BUSY NPP") + field(CALC, "(B=0)&&(C=0)?!A:A") +} + +record(calc, "$(INSTR)$(SPS_REGISTER_NAME):BSY-DISV") +{ + field(INPA, "$(BS_MCU):bsy.DISA NPP") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS NPP") + field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):BUSY NPP") + field(CALC, "(B=0)&&(C=0)?!A:A") +} + +record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-OUT") +{ + field(DESC, "Send new selection to SPS") + field(DOL, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-RAW PP") + field(OMSL, "closed_loop") + field(DRVL, 0) + field(DRVH, 3) + field(PINI, "NO") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER-DELAY") +} + +record(seq, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER-DELAY") +{ + field(DESC, "Delays Internal Trigger as SPS too slow") + field(DOL0, 1) + field(LNK0, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER.PROC PP") + field(DLY0, 0.5) + field(SELM, "All") + field(PINI, "NO") +} + +record(longout, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER") +{ + field(DESC, "Internal Trigger") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):EXECUTE-CHANGE PP") + field(OMSL, "closed_loop") + field(DOL, 1) + field(PINI, "NO") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS PP") +} + +# This is a hack, the SPS sometimes doesn't registers the beamstop +# execute command. +record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):RETRY") +{ + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV NPP") + field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") + # Can't trust the SPS, so instead monitor the MCU state + field(INPD, "$(BS_MCU):BS:TARGET_RANGE NPP") + field(CALC, "A#B&&C#0&&D=0?1:0") + field(DOPT, "Use CALC") + field(OOPT, "When Non-zero") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-OUT.PROC PP") + field(SCAN, "2 second") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SPS-CHANGING") +} + +record(calc, "$(INSTR)$(SPS_REGISTER_NAME):SPS-CHANGING") +{ + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):MOVES NPP") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):IN-POSITION NPP") + field(CALC, "A=1||B=0") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):MCU-CHANGING") +} + +# Can't trust the SPS +record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MCU-CHANGING") +{ + field(INPA, "$(BS_MCU):BS:TARGET_RANGE NPP") + field(CALC, "A#0") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):DECREASE-BUSY-TICK") +} + +record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):DECREASE-BUSY-TICK") +{ + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):BUSY NPP") + field(CALC, "A") + field(OOPT, "When Non-zero") + field(DOPT, "Use OCAL") + field(OCAL, "A-1") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):DELAY-RETRY-ERROR") +} + +# Delay check for retry error, not this happens after each retry. +# But we gate the retry error wih checking if busy is 0 +record(seq, "$(INSTR)$(SPS_REGISTER_NAME):DELAY-RETRY-ERROR") +{ + field(DESC, "Delays checking if retry error occurred") + field(DOL0, 1) + field(LNK0, "$(INSTR)$(SPS_REGISTER_NAME):RETRY-ERROR.PROC PP") + field(DLY0, 1) + field(SELM, "All") +} + +record(calc, "$(INSTR)$(SPS_REGISTER_NAME):RETRY-ERROR") +{ + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV") + field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") + field(INPD, "$(INSTR)$(SPS_REGISTER_NAME):SPS-CHANGING NPP") + field(CALC, "A#B&&C=0&&D=0?1:0") + #field(OOPT, "When Non-zero") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") +} + +record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") +{ + field(DESC, "Maps Status Variables to singular status") + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):SERVICE-MODE NPP") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):SPS-CHANGING NPP") + field(INPD, "$(INSTR)$(SPS_REGISTER_NAME):ERROR NPP") + field(INPE, "$(INSTR)$(SPS_REGISTER_NAME):EXECUTE-POSSIBLE NPP") + field(INPF, "$(INSTR)$(SPS_REGISTER_NAME):ConnStatusFetch NPP") + field(INPG, "$(INSTR)$(SPS_REGISTER_NAME):ConnStatusWrite NPP") + field(INPH, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") + field(INPI, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV NPP") + field(INPK, "$(INSTR)$(SPS_REGISTER_NAME):RETRY-ERROR NPP") + # For the case of 0... as the SPS always has everything as 0 + # during movement, meaning that we end up flicking between + # busy and not busy when switching to 0 + field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):LOADED NPP") + field(CALC, "(F=0||G=0||D=1||K=1)?3:(A=1)?2:(B=1||H#I||H#C)?1:0") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):UNBLOCK-MOTORS") +} + +# Make sure, that motors are re-enabled before the status +# of the changer returns to "Okay". +record(seq, "$(INSTR)$(SPS_REGISTER_NAME):UNBLOCK-MOTORS") +{ + field(DESC, "Trigger Internal Busy Status") + field(SELM, "All") + field(DOL1, "$(INSTR)$(SPS_REGISTER_NAME):BSX-DISV PP") + field(LNK1, "$(BS_MCU):bsx.DISV PP") + field(DOL2, "$(INSTR)$(SPS_REGISTER_NAME):BSY-DISV PP") + field(LNK2, "$(BS_MCU):bsy.DISV PP") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):STATUS PP") +} + +record(mbbi, "$(INSTR)$(SPS_REGISTER_NAME):STATUS") +{ + field(DESC, "Status of Beamstop Changer") + field(INP, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS NPP") + field(ZRVL, "0") + field(ZRST, "Okay") + field(ONVL, "1") + field(ONST, "Busy") + field(TWVL, "2") + field(TWST, "Warning") + field(THVL, "3") + field(THST, "Error") + field(FRST, "4") + field(FRST, "Unknown") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):STATUS-Msg") +} + +record(stringout, "$(INSTR)$(SPS_REGISTER_NAME):Retry-Error-Msg") +{ + field(DESC, "Beamstop max retries failed message") + field(VAL, "Failed trying to change beamstop") +} + +record(scalcout, "$(INSTR)$(SPS_REGISTER_NAME):STATUS-Msg") +{ + field(DESC, "Status Message") + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):RETRY-ERROR NPP") + field(INAA, "$(INSTR)$(SPS_REGISTER_NAME):Retry-Error-Msg NPP") + field(INBB, "$(INSTR)$(SPS_REGISTER_NAME):BLOCKED-REASON-Msg NPP") + field(CALC, 'A=1?AA:BB') + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SET-READY") +} + +record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):SET-READY") +{ + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):MCU-CHANGING NPP") + field(CALC, "A?B:0") + field(OOPT, "Transition To Non-zero") + field(DOPT, "Use OCAL") + field(OCAL, "0") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") +} + +################################################################################ +# Beamstop Motors and Collision Detection +################################################################################ + +record(longin, "$(BS_MCU):BS:X_0") { + field(DESC, "X-Position of Beamstop 0") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q453) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:X_1") { + field(DESC, "X-Position of Beamstop 1") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q454) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:X_2") { + field(DESC, "X-Position of Beamstop 2") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q455) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:X_3") { + field(DESC, "X-Position of Beamstop 3") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q456) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:Y_GET") { + field(DESC, "Y Position for picking up Beamstop") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q553) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:Y_PUT") { + field(DESC, "Y Position under beamstops") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q554) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(calcout, "$(BS_MCU):BS:ST") { + field(DESC, "Monitors beamstop changing") + field(DTYP, "stream") + field(OUT , "@$(PROTO) st() $(BS_MCU_ASYN_PORT) 0") + field(CALC, "0") + field(SCAN, ".1 second") + field(FLNK, "$(BS_MCU):BS:ST_FANOUT1") +} + +record(fanout, "$(BS_MCU):BS:ST_FANOUT1") { + field(LNK1, "$(BS_MCU):BS:TARGET") + field(LNK2, "$(BS_MCU):BS:TARGET_X") + field(LNK3, "$(BS_MCU):BS:TARGET_Y") + field(LNK5, "$(BS_MCU):BS:TARGET_BS_RAW") + field(LNK6, "$(BS_MCU):BS:TARGET_BS") + field(FLNK, "$(BS_MCU):BS:ST_FANOUT2") +} + +record(fanout, "$(BS_MCU):BS:ST_FANOUT2") { + field(LNK1, "$(BS_MCU):BS:BSX_ACK_RBV") + field(LNK2, "$(BS_MCU):BS:BSY_ACK_RBV") + field(LNK3, "$(BS_MCU):BS:TARGET_RANGE_RAW") + field(LNK4, "$(BS_MCU):BS:TARGET_RANGE") + field(LNK5, "$(BS_MCU):BS:LOADED_RAW") + field(LNK6, "$(BS_MCU):BS:INVALID") +} + +record(longin, "$(BS_MCU):BS:TARGET") { + field(DESC, "Beamstop position being driven to") + field(INP, "$(BS_MCU):BS:ST.A NPP MS") +} + +record(ai, "$(BS_MCU):BS:TARGET_X") { + field(DESC, "X Position being driven to") + field(INP, "$(BS_MCU):BS:ST.B NPP MS") +} + +record(ai, "$(BS_MCU):BS:TARGET_Y") { + field(DESC, "Y Position being driven to") + field(INP, "$(BS_MCU):BS:ST.C NPP MS") +} + +record(longin, "$(BS_MCU):BS:BSX_ACK_RBV") { + field(DESC, "BSX ACK") + field(INP, "$(BS_MCU):BS:ST.D NPP MS") +} + +record(longin, "$(BS_MCU):BS:BSY_ACK_RBV") { + field(DESC, "BSY ACK") + field(INP, "$(BS_MCU):BS:ST.E NPP MS") +} + +record(calc, "$(BS_MCU):BS:TARGET_BS_RAW") { + field(DESC, "Beamstop == TARGET_X") + # Dynamic Inputs + field(INPA, "$(BS_MCU):BS:TARGET_X NPP MS") + # Static Inputs + field(INPI, "$(BS_MCU):BS:X_0 NPP MS") + field(INPJ, "$(BS_MCU):BS:X_1 NPP MS") + field(INPK, "$(BS_MCU):BS:X_2 NPP MS") + field(INPL, "$(BS_MCU):BS:X_3 NPP MS") + # Maybe having a tolerance isn't really necessary? + # they get set exactly to the value in the MCU + field(CALC, "ABS(A-I)<1?0:ABS(A-J)<1?1:ABS(A-K)<1?2:ABS(A-L)<1?3:4") + # field(CALC, "A=I?0:A=J?1:A=K?2:A=L?3:4") +} + +record(mbbi, "$(BS_MCU):BS:TARGET_BS") { + field(DESC, "Target Beamstop Holder") + field(DTYP, "Soft Channel") + field(INP, "$(BS_MCU):BS:TARGET_BS_RAW NPP MS") + field(ZRST, "No Beamstop") + field(ONST, "Beamstop 1") + field(TWST, "Beamstop 2") + field(THST, "Beamstop 3") + field(FRST, "User Mode") +} + +record(calc, "$(BS_MCU):BS:TARGET_RANGE_RAW") { + field(DESC, "Beamstop target y-range") + # Dynamic Inputs + field(INPA, "$(BS_MCU):BS:TARGET_Y NPP MS") + # Static Inputs + field(INPK, "$(BS_MCU):BS:Y_GET NPP MS") + field(INPL, "$(BS_MCU):BS:Y_PUT NPP MS") + # Maybe having a tolerance isn't really necessary? + # they get set exactly to the value in the MCU + field(CALC, "ABS(A-K)<1?1:ABS(A-L)<1?2:0") +} + +record(mbbi, "$(BS_MCU):BS:TARGET_RANGE") { + field(DESC, "Beamstop target y-range") + field(DTYP, "Soft Channel") + field(INP, "$(BS_MCU):BS:TARGET_RANGE_RAW NPP MS") + field(ZRST, "User Mode") + field(ONST, "Level with Beamstops") + field(TWST, "Under Beamstops") +} + +record(calcout, "$(BS_MCU):BS:LOADED_RAW") +{ + field(INPA, "$(BS_MCU):BS:TARGET_BS NPP MS") + field(INPB, "$(BS_MCU):BS:TARGET_RANGE NPP MS") + field(CALC, "B=2") + field(OOPT, "Transition To Zero") + field(DOPT, "Use OCAL") + field(OCAL, "A") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):LOADED PP") +} + +record(longout, "$(INSTR)$(SPS_REGISTER_NAME):LOADED-INIT") +{ + field(DESC, "Initialises LOADED PV") + field(DOL, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV NPP") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):LOADED NPP") + field(OMSL, "closed_loop") + field(PINI, "YES") +} + +record(mbbi, "$(INSTR)$(SPS_REGISTER_NAME):LOADED") +{ + field(DESC, "Most recently lifted beamstop") + field(ZRST, "No Beamstop") + field(ONST, "Beamstop 1") + field(TWST, "Beamstop 2") + field(THST, "Beamstop 3") +} + +record(calcout, "$(BS_MCU):BS:INVALID") { + field(DESC, "Invalid Move STOP MOTORS!") + # Dynamic Inputs + field(INPA, "$(BS_MCU):BS:TARGET_BS NPP MS") + field(INPB, "$(BS_MCU):BS:TARGET_RANGE NPP MS") + field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):LOADED NPP MS") + field(CALC, "(A<4) && (B=1) && (A#C)") + field(OOPT, "Transition To Non-zero") + field(OUT, "$(BS_MCU):BS:IMMEDIATE_STOP.PROC PP") +} + +record(longout, "$(BS_MCU):BS:IMMEDIATE_STOP") { + field(DESC, "Invalid Move STOP MOTORS!") + # For Test + # field(OUT, "TEST_RECORD PP") + # field(OMSL, "closed_loop") + # field(DOL, "1") + # TODO not currently activated + # FOR REAL + # field(DTYP, "stream") + # field(OUT , "@$(PROTO) stop() $(BS_MCU_ASYN_PORT) 0") +} + +# record(longin, "TEST_RECORD") { +# field(VAL, 0) +# } diff --git a/templates/sans_llb_beamstop.substitutions b/beamstop/sans_llb_beamstop.substitutions similarity index 90% rename from templates/sans_llb_beamstop.substitutions rename to beamstop/sans_llb_beamstop.substitutions index 4a6c16c..539b130 100644 --- a/templates/sans_llb_beamstop.substitutions +++ b/beamstop/sans_llb_beamstop.substitutions @@ -34,6 +34,6 @@ file "$(sinqSPS_DB)/readbit.db" file "$(sinqSPS_DB)/readstring.db" { pattern - {OFFSET, LENGTH, STRING_NAME } - {8 , 30 , "BLOCKED-REASON" } + {OFFSET, LENGTH, STRING_NAME , FLNK } + {8 , 30 , "BLOCKED-REASON", "$(STATUS_FLNK)"} } diff --git a/db/readusint.db b/db/readusint.db index d088264..3b1b374 100644 --- a/db/readusint.db +++ b/db/readusint.db @@ -5,4 +5,5 @@ record(longin, "$(INSTR)$(SPS_REGISTER_NAME):$(UINT_NAME)") field(INP, "@$(SPS_REGISTER_NAME)/$(OFFSET) T=BYTE") field(PINI, "YES") field(SCAN, "I/O Intr") + field(FLNK, "$(FLNK=)") } diff --git a/db/sans_llb_beamstop.db b/db/sans_llb_beamstop.db deleted file mode 100644 index 39011e3..0000000 --- a/db/sans_llb_beamstop.db +++ /dev/null @@ -1,72 +0,0 @@ -record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-INIT") -{ - field(DESC, "Initialises BEAMSTOP PV") - field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") - field(DOL, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV NPP") - field(OMSL, "closed_loop") - field(PINI, "YES") -} - -record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP") -{ - field(DESC, "Move to new Beamstop") - field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-RAW PP") - field(OMSL, "supervisory") - field(DRVL, 1) - field(DRVH, 3) - field(PINI, "NO") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER-DELAY PP") -} - -record(seq, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER-DELAY") -{ - field(DESC, "Delays Internal Trigger as SPS too slow") - field(DOL0, 1) - field(LNK0, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER PP") - field(DLY0, 0.5) - field(SELM, "All") - field(PINI, "NO") -} - -record(longout, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER") -{ - field(DESC, "Internal Trigger") - field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):EXECUTE-CHANGE PP") - field(OMSL, "closed_loop") - field(DOL, 1) - field(PINI, "NO") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS PP") -} - -record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") -{ - field(DESC, "Maps Status Variables to singular status") - field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):SERVICE-MODE NPP") - field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):IN-POSITION NPP") - field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):MOVES NPP") - field(INPD, "$(INSTR)$(SPS_REGISTER_NAME):ERROR NPP") - field(INPE, "$(INSTR)$(SPS_REGISTER_NAME):EXECUTE-POSSIBLE NPP") - field(INPF, "$(INSTR)$(SPS_REGISTER_NAME):ConnStatusFetch NPP") - field(INPG, "$(INSTR)$(SPS_REGISTER_NAME):ConnStatusWrite NPP") - field(INPH, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") - field(INPI, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV NPP") - field(CALC, "(F=0||G=0||D=1)?3:(A=1)?2:(C=1||H#I)?1:(B=0)?3:0") - field(SCAN, ".1 second") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):STATUS PP") -} - -record(mbbi, "$(INSTR)$(SPS_REGISTER_NAME):STATUS") -{ - field(DESC, "Status of Shutter") - field(INP, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS NPP") - field(ZRVL, "0") - field(ZRST, "Okay") - field(ONVL, "1") - field(ONST, "Busy") - field(TWVL, "2") - field(TWST, "Warning") - field(THVL, "3") - field(THST, "Error") - field(FRST, "4") - field(FRST, "Unknown") -} diff --git a/scripts/shutter.cmd b/shutter/shutter.cmd similarity index 100% rename from scripts/shutter.cmd rename to shutter/shutter.cmd diff --git a/db/shutter.db b/shutter/shutter.db similarity index 99% rename from db/shutter.db rename to shutter/shutter.db index 556e534..0baf51c 100644 --- a/db/shutter.db +++ b/shutter/shutter.db @@ -203,4 +203,3 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):SET-READY") field(OCAL, "0") field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") } - diff --git a/templates/shutter.substitutions b/shutter/shutter.substitutions similarity index 100% rename from templates/shutter.substitutions rename to shutter/shutter.substitutions diff --git a/test/beamstop.log b/test/beamstop.log new file mode 100644 index 0000000..59ae3e3 --- /dev/null +++ b/test/beamstop.log @@ -0,0 +1,70 @@ +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 11:09:32.656133 -20.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 11:09:32.659449 -19.9995 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:54:23.954702 0 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:54:23.958820 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:54:31.059702 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:54:36.454703 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:54:36.459712 3 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:54:52.464797 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:54:58.055078 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:54:58.058422 -19.9995 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:55:25.855989 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:55:25.960081 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:55:41.461015 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:55:46.955108 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:55:46.962014 2 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:55:53.960696 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:55:59.456495 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:55:59.460360 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:56:24.678117 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:56:24.681708 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:56:35.059603 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:56:40.455381 -96 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:56:40.462485 1 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:56:47.458093 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:56:52.858578 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:56:52.958942 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:57:14.855467 -96 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:57:14.959653 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:57:21.956792 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:57:27.456472 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:57:27.463668 3 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:57:39.559147 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:57:45.155695 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:57:45.160185 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:58:16.755069 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:58:16.757927 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:58:32.359963 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:58:37.756299 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:58:37.763502 2 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:58:44.758396 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:58:50.255358 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:58:50.259949 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:59:56.755610 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:59:56.858744 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:00:07.159971 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:00:12.555471 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 15:00:12.561718 3 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:00:19.560666 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:00:25.059011 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:00:25.155561 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:01:27.755497 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:01:27.858174 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:01:43.359424 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:01:48.757375 -96 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 15:01:48.763274 1 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:02:03.153618 0 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:02:17.959320 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:02:22.055431 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:02:22.059497 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:02:56.855467 0 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 15:02:56.862398 0 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:02:56.958718 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:03:03.964312 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:03:09.455238 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 15:03:09.462565 3 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:03:25.459099 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:04:08.355614 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:04:08.359484 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:01:27.755497 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:01:27.858174 -150 diff --git a/test/beamstop.sh b/test/beamstop.sh new file mode 100755 index 0000000..3667ae2 --- /dev/null +++ b/test/beamstop.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +# Last two lines of the log file were added to produce an error state + +while IFS=' ' read -r pv val; do + echo "caput ${pv} ${val}" + caput ${pv} ${val} > /dev/null 2>&1 + sleep 4 +done < <(cut -d' ' -f 1,4 "${SCRIPT_DIR}/beamstop.log")