179 lines
5.5 KiB
Plaintext
179 lines
5.5 KiB
Plaintext
#
|
|
# 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 {args} {
|
|
@ 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. Without argurments selrs reports current positions."
|
|
@ set catch_status [ catch {
|
|
@ switch [llength $args] {
|
|
@ 0 {
|
|
@ clientput [hlist -val /sics/shutters]
|
|
@ return
|
|
@ }
|
|
@ 1 {
|
|
@ set slit $args
|
|
@ set cb_timeout 60
|
|
@ }
|
|
@ 2 {
|
|
@ foreach {slit cb_timeout} $args {}
|
|
@ }
|
|
@ default {
|
|
@ error "[info level 0]: $usage_msg"
|
|
@ }
|
|
@ }
|
|
@ 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
|
|
}
|
|
};
|