From 0c6168a526e2662e9ae3f4a9a1da1594aa76c5f6 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Fri, 16 Jan 2015 16:17:53 +1100 Subject: [PATCH] SICS-840: Added selrs to select roughing slits and guarantee that a slit is always selected. Also disabled driving slits via hset on GumTree. --- .../bilby/config/motors/shutters.sct | 71 +++++++++++++- .../bilby/config/motors/shutters_sct.tcl | 98 ++++++++++++++++++- 2 files changed, 165 insertions(+), 4 deletions(-) diff --git a/site_ansto/instrument/bilby/config/motors/shutters.sct b/site_ansto/instrument/bilby/config/motors/shutters.sct index 46c428b4..04486fad 100644 --- a/site_ansto/instrument/bilby/config/motors/shutters.sct +++ b/site_ansto/instrument/bilby/config/motors/shutters.sct @@ -31,7 +31,7 @@ driver shutters = { read_function = read_switch_pair; read_command = 'MG @IN[13], @IN[14]' writeable = 1 - write_function = write_switch; + write_function = no_write; write_command = '10' allowed = 'in,out' property 'nxalias' = 'rough_40' @@ -41,7 +41,7 @@ driver shutters = { read_function = read_switch_pair; read_command = 'MG @IN[15], @IN[16]' writeable = 1 - write_function = write_switch; + write_function = no_write; write_command = '11' allowed = 'in,out' property 'nxalias' = 'rough_100' @@ -55,6 +55,7 @@ driver shutters = { code read_function read_switch_pair = { @ if { [string equal -nocase -length 1 "${data}" "?"] } { @ sct geterror "Galil error in: '${data}'" +@ set cb_event "fatal_error" @ } else { @ set data_list [split [string trim "${data}"]] @ if { [llength ${data_list}] > 2 && [lindex ${data_list} end] == ":" } { @@ -65,15 +66,20 @@ driver shutters = { @ set right [expr [lindex ${data_list} 1]] @ if { ${left} == 1 && ${right} == 0 } { # open @ set data "out" +@ set cb_event $data @ } elseif { ${left} == 0 && ${right} == 1 } { # closed @ set data "in" +@ set cb_event $data @ } else { # indeterminate @ set data "moving" +@ set cb_event $data @ } @ } else { @ sct geterror "Syntax error in: '${data}'=>'${data_list}'" +@ set cb_event "fatal_error" @ } @ } +@ call_oneshot [sct] $cb_event } code write_function write_switch = { @ if { [string equal -nocase -length 2 "${par}" "in"] } { @@ -84,9 +90,70 @@ driver shutters = { @ sct geterror "Value error: '${par}' not in ('in', 'out')" @ } } + code write_function no_write = { +@ error "Setting this value is disallowed" + } # # This code is after database creation # code mkDriver = { } + code postamble = { +@ variable rough_slits_enabled 0 +@ variable rough_slits_cb_pending 0 +@ proc selrs {slit {cb_timeout 60}} { +@ variable rough_slits_enabled +@ variable rough_slits_cb_pending +@ set usage_msg "Valid arguments are 40 or 100 or use 'reset' to terminate a previous selrs call" +@ set catch_status [ catch { +@ if {$slit == "help"} { +@ clientput "Usage: $usage_msg" +@ return +@ } +@ if { $rough_slits_enabled != 1 } { +@ error "Roughing slit selection disabled" +@ } +@ if {$slit == "reset"} { +@ set_oneshot /sics/shutters/rough_40 xxx "in" "clear" +@ set_oneshot /sics/shutters/rough_100 xxx "in" "clear" +@ return +@ } else { +@ if {$slit != 40 && $slit != 100} { +@ error "[info level 0]: Invalid roughing slit $slit. $usage_msg" +@ } +@ if [hpropexists /sics/shutters/rough_40 oneshot_state] { +@ set R40_state [hgetpropval /sics/shutters/rough_40 oneshot_state] +@ } else { +@ set R40_state 0 +@ } +@ if [hpropexists /sics/shutters/rough_100 oneshot_state] { +@ set R100_state [hgetpropval /sics/shutters/rough_100 oneshot_state] +@ } else { +@ set R100_state 0 +@ } +@ if {$R40_state == 1 || $R100_state == 1} { +@ error "Waiting for a previous selrs call to complete" +@ } +@ } +@ if {![string is integer $cb_timeout]} { +@ error "The timeout must be an integer" +@ } +@ switch $slit { +@ 40 { +@ mc4 send SB10 +@ # Raise RS100 on receiving the "in" event on RS40 within the given timeout +@ set_oneshot /sics/shutters/rough_40 { apply {{hp args} {mc4 send CB11}} } "in" $cb_timeout +@ } +@ 100 { +@ mc4 send SB11 +@ # Raise RS40 on receiving the "in" event on RS100 within the given timeout +@ set_oneshot /sics/shutters/rough_100 { apply {{hp args} {mc4 send CB10}} } "in" $cb_timeout +@ } +@ } +@ } catch_message ] +@ handle_exception ${catch_status} ${catch_message} +@ } +@ namespace export selrs +@ publish selrs mugger + } }; diff --git a/site_ansto/instrument/bilby/config/motors/shutters_sct.tcl b/site_ansto/instrument/bilby/config/motors/shutters_sct.tcl index 9a0d259c..c3ea3812 100644 --- a/site_ansto/instrument/bilby/config/motors/shutters_sct.tcl +++ b/site_ansto/instrument/bilby/config/motors/shutters_sct.tcl @@ -84,6 +84,36 @@ proc ::scobj::shutters::noResponse {tc_root} { handle_exception ${catch_status} ${catch_message} } +# function to write a parameter value on a device +proc ::scobj::shutters::no_write {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "no_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set par [sct target] + set cmd "${cmd_str}${par}" +# no_write hook code starts + error "Setting this value is disallowed" +# no_write hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { [hpropexists [sct] driving] } { + if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { + sct driving 1 + } + } + debug_log ${tc_root} 1 "no_write sct send ${cmd}" + if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { + sct send "${cmd}" + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + # function to parse the read of a parameter on a device proc ::scobj::shutters::read_switch_pair {tc_root} { set catch_status [ catch { @@ -101,6 +131,7 @@ proc ::scobj::shutters::read_switch_pair {tc_root} { # read_switch_pair hook code starts if { [string equal -nocase -length 1 "${data}" "?"] } { sct geterror "Galil error in: '${data}'" + set cb_event "fatal_error" } else { set data_list [split [string trim "${data}"]] if { [llength ${data_list}] > 2 && [lindex ${data_list} end] == ":" } { @@ -111,15 +142,20 @@ proc ::scobj::shutters::read_switch_pair {tc_root} { set right [expr [lindex ${data_list} 1]] if { ${left} == 1 && ${right} == 0 } { # open set data "out" + set cb_event $data } elseif { ${left} == 0 && ${right} == 1 } { # closed set data "in" + set cb_event $data } else { # indeterminate set data "moving" + set cb_event $data } } else { sct geterror "Syntax error in: '${data}'=>'${data_list}'" + set cb_event "fatal_error" } } + call_oneshot [sct] $cb_event # read_switch_pair hook code ends if { [hpropexists [sct] geterror] } { debug_log ${tc_root} 9 "[sct] error: [sct geterror]" @@ -233,7 +269,7 @@ proc ::scobj::shutters::mkDriver { sct_controller name device_class simulation_f hfactory ${scobj_hpath}/rough_100 plain user text hsetprop ${scobj_hpath}/rough_100 read ${ns}::getValue ${scobj_hpath} read_switch_pair {MG @IN[15], @IN[16]} hsetprop ${scobj_hpath}/rough_100 read_switch_pair ${ns}::read_switch_pair ${scobj_hpath} - hsetprop ${scobj_hpath}/rough_100 write ${ns}::write_switch ${scobj_hpath} noResponse {11} + hsetprop ${scobj_hpath}/rough_100 write ${ns}::no_write ${scobj_hpath} noResponse {11} hsetprop ${scobj_hpath}/rough_100 noResponse ${ns}::noResponse ${scobj_hpath} hsetprop ${scobj_hpath}/rough_100 check ${ns}::checkrange ${scobj_hpath} hsetprop ${scobj_hpath}/rough_100 control true @@ -259,7 +295,7 @@ proc ::scobj::shutters::mkDriver { sct_controller name device_class simulation_f hfactory ${scobj_hpath}/rough_40 plain user text hsetprop ${scobj_hpath}/rough_40 read ${ns}::getValue ${scobj_hpath} read_switch_pair {MG @IN[13], @IN[14]} hsetprop ${scobj_hpath}/rough_40 read_switch_pair ${ns}::read_switch_pair ${scobj_hpath} - hsetprop ${scobj_hpath}/rough_40 write ${ns}::write_switch ${scobj_hpath} noResponse {10} + hsetprop ${scobj_hpath}/rough_40 write ${ns}::no_write ${scobj_hpath} noResponse {10} hsetprop ${scobj_hpath}/rough_40 noResponse ${ns}::noResponse ${scobj_hpath} hsetprop ${scobj_hpath}/rough_40 check ${ns}::checkrange ${scobj_hpath} hsetprop ${scobj_hpath}/rough_40 control true @@ -324,6 +360,64 @@ namespace eval ::scobj::shutters { namespace export sics_log namespace export mkDriver namespace export add_driver +# postamble hook code starts + variable rough_slits_enabled 0 + variable rough_slits_cb_pending 0 + proc selrs {slit {cb_timeout 60}} { + variable rough_slits_enabled + variable rough_slits_cb_pending + set usage_msg "Valid arguments are 40 or 100 or use 'reset' to terminate a previous selrs call" + set catch_status [ catch { + if {$slit == "help"} { + clientput "Usage: $usage_msg" + return + } + if { $rough_slits_enabled != 1 } { + error "Roughing slit selection disabled" + } + if {$slit == "reset"} { + set_oneshot /sics/shutters/rough_40 xxx "in" "clear" + set_oneshot /sics/shutters/rough_100 xxx "in" "clear" + return + } else { + if {$slit != 40 && $slit != 100} { + error "[info level 0]: Invalid roughing slit $slit. $usage_msg" + } + if [hpropexists /sics/shutters/rough_40 oneshot_state] { + set R40_state [hgetpropval /sics/shutters/rough_40 oneshot_state] + } else { + set R40_state 0 + } + if [hpropexists /sics/shutters/rough_100 oneshot_state] { + set R100_state [hgetpropval /sics/shutters/rough_100 oneshot_state] + } else { + set R100_state 0 + } + if {$R40_state == 1 || $R100_state == 1} { + error "Waiting for a previous selrs call to complete" + } + } + if {![string is integer $cb_timeout]} { + error "The timeout must be an integer" + } + switch $slit { + 40 { + mc4 send SB10 + # Raise RS100 on receiving the "in" event on RS40 within the given timeout + set_oneshot /sics/shutters/rough_40 { apply {{hp args} {mc4 send CB11}} } "in" $cb_timeout + } + 100 { + mc4 send SB11 + # Raise RS40 on receiving the "in" event on RS100 within the given timeout + set_oneshot /sics/shutters/rough_100 { apply {{hp args} {mc4 send CB10}} } "in" $cb_timeout + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} + } + namespace export selrs + publish selrs mugger +# postamble hook code ends } proc add_shutters {name ip_address tcp_port} {