diff --git a/site_ansto/instrument/config/environment/sct_keysight_N8740A.tcl b/site_ansto/instrument/config/environment/sct_keysight_N8740A.tcl index bb079087..839afea7 100644 --- a/site_ansto/instrument/config/environment/sct_keysight_N8740A.tcl +++ b/site_ansto/instrument/config/environment/sct_keysight_N8740A.tcl @@ -188,6 +188,65 @@ proc ::scobj::keysight_N8740A::rdValue {tc_root} { handle_exception ${catch_status} ${catch_message} } +# function to request the read of a parameter on a device +proc ::scobj::keysight_N8740A::read_setpoint {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "read_setpoint tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set cmd "${cmd_str}" +# read_setpoint hook code starts + if { [hpropexists [sct] target] } { + set target [sct target] + if { [hval ${tc_root}/working_setpoint] != ${target} } { + set elapsed_time [expr {[sct utime] - [sct ramp_start_time]}] + debug_log ${tc_root} 1 "read_setpoint elapsed_time = ${elapsed_time}" + if {[hpropexists [sct] ramp_rate_value] && [sct ramp_rate_value] > 0.0} { + set ramped_value [expr {[sct ramp_rate_value] * ${elapsed_time}}] + debug_log ${tc_root} 1 "read_setpoint ramped_value = ${ramped_value}" + if { ${target} > [hval ${tc_root}/working_setpoint] } { + set working_setpoint [expr {[sct ramp_start_value] + ${ramped_value}}] + debug_log ${tc_root} 1 "read_setpoint working_setpoint+ = ${working_setpoint}" + if { ${working_setpoint} > ${target} } { + set working_setpoint ${target} + } + } else { + set working_setpoint [expr {[sct ramp_start_value] - ${ramped_value}}] + debug_log ${tc_root} 1 "read_setpoint working_setpoint- = ${working_setpoint}" + if { ${working_setpoint} < ${target} } { + set working_setpoint ${target} + } + } + } else { + set working_setpoint ${target} + debug_log ${tc_root} 1 "read_setpoint working_setpoint = ${working_setpoint}" + } + if {![hpropexists [sct] ramp_rate_value] || [sct ramp_rate_value] != [hval ${tc_root}/ramp_rate]} { + sct ramp_start_time [sct utime] + sct ramp_start_value [hval ${tc_root}/working_setpoint] + sct ramp_rate_value [hval ${tc_root}/ramp_rate] + } + set cmd "SOURCE:VOLTAGE ${working_setpoint}@@NOREPLY@@" + sct result [hval ${tc_root}/working_setpoint] + } + } else { + # cmd is fine + } +# read_setpoint hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + debug_log ${tc_root} 1 "read_setpoint 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 write a parameter value on a device proc ::scobj::keysight_N8740A::setValue {tc_root nextState cmd_str} { set catch_status [ catch { @@ -218,6 +277,83 @@ proc ::scobj::keysight_N8740A::setValue {tc_root nextState cmd_str} { handle_exception ${catch_status} ${catch_message} } +# function to write a parameter value on a device +proc ::scobj::keysight_N8740A::write_direct {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "write_direct 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}" +# write_direct hook code starts + set cmd "@@NOSEND@@" + sct result "" + if { [sct target] != [sct oldval] } { + debug_log ${tc_root} 1 "[sct] changed to new:[sct target], from old:[sct oldval]" + sct oldval [sct target] + sct update [sct target] + sct utime readtime + } +# write_direct 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 "write_direct 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 write a parameter value on a device +proc ::scobj::keysight_N8740A::write_setpoint {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "write_setpoint 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}" +# write_setpoint hook code starts + set cmd "@@NOSEND@@" + sct result "" + sct ramp_start_time [sct utime] + sct ramp_start_value [hval ${tc_root}/working_setpoint] + sct ramp_rate_value [hval ${tc_root}/ramp_rate] + if { [sct target] != [sct oldval] } { + debug_log ${tc_root} 1 "[sct] changed to new:[sct target], from old:[sct oldval]" + sct oldval [sct target] + sct update [sct target] + sct utime readtime + } +# write_setpoint 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 "write_setpoint sct send ${cmd}" + if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { + sct send "${cmd}" + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + proc ::scobj::keysight_N8740A::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port } { ::scobj::keysight_N8740A::sics_log 9 "::scobj::keysight_N8740A::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}" set ns "[namespace current]" @@ -279,17 +415,43 @@ proc ::scobj::keysight_N8740A::mkDriver { sct_controller name device_class simul hsetprop ${scobj_hpath}/output_enable simulated true } + hfactory ${scobj_hpath}/ramp_rate plain user float + hsetprop ${scobj_hpath}/ramp_rate write ${ns}::write_direct ${scobj_hpath} noResponse {} + hsetprop ${scobj_hpath}/ramp_rate noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ramp_rate check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ramp_rate control true + hsetprop ${scobj_hpath}/ramp_rate data true + hsetprop ${scobj_hpath}/ramp_rate mutable true + hsetprop ${scobj_hpath}/ramp_rate nxsave true + hsetprop ${scobj_hpath}/ramp_rate lowerlimit 0 + hsetprop ${scobj_hpath}/ramp_rate upperlimit 15 + hsetprop ${scobj_hpath}/ramp_rate units V/S + hsetprop ${scobj_hpath}/ramp_rate oldval 1.0 + hset ${scobj_hpath}/ramp_rate 1.0 + hsetprop ${scobj_hpath}/ramp_rate klass "parameter" + hsetprop ${scobj_hpath}/ramp_rate sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ramp_rate type "part" + hsetprop ${scobj_hpath}/ramp_rate nxalias "${name}_ramp_rate" + + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} write ${scobj_hpath}/ramp_rate + hsetprop ${scobj_hpath}/ramp_rate simulated false + } else { + ::scobj::keysight_N8740A::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for keysight_N8740A" + hsetprop ${scobj_hpath}/ramp_rate simulated true + } + hfactory ${scobj_hpath}/setpoint plain user float - hsetprop ${scobj_hpath}/setpoint read ${ns}::getValue ${scobj_hpath} rdValue {SOURCE:VOLTAGE?} + hsetprop ${scobj_hpath}/setpoint read ${ns}::read_setpoint ${scobj_hpath} rdValue {SOURCE:VOLTAGE?} hsetprop ${scobj_hpath}/setpoint rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/setpoint write ${ns}::setValue ${scobj_hpath} noResponse {SOURCE:VOLTAGE } + hsetprop ${scobj_hpath}/setpoint write ${ns}::write_setpoint ${scobj_hpath} noResponse {SOURCE:VOLTAGE } hsetprop ${scobj_hpath}/setpoint noResponse ${ns}::noResponse ${scobj_hpath} hsetprop ${scobj_hpath}/setpoint check ${ns}::checkrange ${scobj_hpath} hsetprop ${scobj_hpath}/setpoint driving 0 hsetprop ${scobj_hpath}/setpoint checklimits ${ns}::checklimits ${scobj_hpath} hsetprop ${scobj_hpath}/setpoint checkstatus ${ns}::checkstatus ${scobj_hpath} hsetprop ${scobj_hpath}/setpoint halt ${ns}::halt ${scobj_hpath} - hsetprop ${scobj_hpath}/setpoint driveable setpoint + hsetprop ${scobj_hpath}/setpoint driveable working_setpoint hsetprop ${scobj_hpath}/setpoint control true hsetprop ${scobj_hpath}/setpoint data true hsetprop ${scobj_hpath}/setpoint mutable true @@ -301,6 +463,7 @@ proc ::scobj::keysight_N8740A::mkDriver { sct_controller name device_class simul hsetprop ${scobj_hpath}/setpoint oldval 0.0 hsetprop ${scobj_hpath}/setpoint klass "parameter" hsetprop ${scobj_hpath}/setpoint sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/setpoint settle_time "5" hsetprop ${scobj_hpath}/setpoint type "drivable" hsetprop ${scobj_hpath}/setpoint nxalias "${name}_setpoint" @@ -335,10 +498,36 @@ proc ::scobj::keysight_N8740A::mkDriver { sct_controller name device_class simul hsetprop ${scobj_hpath}/volts simulated true } + hfactory ${scobj_hpath}/working_setpoint plain user float + hsetprop ${scobj_hpath}/working_setpoint read ${ns}::getValue ${scobj_hpath} rdValue {SOURCE:VOLTAGE?} + hsetprop ${scobj_hpath}/working_setpoint rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/working_setpoint write ${ns}::write_direct ${scobj_hpath} noResponse {} + hsetprop ${scobj_hpath}/working_setpoint noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/working_setpoint check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/working_setpoint control true + hsetprop ${scobj_hpath}/working_setpoint data true + hsetprop ${scobj_hpath}/working_setpoint mutable true + hsetprop ${scobj_hpath}/working_setpoint nxsave true + hsetprop ${scobj_hpath}/working_setpoint units V + hsetprop ${scobj_hpath}/working_setpoint oldval 0.0 + hsetprop ${scobj_hpath}/working_setpoint klass "parameter" + hsetprop ${scobj_hpath}/working_setpoint sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/working_setpoint type "part" + hsetprop ${scobj_hpath}/working_setpoint nxalias "${name}_working_setpoint" + + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} poll ${scobj_hpath}/working_setpoint 1 + ${sct_controller} write ${scobj_hpath}/working_setpoint + hsetprop ${scobj_hpath}/working_setpoint simulated false + } else { + ::scobj::keysight_N8740A::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for keysight_N8740A" + hsetprop ${scobj_hpath}/working_setpoint simulated true + } + hsetprop ${scobj_hpath} data "true" hsetprop ${scobj_hpath} klass "@none" hsetprop ${scobj_hpath} type "part" - ansto_makesctdrive ${name}_setpoint ${scobj_hpath}/setpoint ${scobj_hpath}/setpoint ${sct_controller} + ansto_makesctdrive ${name}_setpoint ${scobj_hpath}/setpoint ${scobj_hpath}/working_setpoint ${sct_controller} hfactory ${scobj_hpath}/current plain spy none