From 8c38bbe85a359cc73902ecab2c7744df21e20d02 Mon Sep 17 00:00:00 2001 From: soederqvist_a Date: Wed, 8 Apr 2026 16:04:43 +0200 Subject: [PATCH 01/15] Improvements to shutter Based on work with NEUTRA N-Shutter or experiment shutter. --- scripts/shutter.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/shutter.cmd b/scripts/shutter.cmd index ecb135a..b09fa2e 100644 --- a/scripts/shutter.cmd +++ b/scripts/shutter.cmd @@ -23,7 +23,7 @@ $(SET_SIM_MODE=#) $(SET_SIM_MODE) system "$(sinqSPS_DIR)shutter_sim.py $(FETCH_P $(SET_SIM_MODE=#) $(SET_SIM_MODE) sleep 3 -s7plcFWConfigure("$(SPS_REGISTER_NAME)", "$(SPS_IP)", "$(FETCH_PORT=2000),1,$(FETCH_DB),0,$(SPS_FETCH_SIZE)", "$(WRITE_PORT=2001),1,$(WRITE_DB=$(FETCH_DB)),0,$(SPS_WRITE_SIZE)", "$(SPS_ENDIANNESS=1)", "$(SPS_RECEIVE_TIMEOUT=1000)", "$(SPS_RECEIVE_DELAY=200)", "0") +s7plcFWConfigure("$(SPS_REGISTER_NAME)", "$(SPS_IP)", "$(FETCH_PORT=2000),1,$(FETCH_DB),0,$(SPS_FETCH_SIZE)", "$(WRITE_PORT=2001),1,$(WRITE_DB=$(FETCH_DB)),0,$(SPS_WRITE_SIZE)", "$(SPS_ENDIANNESS=1)", "$(SPS_RECEIVE_TIMEOUT=1000)", "$(SPS_RECEIVE_DELAY=600)", "0", 1) # Provides Connection Status PVs dbLoadRecords("$(sinqSPS_DB)/sps_status.db", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME)") From 28cd0879be617cc57eb2f599e91deaf58a89862a Mon Sep 17 00:00:00 2001 From: soederqvist_a Date: Thu, 9 Apr 2026 10:13:14 +0200 Subject: [PATCH 02/15] Add error for retries, don't retry unless status is ok --- scripts/shutter.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/shutter.cmd b/scripts/shutter.cmd index b09fa2e..ecb135a 100644 --- a/scripts/shutter.cmd +++ b/scripts/shutter.cmd @@ -23,7 +23,7 @@ $(SET_SIM_MODE=#) $(SET_SIM_MODE) system "$(sinqSPS_DIR)shutter_sim.py $(FETCH_P $(SET_SIM_MODE=#) $(SET_SIM_MODE) sleep 3 -s7plcFWConfigure("$(SPS_REGISTER_NAME)", "$(SPS_IP)", "$(FETCH_PORT=2000),1,$(FETCH_DB),0,$(SPS_FETCH_SIZE)", "$(WRITE_PORT=2001),1,$(WRITE_DB=$(FETCH_DB)),0,$(SPS_WRITE_SIZE)", "$(SPS_ENDIANNESS=1)", "$(SPS_RECEIVE_TIMEOUT=1000)", "$(SPS_RECEIVE_DELAY=600)", "0", 1) +s7plcFWConfigure("$(SPS_REGISTER_NAME)", "$(SPS_IP)", "$(FETCH_PORT=2000),1,$(FETCH_DB),0,$(SPS_FETCH_SIZE)", "$(WRITE_PORT=2001),1,$(WRITE_DB=$(FETCH_DB)),0,$(SPS_WRITE_SIZE)", "$(SPS_ENDIANNESS=1)", "$(SPS_RECEIVE_TIMEOUT=1000)", "$(SPS_RECEIVE_DELAY=200)", "0") # Provides Connection Status PVs dbLoadRecords("$(sinqSPS_DB)/sps_status.db", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME)") From 0d20534dcf9a65bedfe50207f81c3adc6d4fa144 Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Thu, 9 Apr 2026 16:08:14 +0200 Subject: [PATCH 03/15] adds a similar retry mechanism as was implemented with the shutter --- db/readusint.db | 1 + db/sans_llb_beamstop.db | 114 +++++++++++++++++++++- db/shutter.db | 1 - scripts/sans_llb_beamstop.cmd | 2 +- templates/sans_llb_beamstop.substitutions | 16 +-- 5 files changed, 121 insertions(+), 13 deletions(-) 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 index 39011e3..29f09c0 100644 --- a/db/sans_llb_beamstop.db +++ b/db/sans_llb_beamstop.db @@ -1,8 +1,8 @@ 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(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") field(OMSL, "closed_loop") field(PINI, "YES") } @@ -22,12 +22,42 @@ 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(LNK0, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY.PROC PP") field(DLY0, 0.5) field(SELM, "All") field(PINI, "NO") } +record(longout, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY") +{ + field(DESC, "Trigger Internal Busy Status") + # This determines the number of max retry ticks + field(VAL, 5) + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER") +} + +# 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") +} + record(longout, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER") { field(DESC, "Internal Trigger") @@ -38,6 +68,57 @@ record(longout, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER") 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") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV") + field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") + field(INPD, "$(INSTR)$(SPS_REGISTER_NAME):MOVES") + field(INPE, "$(INSTR)$(SPS_REGISTER_NAME):STATUS") + field(CALC, "A#B&&C#0&&D=0&&E=0?1:0") + field(DOPT, "Use CALC") + field(OOPT, "When Non-zero") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER.PROC PP") + field(SCAN, "1 second") + 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") + 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, 0.5) + field(SELM, "All") +} + +record(calcout, "$(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):MOVES") + field(CALC, "A#B&&C=0&&D=0?1:0") + field(OOPT, "When Non-zero") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS PP") +} + record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") { field(DESC, "Maps Status Variables to singular status") @@ -51,7 +132,6 @@ record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") 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") } @@ -69,4 +149,32 @@ record(mbbi, "$(INSTR)$(SPS_REGISTER_NAME):STATUS") 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):MOVES") + field(CALC, "A") + field(OOPT, "Transition To Zero") + field(DOPT, "Use OCAL") + field(OCAL, "0") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") +} + diff --git a/db/shutter.db b/db/shutter.db index 556e534..0baf51c 100644 --- a/db/shutter.db +++ b/db/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/scripts/sans_llb_beamstop.cmd b/scripts/sans_llb_beamstop.cmd index 42159de..0fb9b03 100644 --- a/scripts/sans_llb_beamstop.cmd +++ b/scripts/sans_llb_beamstop.cmd @@ -19,7 +19,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)") diff --git a/templates/sans_llb_beamstop.substitutions b/templates/sans_llb_beamstop.substitutions index 4a6c16c..ddb5cb3 100644 --- a/templates/sans_llb_beamstop.substitutions +++ b/templates/sans_llb_beamstop.substitutions @@ -23,17 +23,17 @@ file "$(sinqSPS_DB)/readusint.db" file "$(sinqSPS_DB)/readbit.db" { pattern - {OFFSET, BIT, BIT_NAME , ZNAM , ONAM , DESC} - {6 , 0 , "SERVICE-MODE" , "disabled", "enabled", "" } - {6 , 1 , "IN-POSITION" , "no" , "yes" , "" } - {6 , 2 , "MOVES" , "no" , "yes" , "" } - {6 , 3 , "ERROR" , "no" , "yes" , "" } - {6 , 4 , "EXECUTE-POSSIBLE" , "no" , "yes" , "" } + {OFFSET, BIT, BIT_NAME , ZNAM , ONAM , DESC, FLNK } + {6 , 0 , "SERVICE-MODE" , "disabled", "enabled", "" , "" } + {6 , 1 , "IN-POSITION" , "no" , "yes" , "" , "" } + {6 , 2 , "MOVES" , "no" , "yes" , "" , "" } + {6 , 3 , "ERROR" , "no" , "yes" , "" , "" } + {6 , 4 , "EXECUTE-POSSIBLE" , "no" , "yes" , "" , "$(STATUS_FLNK)"} } 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)"} } From 611b9f54162f9620b6781eedd8dfa2dfdb925ff1 Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Fri, 10 Apr 2026 08:22:47 +0200 Subject: [PATCH 04/15] disables the bsx and bsy motors when the beamstop isn't in an okay state --- db/sans_llb_beamstop.db | 26 ++++++++++++++++++++++---- scripts/sans_llb_beamstop.cmd | 4 +++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/db/sans_llb_beamstop.db b/db/sans_llb_beamstop.db index 29f09c0..a2eda5a 100644 --- a/db/sans_llb_beamstop.db +++ b/db/sans_llb_beamstop.db @@ -22,7 +22,7 @@ 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):SET-BUSY.PROC PP") + field(LNK0, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY.PROC PP") field(DLY0, 0.5) field(SELM, "All") field(PINI, "NO") @@ -32,8 +32,8 @@ record(longout, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY") { field(DESC, "Trigger Internal Busy Status") # This determines the number of max retry ticks - field(VAL, 5) - field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") + field(VAL, 5) + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER") } @@ -103,7 +103,7 @@ 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(LNK0, "$(INSTR)$(SPS_REGISTER_NAME):RETRY-ERROR.PROC PP") field(DLY0, 0.5) field(SELM, "All") } @@ -176,5 +176,23 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):SET-READY") field(DOPT, "Use OCAL") field(OCAL, "0") field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-MOTORS") } +record(calc, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-MOTORS") +{ + field(DESC, "Whether to block bsx and bsy") + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") + field(CALC, "A=0?0:1") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-MOTOR-BLOCK PP") +} + +record(seq, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-MOTOR-BLOCK") +{ + field(DESC, "Block moving bsx and bsy") + field(DOL0, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-MOTORS NPP") + field(LNK0, "$(BSX_MOT).DISV PP") + field(DOL1, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-MOTORS NPP") + field(LNK1, "$(BSY_MOT).DISV PP") + field(SELM, "All") +} diff --git a/scripts/sans_llb_beamstop.cmd b/scripts/sans_llb_beamstop.cmd index 0fb9b03..d3728de 100644 --- a/scripts/sans_llb_beamstop.cmd +++ b/scripts/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") @@ -22,4 +24,4 @@ dbLoadRecords("$(sinqSPS_DB)/sps_status.db", "INSTR=$(INSTR), 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), BSX_MOT=$(BSX_MOT), BSY_MOT=$(BSY_MOT)") From 2ac93f2556a0411eb8cd3c6833ab625748fcc04c Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Fri, 10 Apr 2026 10:13:22 +0200 Subject: [PATCH 05/15] set DISV to ~DISA --- db/sans_llb_beamstop.db | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/db/sans_llb_beamstop.db b/db/sans_llb_beamstop.db index a2eda5a..ffa39cd 100644 --- a/db/sans_llb_beamstop.db +++ b/db/sans_llb_beamstop.db @@ -179,20 +179,30 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):SET-READY") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-MOTORS") } -record(calc, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-MOTORS") +record(calc, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSX") { field(DESC, "Whether to block bsx and bsy") field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") - field(CALC, "A=0?0:1") + field(INPB, "$(BSX_MOT).DISA NPP") + field(CALC, "A=0?!B:B") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSY PP") +} + +record(calc, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSY") +{ + field(DESC, "Whether to block bsx and bsy") + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") + field(INPB, "$(BSY_MOT).DISA NPP") + field(CALC, "A=0?!B:B") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-MOTOR-BLOCK PP") } record(seq, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-MOTOR-BLOCK") { field(DESC, "Block moving bsx and bsy") - field(DOL0, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-MOTORS NPP") + field(DOL0, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSX NPP") field(LNK0, "$(BSX_MOT).DISV PP") - field(DOL1, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-MOTORS NPP") + field(DOL1, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSY NPP") field(LNK1, "$(BSY_MOT).DISV PP") field(SELM, "All") } From 9b759ec4e2732fdb255794e273c520c24c40411b Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Fri, 10 Apr 2026 13:59:54 +0200 Subject: [PATCH 06/15] correct set-ready logic --- db/sans_llb_beamstop.db | 12 +++++++----- templates/sans_llb_beamstop.substitutions | 12 ++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/db/sans_llb_beamstop.db b/db/sans_llb_beamstop.db index ffa39cd..1cf4bbb 100644 --- a/db/sans_llb_beamstop.db +++ b/db/sans_llb_beamstop.db @@ -88,7 +88,7 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):RETRY") record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):DECREASE-BUSY-TICK") { - field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):BUSY NPP") field(CALC, "A") field(OOPT, "When Non-zero") field(DOPT, "Use OCAL") @@ -131,7 +131,8 @@ record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") 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(INPK, "$(INSTR)$(SPS_REGISTER_NAME):RETRY-ERROR NPP") + field(CALC, "(F=0||G=0||D=1||K=1)?3:(A=1)?2:(C=1||H#I)?1:(B=0)?3:0") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):STATUS PP") } @@ -171,12 +172,13 @@ record(scalcout, "$(INSTR)$(SPS_REGISTER_NAME):STATUS-Msg") record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):SET-READY") { field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):MOVES") - field(CALC, "A") - field(OOPT, "Transition To Zero") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") + field(CALC, "B?A:0") + field(OOPT, "Transition To Non-zero") field(DOPT, "Use OCAL") field(OCAL, "0") field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-MOTORS") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSX") } record(calc, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSX") diff --git a/templates/sans_llb_beamstop.substitutions b/templates/sans_llb_beamstop.substitutions index ddb5cb3..539b130 100644 --- a/templates/sans_llb_beamstop.substitutions +++ b/templates/sans_llb_beamstop.substitutions @@ -23,12 +23,12 @@ file "$(sinqSPS_DB)/readusint.db" file "$(sinqSPS_DB)/readbit.db" { pattern - {OFFSET, BIT, BIT_NAME , ZNAM , ONAM , DESC, FLNK } - {6 , 0 , "SERVICE-MODE" , "disabled", "enabled", "" , "" } - {6 , 1 , "IN-POSITION" , "no" , "yes" , "" , "" } - {6 , 2 , "MOVES" , "no" , "yes" , "" , "" } - {6 , 3 , "ERROR" , "no" , "yes" , "" , "" } - {6 , 4 , "EXECUTE-POSSIBLE" , "no" , "yes" , "" , "$(STATUS_FLNK)"} + {OFFSET, BIT, BIT_NAME , ZNAM , ONAM , DESC} + {6 , 0 , "SERVICE-MODE" , "disabled", "enabled", "" } + {6 , 1 , "IN-POSITION" , "no" , "yes" , "" } + {6 , 2 , "MOVES" , "no" , "yes" , "" } + {6 , 3 , "ERROR" , "no" , "yes" , "" } + {6 , 4 , "EXECUTE-POSSIBLE" , "no" , "yes" , "" } } file "$(sinqSPS_DB)/readstring.db" From 28ebf11e4191e40c270d2c8a69857096c2e15018 Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Fri, 10 Apr 2026 14:46:51 +0200 Subject: [PATCH 07/15] simplifies motor disabling --- db/sans_llb_beamstop.db | 89 +++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/db/sans_llb_beamstop.db b/db/sans_llb_beamstop.db index 1cf4bbb..f2651b7 100644 --- a/db/sans_llb_beamstop.db +++ b/db/sans_llb_beamstop.db @@ -9,32 +9,11 @@ record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-INIT") 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(DESC, "Select new Beamstop") 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):SET-BUSY.PROC PP") - field(DLY0, 0.5) - field(SELM, "All") - field(PINI, "NO") -} - -record(longout, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY") -{ - field(DESC, "Trigger Internal Busy Status") - # This determines the number of max retry ticks - field(VAL, 5) - field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY.PROC PP") } # Reset status @@ -58,6 +37,37 @@ record(bi, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") field(ONAM, "Busy") } +record(longout, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY") +{ + field(DESC, "Trigger Internal Busy Status") + # This determines the number of max retry ticks + field(VAL, 5) + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-OUT") +} + +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, 1) + 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") @@ -81,8 +91,8 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):RETRY") field(CALC, "A#B&&C#0&&D=0&&E=0?1:0") field(DOPT, "Use CALC") field(OOPT, "When Non-zero") - field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER.PROC PP") - field(SCAN, "1 second") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-OUT.PROC PP") + field(SCAN, "2 second") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):DECREASE-BUSY-TICK") } @@ -104,7 +114,7 @@ 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, 0.5) + field(DLY0, 1) field(SELM, "All") } @@ -178,33 +188,26 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):SET-READY") field(DOPT, "Use OCAL") field(OCAL, "0") field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSX") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") } -record(calc, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSX") +record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") { - field(DESC, "Whether to block bsx and bsy") + field(DESC, "Disable BSX during change") field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") field(INPB, "$(BSX_MOT).DISA NPP") field(CALC, "A=0?!B:B") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSY PP") + field(DOPT, "Use CALC") + field(OUT, "$(BSX_MOT).DISV PP") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") } -record(calc, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSY") +record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") { - field(DESC, "Whether to block bsx and bsy") + field(DESC, "Disable BSY during change") field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") field(INPB, "$(BSY_MOT).DISA NPP") field(CALC, "A=0?!B:B") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-MOTOR-BLOCK PP") -} - -record(seq, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-MOTOR-BLOCK") -{ - field(DESC, "Block moving bsx and bsy") - field(DOL0, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSX NPP") - field(LNK0, "$(BSX_MOT).DISV PP") - field(DOL1, "$(INSTR)$(SPS_REGISTER_NAME):SHOULD-BLOCK-BSY NPP") - field(LNK1, "$(BSY_MOT).DISV PP") - field(SELM, "All") + field(DOPT, "Use CALC") + field(OUT, "$(BSY_MOT).DISV PP") } From f33f5f68f65e5da41c6718b6d4c71e2315fa5f69 Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Thu, 23 Apr 2026 17:33:23 +0200 Subject: [PATCH 08/15] draft of extra sanity checking when placing a beamstop --- Makefile | 16 +- beamstop/beamstop_motors.proto | 23 ++ {scripts => beamstop}/sans_llb_beamstop.cmd | 2 +- {db => beamstop}/sans_llb_beamstop.db | 202 +++++++++++++++++- .../sans_llb_beamstop.substitutions | 0 {scripts => shutter}/shutter.cmd | 0 {db => shutter}/shutter.db | 0 {templates => shutter}/shutter.substitutions | 0 test/beamstop.log | 70 ++++++ test/beamstop.sh | 13 ++ 10 files changed, 314 insertions(+), 12 deletions(-) create mode 100644 beamstop/beamstop_motors.proto rename {scripts => beamstop}/sans_llb_beamstop.cmd (89%) rename {db => beamstop}/sans_llb_beamstop.db (53%) rename {templates => beamstop}/sans_llb_beamstop.substitutions (100%) rename {scripts => shutter}/shutter.cmd (100%) rename {db => shutter}/shutter.db (100%) rename {templates => shutter}/shutter.substitutions (100%) create mode 100644 test/beamstop.log create mode 100755 test/beamstop.sh 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..18e7deb --- /dev/null +++ b/beamstop/beamstop_motors.proto @@ -0,0 +1,23 @@ +ReplyTimeout = 1000; +ReadTimeout = 100; + +pmac_get { + InTerminator = CR ACK; + out "\$1"; + in "%d"; +} + +st { + InTerminator = CR ACK; + out "P553 Q401 Q501"; + in "%(A)d%*[ ]%(B)f%*[ ]%(C)f"; + # Multi Record Version + # out "P553Q401 Q501"; + # in "%d%*[ ]%(\$1:BS:TARGET_X)f%*[ ]%(\$1:BS:TARGET_Y)f"; +} + +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 89% rename from scripts/sans_llb_beamstop.cmd rename to beamstop/sans_llb_beamstop.cmd index d3728de..5a1c1fc 100644 --- a/scripts/sans_llb_beamstop.cmd +++ b/beamstop/sans_llb_beamstop.cmd @@ -24,4 +24,4 @@ dbLoadRecords("$(sinqSPS_DB)/sps_status.db", "INSTR=$(INSTR), 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), BSX_MOT=$(BSX_MOT), BSY_MOT=$(BSY_MOT)") +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/db/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db similarity index 53% rename from db/sans_llb_beamstop.db rename to beamstop/sans_llb_beamstop.db index f2651b7..cf7bbc5 100644 --- a/db/sans_llb_beamstop.db +++ b/beamstop/sans_llb_beamstop.db @@ -1,3 +1,7 @@ +################################################################################ +# Beamstop Changer +################################################################################ + record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-INIT") { field(DESC, "Initialises BEAMSTOP PV") @@ -195,10 +199,10 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") { field(DESC, "Disable BSX during change") field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") - field(INPB, "$(BSX_MOT).DISA NPP") + field(INPB, "$(BS_MCU):bsx.DISA NPP") field(CALC, "A=0?!B:B") field(DOPT, "Use CALC") - field(OUT, "$(BSX_MOT).DISV PP") + field(OUT, "$(BS_MCU):bsx.DISV PP") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") } @@ -206,8 +210,198 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") { field(DESC, "Disable BSY during change") field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") - field(INPB, "$(BSY_MOT).DISA NPP") + field(INPB, "$(BS_MCU):bsy.DISA NPP") field(CALC, "A=0?!B:B") field(DOPT, "Use CALC") - field(OUT, "$(BSY_MOT).DISV PP") + field(OUT, "$(BS_MCU):bsy.DISV 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_FANOUT") +} + +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(LNK7, "$(BS_MCU):BS:ST_FANOUT2") + field(SCAN, ".1 second") +} + +record(fanout, "$(BS_MCU):BS:ST_FANOUT2") { + field(LNK1, "$(BS_MCU):BS:TARGET_RANGE_RAW") + field(LNK2, "$(BS_MCU):BS:TARGET_RANGE") + field(LNK3, "$(BS_MCU):BS:LOADED_RAW") + field(LNK4, "$(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(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, "$(BS_MCU):BS: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, "$(BS_MCU):BS:LOADED NPP") + field(OMSL, "closed_loop") + field(PINI, "YES") +} + +record(mbbi, "$(BS_MCU):BS: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, "$(BS_MCU):BS:LOADED NPP MS") + field(CALC, "A<4 & B=1 & A#C") + field(OOPT, "When Non-zero") + field(OUT, "$(BS_MCU):BS:IMMEDIATE_STOP.PROC PP") +} + +record(longout, "$(BS_MCU):BS:IMMEDIATE_STOP") { + field(DESC, "Invalid Move STOP MOTORS!") + field(PINI, "NO") + field(OMSL, "closed_loop") + field(DOL, "1") + # For Test + # field(OUT, "TEST_RECORD PP") + # 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 100% rename from templates/sans_llb_beamstop.substitutions rename to beamstop/sans_llb_beamstop.substitutions 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 100% rename from db/shutter.db rename to shutter/shutter.db 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") From d76f8ed3e56103e3be7ccb514aedfec5b60ed8cc Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Fri, 24 Apr 2026 10:09:39 +0200 Subject: [PATCH 09/15] bugfix --- beamstop/beamstop_motors.proto | 3 --- beamstop/sans_llb_beamstop.db | 9 ++++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/beamstop/beamstop_motors.proto b/beamstop/beamstop_motors.proto index 18e7deb..420e5d5 100644 --- a/beamstop/beamstop_motors.proto +++ b/beamstop/beamstop_motors.proto @@ -11,9 +11,6 @@ st { InTerminator = CR ACK; out "P553 Q401 Q501"; in "%(A)d%*[ ]%(B)f%*[ ]%(C)f"; - # Multi Record Version - # out "P553Q401 Q501"; - # in "%d%*[ ]%(\$1:BS:TARGET_X)f%*[ ]%(\$1:BS:TARGET_Y)f"; } stop { diff --git a/beamstop/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db index cf7bbc5..c5b0545 100644 --- a/beamstop/sans_llb_beamstop.db +++ b/beamstop/sans_llb_beamstop.db @@ -385,18 +385,17 @@ record(calcout, "$(BS_MCU):BS:INVALID") { field(INPA, "$(BS_MCU):BS:TARGET_BS NPP MS") field(INPB, "$(BS_MCU):BS:TARGET_RANGE NPP MS") field(INPC, "$(BS_MCU):BS:LOADED NPP MS") - field(CALC, "A<4 & B=1 & A#C") - field(OOPT, "When Non-zero") + 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!") - field(PINI, "NO") - field(OMSL, "closed_loop") - field(DOL, "1") # For Test # field(OUT, "TEST_RECORD PP") + # field(OMSL, "closed_loop") + # field(DOL, "1") # FOR REAL field(DTYP, "stream") field(OUT , "@$(PROTO) stop() $(BS_MCU_ASYN_PORT) 0") From 208cb75fc1bbcadcbdf2c2abe64566097a0d3f0c Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Fri, 24 Apr 2026 11:29:05 +0200 Subject: [PATCH 10/15] adds proc field --- beamstop/sans_llb_beamstop.db | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beamstop/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db index c5b0545..8852775 100644 --- a/beamstop/sans_llb_beamstop.db +++ b/beamstop/sans_llb_beamstop.db @@ -268,7 +268,7 @@ record(calcout, "$(BS_MCU):BS:ST") { field(OUT , "@$(PROTO) st() $(BS_MCU_ASYN_PORT) 0") field(CALC, "0") field(SCAN, ".1 second") - field(FLNK, "$(BS_MCU):BS:ST_FANOUT") + field(FLNK, "$(BS_MCU):BS:ST_FANOUT.PROC") } record(fanout, "$(BS_MCU):BS:ST_FANOUT1") { From bea7df79baa3c0c1ef2cc958a43d6df99726051e Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Wed, 13 May 2026 10:40:32 +0200 Subject: [PATCH 11/15] also allows selecting beamstop 0 --- beamstop/sans_llb_beamstop.db | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/beamstop/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db index 8852775..e4f83c5 100644 --- a/beamstop/sans_llb_beamstop.db +++ b/beamstop/sans_llb_beamstop.db @@ -14,7 +14,7 @@ record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-INIT") record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP") { field(DESC, "Select new Beamstop") - field(DRVL, 1) + field(DRVL, 0) field(DRVH, 3) field(PINI, "NO") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):SET-BUSY.PROC PP") @@ -396,9 +396,10 @@ record(longout, "$(BS_MCU):BS:IMMEDIATE_STOP") { # 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") + # field(DTYP, "stream") + # field(OUT , "@$(PROTO) stop() $(BS_MCU_ASYN_PORT) 0") } # record(longin, "TEST_RECORD") { From ef54f7d7be21d9f2064567553cdf928166a745b9 Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Mon, 18 May 2026 11:03:58 +0200 Subject: [PATCH 12/15] relying now on IN-POSITION as well. this is probably not optimal, it should really only be used for error checking --- beamstop/sans_llb_beamstop.db | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/beamstop/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db index e4f83c5..9b9b2d6 100644 --- a/beamstop/sans_llb_beamstop.db +++ b/beamstop/sans_llb_beamstop.db @@ -128,7 +128,8 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):RETRY-ERROR") field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV") field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") field(INPD, "$(INSTR)$(SPS_REGISTER_NAME):MOVES") - field(CALC, "A#B&&C=0&&D=0?1:0") + field(INPE, "$(INSTR)$(SPS_REGISTER_NAME):IN-POSITION NPP") + field(CALC, "A#B&&C=0&&D=0&&E=1?1:0") field(OOPT, "When Non-zero") field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS PP") } @@ -146,7 +147,7 @@ record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") 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") - field(CALC, "(F=0||G=0||D=1||K=1)?3:(A=1)?2:(C=1||H#I)?1:(B=0)?3:0") + field(CALC, "(F=0||G=0||D=1||K=1)?3:(A=1)?2:(B=0||C=1||H#I)?1:0") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):STATUS PP") } From 42d8332eceb8a3d28e50f8ebf3d8744254fd87f6 Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Mon, 18 May 2026 16:39:55 +0200 Subject: [PATCH 13/15] don't trust sps --- beamstop/sans_llb_beamstop.db | 102 ++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/beamstop/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db index 9b9b2d6..2751a81 100644 --- a/beamstop/sans_llb_beamstop.db +++ b/beamstop/sans_llb_beamstop.db @@ -56,7 +56,7 @@ record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-OUT") field(DOL, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-RAW PP") field(OMSL, "closed_loop") - field(DRVL, 1) + field(DRVL, 0) field(DRVH, 3) field(PINI, "NO") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER-DELAY") @@ -87,17 +87,38 @@ record(longout, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER") # record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):RETRY") { - field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP") - field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV") + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP NPP") + field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV NPP") field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") - field(INPD, "$(INSTR)$(SPS_REGISTER_NAME):MOVES") - field(INPE, "$(INSTR)$(SPS_REGISTER_NAME):STATUS") - field(CALC, "A#B&&C#0&&D=0&&E=0?1:0") + # Can't trust the SPS + field(INPD, "$(BS_MCU):BS:TARGET_RANGE NPP") + field(CALC, "A#B&&C#0&&D=0?1:0") + # field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") + # field(INPD, "$(INSTR)$(SPS_REGISTER_NAME):MOVES") + # field(INPE, "$(INSTR)$(SPS_REGISTER_NAME):STATUS") + # field(INPF, "$(INSTR)$(SPS_REGISTER_NAME):IN-POSITION NPP") + # field(CALC, "A#B&&C#0&&D=0&&F=1&&E=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):DECREASE-BUSY-TICK") + 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") @@ -122,24 +143,22 @@ record(seq, "$(INSTR)$(SPS_REGISTER_NAME):DELAY-RETRY-ERROR") field(SELM, "All") } -record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):RETRY-ERROR") +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):MOVES") - field(INPE, "$(INSTR)$(SPS_REGISTER_NAME):IN-POSITION NPP") - field(CALC, "A#B&&C=0&&D=0&&E=1?1:0") - field(OOPT, "When Non-zero") - field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS PP") + 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):IN-POSITION NPP") - field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):MOVES 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") @@ -147,10 +166,33 @@ record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") 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") - field(CALC, "(F=0||G=0||D=1||K=1)?3:(A=1)?2:(B=0||C=1||H#I)?1:0") + field(CALC, "(F=0||G=0||D=1||K=1)?3:(A=1)?2:(B=1||H#I)?1:0") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") +} + +record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") +{ + field(DESC, "Disable BSX during change") + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") + field(INPB, "$(BS_MCU):bsx.DISA NPP") + field(CALC, "A=0?!B:B") + field(DOPT, "Use CALC") + field(OUT, "$(BS_MCU):bsx.DISV PP") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") +} + +record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") +{ + field(DESC, "Disable BSY during change") + field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") + field(INPB, "$(BS_MCU):bsy.DISA NPP") + field(CALC, "A=0?!B:B") + field(DOPT, "Use CALC") + field(OUT, "$(BS_MCU):bsy.DISV PP") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):STATUS PP") } + record(mbbi, "$(INSTR)$(SPS_REGISTER_NAME):STATUS") { field(DESC, "Status of Shutter") @@ -186,35 +228,13 @@ record(scalcout, "$(INSTR)$(SPS_REGISTER_NAME):STATUS-Msg") record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):SET-READY") { - field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):MOVES") - field(INPB, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") - field(CALC, "B?A:0") + 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") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") -} - -record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") -{ - field(DESC, "Disable BSX during change") - field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") - field(INPB, "$(BS_MCU):bsx.DISA NPP") - field(CALC, "A=0?!B:B") - field(DOPT, "Use CALC") - field(OUT, "$(BS_MCU):bsx.DISV PP") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") -} - -record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") -{ - field(DESC, "Disable BSY during change") - field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") - field(INPB, "$(BS_MCU):bsy.DISA NPP") - field(CALC, "A=0?!B:B") - field(DOPT, "Use CALC") - field(OUT, "$(BS_MCU):bsy.DISV PP") } ################################################################################ From a31ec09407a72c83b7a959e1e65f0e079e86676f Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Tue, 19 May 2026 11:19:35 +0200 Subject: [PATCH 14/15] block motors before triggering SPS and make sure unblocked, before returning to okay status --- beamstop/sans_llb_beamstop.db | 452 +++++++++++++++++----------------- 1 file changed, 230 insertions(+), 222 deletions(-) diff --git a/beamstop/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db index 2751a81..eb30d31 100644 --- a/beamstop/sans_llb_beamstop.db +++ b/beamstop/sans_llb_beamstop.db @@ -23,31 +23,56 @@ record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP") # 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") + 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") + field(DESC, "Internal Busy State") + field(VAL, 0) + field(ZNAM, "Ready") + field(ONAM, "Busy") } -record(longout, "$(INSTR)$(SPS_REGISTER_NAME):SET-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") - # This determines the number of max retry ticks - field(VAL, 5) - field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):BUSY PP") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-OUT") + 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") @@ -84,25 +109,19 @@ record(longout, "$(INSTR)$(SPS_REGISTER_NAME):TRIGGER") # 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 - field(INPD, "$(BS_MCU):BS:TARGET_RANGE NPP") - field(CALC, "A#B&&C#0&&D=0?1:0") - # field(INPC, "$(INSTR)$(SPS_REGISTER_NAME):BUSY") - # field(INPD, "$(INSTR)$(SPS_REGISTER_NAME):MOVES") - # field(INPE, "$(INSTR)$(SPS_REGISTER_NAME):STATUS") - # field(INPF, "$(INSTR)$(SPS_REGISTER_NAME):IN-POSITION NPP") - # field(CALC, "A#B&&C#0&&D=0&&F=1&&E=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") + 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") @@ -123,13 +142,13 @@ record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MCU-CHANGING") 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") + 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. @@ -145,96 +164,86 @@ record(seq, "$(INSTR)$(SPS_REGISTER_NAME):DELAY-RETRY-ERROR") 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") + 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") - field(CALC, "(F=0||G=0||D=1||K=1)?3:(A=1)?2:(B=1||H#I)?1:0") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") + 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") + field(CALC, "(F=0||G=0||D=1||K=1)?3:(A=1)?2:(B=1||H#I)?1:0") + field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):UNBLOCK-MOTORS") } -record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") +# 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, "Disable BSX during change") - field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") - field(INPB, "$(BS_MCU):bsx.DISA NPP") - field(CALC, "A=0?!B:B") - field(DOPT, "Use CALC") - field(OUT, "$(BS_MCU):bsx.DISV PP") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") + 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(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") -{ - field(DESC, "Disable BSY during change") - field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") - field(INPB, "$(BS_MCU):bsy.DISA NPP") - field(CALC, "A=0?!B:B") - field(DOPT, "Use CALC") - field(OUT, "$(BS_MCU):bsy.DISV PP") - 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") - field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):STATUS-Msg") + 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") + 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") + 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") + 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") } ################################################################################ @@ -242,144 +251,143 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):SET-READY") ################################################################################ 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") + 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") + 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") + 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") + 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") + 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") + 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_FANOUT.PROC") + 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(LNK7, "$(BS_MCU):BS:ST_FANOUT2") - field(SCAN, ".1 second") + 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:TARGET_RANGE_RAW") - field(LNK2, "$(BS_MCU):BS:TARGET_RANGE") - field(LNK3, "$(BS_MCU):BS:LOADED_RAW") - field(LNK4, "$(BS_MCU):BS:INVALID") + field(LNK1, "$(BS_MCU):BS:TARGET_RANGE_RAW") + field(LNK2, "$(BS_MCU):BS:TARGET_RANGE") + field(LNK3, "$(BS_MCU):BS:LOADED_RAW") + field(LNK4, "$(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") + 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_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(ai, "$(BS_MCU):BS:TARGET_Y") { + field(DESC, "Y Position being driven to") + field(INP, "$(BS_MCU):BS:ST.C 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") + 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") + 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") + 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") + 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, "$(BS_MCU):BS:LOADED PP") + 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, "$(BS_MCU):BS:LOADED PP") } record(longout, "$(INSTR)$(SPS_REGISTER_NAME):LOADED-INIT") @@ -393,34 +401,34 @@ record(longout, "$(INSTR)$(SPS_REGISTER_NAME):LOADED-INIT") record(mbbi, "$(BS_MCU):BS:LOADED") { - field(DESC, "Most recently lifted beamstop") - field(ZRST, "No Beamstop") - field(ONST, "Beamstop 1") - field(TWST, "Beamstop 2") - field(THST, "Beamstop 3") + 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, "$(BS_MCU):BS: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") + 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, "$(BS_MCU):BS: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") + 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") { From c2b45a91d26af729c78c2b13219d0a938ebffe14 Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Tue, 19 May 2026 15:31:31 +0200 Subject: [PATCH 15/15] use internal MCU-derived state in addition to SPS --- beamstop/beamstop_motors.proto | 4 ++-- beamstop/sans_llb_beamstop.db | 34 +++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/beamstop/beamstop_motors.proto b/beamstop/beamstop_motors.proto index 420e5d5..667d31a 100644 --- a/beamstop/beamstop_motors.proto +++ b/beamstop/beamstop_motors.proto @@ -9,8 +9,8 @@ pmac_get { st { InTerminator = CR ACK; - out "P553 Q401 Q501"; - in "%(A)d%*[ ]%(B)f%*[ ]%(C)f"; + out "P553 Q401 Q501 P423 P523"; + in "%(A)d%*[ ]%(B)f%*[ ]%(C)f\r%(D)d\r%(E)d"; } stop { diff --git a/beamstop/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db index eb30d31..1964958 100644 --- a/beamstop/sans_llb_beamstop.db +++ b/beamstop/sans_llb_beamstop.db @@ -185,7 +185,11 @@ record(calc, "$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") 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") - field(CALC, "(F=0||G=0||D=1||K=1)?3:(A=1)?2:(B=1||H#I)?1:0") + # 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") } @@ -311,10 +315,12 @@ record(fanout, "$(BS_MCU):BS:ST_FANOUT1") { } record(fanout, "$(BS_MCU):BS:ST_FANOUT2") { - field(LNK1, "$(BS_MCU):BS:TARGET_RANGE_RAW") - field(LNK2, "$(BS_MCU):BS:TARGET_RANGE") - field(LNK3, "$(BS_MCU):BS:LOADED_RAW") - field(LNK4, "$(BS_MCU):BS:INVALID") + 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") { @@ -332,6 +338,16 @@ record(ai, "$(BS_MCU):BS:TARGET_Y") { 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 @@ -387,19 +403,19 @@ record(calcout, "$(BS_MCU):BS:LOADED_RAW") field(OOPT, "Transition To Zero") field(DOPT, "Use OCAL") field(OCAL, "A") - field(OUT, "$(BS_MCU):BS:LOADED PP") + 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, "$(BS_MCU):BS:LOADED NPP") + field(OUT, "$(INSTR)$(SPS_REGISTER_NAME):LOADED NPP") field(OMSL, "closed_loop") field(PINI, "YES") } -record(mbbi, "$(BS_MCU):BS:LOADED") +record(mbbi, "$(INSTR)$(SPS_REGISTER_NAME):LOADED") { field(DESC, "Most recently lifted beamstop") field(ZRST, "No Beamstop") @@ -413,7 +429,7 @@ record(calcout, "$(BS_MCU):BS:INVALID") { # Dynamic Inputs field(INPA, "$(BS_MCU):BS:TARGET_BS NPP MS") field(INPB, "$(BS_MCU):BS:TARGET_RANGE NPP MS") - field(INPC, "$(BS_MCU):BS:LOADED 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")