# # Simple driver generator for the non-motor galil controls on mc4 # vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent # driver shutters = { vendor = galil; device = mc4; protocol = dmc2280; class = instrument simulation_group = motor_simulation # # Unnamed group has variables at device level # # # The named group is at the device level, variables below that # group = { type = text priv = user group_property 'data' = 'true' group_property 'nxsave' = 'true' property 'type' = 'part' property 'klass' = 'collimator' property 'sdsinfo' = '::nexus::scobj::sdsinfo' var fast_shutter = { readable = 1 read_command = 'MG @IN[5], @IN[6]' read_function = read_switch_pair mutable = false property 'nxalias' = 'fast_shutter' } var rough_40 = { readable = 1; read_function = read_switch_pair; read_command = 'MG @IN[13], @IN[14]' writeable = 1 write_function = no_write; write_command = '10' allowed = 'in,out' mutable = false property 'nxalias' = 'rough_40' } var rough_100 = { readable = 1; read_function = read_switch_pair; read_command = 'MG @IN[15], @IN[16]' writeable = 1 write_function = no_write; write_command = '11' allowed = 'in,out' mutable = false property 'nxalias' = 'rough_100' } }; # # Code lines start with '@' which is stripped before being emitted # The code is emitted at the appropriate place in the given function # 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] == ":" } { @ set data_list [lrange ${data_list} 0 1] @ } @ if { [llength ${data_list}] == 2 } { @ set left [expr [lindex ${data_list} 0]] @ 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"] } { @ set cmd "SB${cmd_str}" @ } elseif { [string equal -nocase -length 2 "${par}" "out"] } { @ set cmd "CB${cmd_str}" @ } else { @ 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 } };