sct_fermichopper.tcl

Refactored to enable creation master and slave chopper objects and added
a mkChoppers command.

r3749 | ffr | 2012-09-26 10:02:12 +1000 (Wed, 26 Sep 2012) | 4 lines
This commit is contained in:
Ferdi Franceschini
2012-09-26 10:02:12 +10:00
committed by Douglas Clowes
parent b887636684
commit 99c3c397d3

View File

@@ -1,35 +1,36 @@
namespace eval ::scobj::chopper { namespace eval ::scobj::chopper {
# MakeSICSObj disk_chopper SCT_OBJECT user int # MakeSICSObj disk_chopper SCT_OBJECT user int
# sicslist setatt disk_chopper klass NXdisk_chopper # sicslist setatt disk_chopper klass NXdisk_chopper
# sicslist setatt disk_chopper long_name disk_chopper # sicslist setatt disk_chopper long_name disk_chopper
proc sndMBquery {rdScript cmd nextReq} { proc sndMBquery {rdScript cmd nextReq} {
set chN [sct chopper] set chN [ lindex [sct P_chAddress] [sct P_chIndex] ]
sct nextSndReq $nextReq sct nextSndReq $nextReq
sct send "$chN:$cmd" sct send "$chN:$cmd"
return $rdScript return $rdScript
} }
proc sndMBset {root cmd} { proc sndMBset {root cmd} {
set val [sct target] set val [sct target]
#TODO convert val to appropriate units, if [convfact] then val = val * [sct convfact] #TODO convert val to appropriate units, if [convfact] then val = val * [sct convfact]
sct send "$cmd:$val" sct send "$cmd:$val"
sct target 0 sct target 0
return RDSETREPLY return RDSETREPLY
} }
proc rdStatus {root statnode fields} { proc rdStatus {root statnode fields} {
set currCh [sct chopper] set currCh [ lindex [sct P_name] [sct P_chIndex] ]
set chPath $root/ch$currCh/$statnode set chPath $root/$currCh/$statnode
set oldval [hgetpropval $chPath oldval] set oldval [hgetpropval $chPath P_oldval]
set val [sct result] set val [sct result]
if {[string match "ASCERR:*" $val]} { if {[string match "ASCERR:*" $val]} {
sct geterror $val sct geterror $val
return idle return idle
} }
if {$val != $oldval} { if {$val != $oldval} {
hsetprop $chPath oldval $val sct update 1
hsetprop $chPath P_oldval $val
binary scan [binary format c $val] B* binNum binary scan [binary format c $val] B* binNum
set bitfield [split $binNum ""] set bitfield [split $binNum ""]
foreach n $fields b $bitfield { foreach n $fields b $bitfield {
@@ -37,61 +38,28 @@ proc rdStatus {root statnode fields} {
} }
} }
return [sct nextSndReq] return [sct nextSndReq]
} }
proc rdSysStatus {root nodes} {
# Read status byte and set nodes for each bit proc rdCoil {root node coil} {
set currCh [sct chopper] set chIndex [sct P_chIndex]
set chPath $root/ch$currCh/system_status set currCh [ lindex [sct P_name] $chIndex ]
set oldval [hgetpropval $chPath oldval]
set val [sct result] set val [sct result]
if {[string match "ASCERR:*" $val]} { set cAddr [expr $coil - 1]
sct geterror $val set coilPath $root/$currCh/$node
return idle
} set oldval [hgetpropval $coilPath P_oldval]
if {$val != $oldval} { if {$val != $oldval} {
hsetprop $chPath oldval $val hsetprop $coilPath P_oldval $val
binary scan [binary format c $val] B* binNum
set bitfield [split $binNum ""]
binary scan [binary format c $oldval] B* oldbinNum
set oldbitfield [split $oldbinNum ""]
foreach n $nodes b $bitfield ob $oldbitfield {
if {$b != $ob} {
hset $chPath/$n $b
}
}
} }
return [sct nextSndReq] return [sct nextSndReq]
}
proc rdIntLkStatus {root nodes} {
# Read status byte and set nodes for each bit
set currCh [sct chopper]
set chPath $root/ch$currCh/intlck_status
set oldval [hgetpropval $chPath oldval]
set val [sct result]
if {[string match "ASCERR:*" $val]} {
sct geterror $val
return idle
} }
if {$val != $oldval} { ##
hsetprop $chPath oldval $val # Reads a list of values in the result and assigns them to the nodes in the args list
binary scan [binary format c $val] B* binNum proc rdVal {root nodes} {
set bitfield [split $binNum ""] set chIndex [sct P_chIndex]
binary scan [binary format c $oldval] B* oldbinNum set currCh [ lindex [sct P_name] $chIndex ]
set oldbitfield [split $oldbinNum ""]
foreach n $nodes b $bitfield ob $oldbitfield {
if {$b != $ob} {
hset $chPath/$n $b
}
}
}
return [sct nextSndReq]
}
##
# Reads a list of values in the result and assigns them to the nodes in the args list
proc rdVal {root nodes} {
set currCh [sct chopper]
set values [sct result] set values [sct result]
set chPath $root/ch$currCh set chPath $root/$currCh
if {[string match "ASCERR:*" $values]} { if {[string match "ASCERR:*" $values]} {
sct geterror $values sct geterror $values
hset $chPath/device_error $values hset $chPath/device_error $values
@@ -102,30 +70,24 @@ proc rdVal {root nodes} {
} }
foreach n $nodes v $values { foreach n $nodes v $values {
set oldval [hval $chPath/$n] set oldval [hval $chPath/$n]
# if {$n == "speed_setpt"} {
# broadcast rdVal,$n $chPath/$n: oldval=$oldval, v=$v
# }
if {$v != $oldval} { if {$v != $oldval} {
# if {$n == "speed_setpt"} {
# broadcast rdVal,$n: hset $chPath/$n $v
# }
hset $chPath/$n $v hset $chPath/$n $v
} }
} }
set nextReq [sct nextSndReq] set nextReq [sct nextSndReq]
if {$nextReq == "NXTCHOPPER"} { if {$nextReq == "NXTCHOPPER"} {
if {$currCh < [sct chMax] } { incr chIndex
incr currCh if {$chIndex < [sct P_numChops] } {
sct chopper $currCh sct P_chIndex $chIndex
} else { } else {
sct chopper 1 sct P_chIndex 0
return idle return idle
} }
} }
return $nextReq return $nextReq
} }
proc rdSetCmdReply {root chPath} { proc rdSetCmdReply {root chPath} {
set reply [sct result] set reply [sct result]
if {[string match "ASCERR:*" $reply]} { if {[string match "ASCERR:*" $reply]} {
sct geterror $reply sct geterror $reply
@@ -137,50 +99,67 @@ proc rdSetCmdReply {root chPath} {
} }
sct_fermi queue $root progress read sct_fermi queue $root progress read
return idle return idle
} }
# Create chopper control
set scobjNS ::scobj::chopper ##
set sim_mode false # @brief Make fermi chopper driver
set pollrate 5 #
MakeSICSObj fermi_chopper SCT_OBJECT user int # @param nm_addr_list, list of chopper names and modbus addresses eg mkChoppers {mch 1 sch 2}
sicslist setatt fermi_chopper klass NXfermi_chopper proc mkChoppers {nm_addr_list} {
set fermiPath /sics/fermi_chopper set scobjNS ::scobj::chopper
::scobj::hinitprops fermi_chopper set pollrate 5
foreach {n a} $nm_addr_list {
lappend chopperName $n
lappend chAddress $a
}
set numChops [llength $chAddress]
MakeSICSObj fermi_chopper SCT_OBJECT
sicslist setatt fermi_chopper klass NXfermi_chopper
variable fermiPath
set fermiPath /sics/fermi_chopper
::scobj::hinitprops fermi_chopper
set sim_mode false
if {$sim_mode == "false"} { if {$sim_mode == "false"} {
makesctcontroller sct_fermi tcpmodbus 137.157.202.213:502 makesctcontroller sct_fermi tcpmodbus 137.157.202.213:502
} }
hsetprop $fermiPath chopper 1 hsetprop $fermiPath P_chIndex 0
set intlck_fields {test_mode cc_shutdown_req dsp_summ_shtdwn cooling_loss spd_sensor_loss ref_sig_loss over_temp vac_fail overspeed_or_breakfail cc_wd_fail ext_fault ups_fail emerg_stop pos_alarm osc_fail dsp_wd_fail}
set intlck_fields {test_mode cc_shutdown_req dsp_summ_shtdwn cooling_loss spd_sensor_loss ref_sig_loss over_temp vac_fail overspeed_or_brakefail cc_wd_fail ext_fault ups_fail emerg_stop pos_alarm osc_fail dsp_wd_fail} hsetprop $fermiPath P_numChops $numChops
hsetprop $fermiPath P_chAddress $chAddress
set chMax 1 hsetprop $fermiPath P_name $chopperName
hsetprop $fermiPath chMax $chMax variable fermiPath
for {set chN 1} {$chN <= $chMax} {incr chN} { foreach {chname chN} $nm_addr_list {
set chname ch$chN # set chname [lindex $chopperName [expr $chN - 1]]
sicslist setatt fermi_chopper klass NXfermi_chopper sicslist setatt fermi_chopper klass NXfermi_chopper
sicslist setatt fermi_chopper long_name fermi_chopper sicslist setatt fermi_chopper long_name fermi_chopper
hfactory $fermiPath/$chname plain user float hfactory $fermiPath/$chname plain user none
set chPath $fermiPath/$chname set chPath $fermiPath/$chname
hfactory $chPath/device_error plain user text hfactory $chPath/device_error plain user text
foreach field { foreach field {
system_status intlck_status rotation_speed rotation_speed phase_veto_count phase_nonveto_count phase_acc phase_rep
phase_veto_count phase_nonveto_count phase_acc phase_ok vetowin100ns vetowin50ns mode speed_setpt
phase_rep phase_ok vetowin100ns prop_gain int_gain phase_gain ref_delay ref_period
vetowin50ns mode speed_setpt sync_srce motdir
prop_gain int_gain phase_gain
ref_delay ref_period sync_srce motdir idle_toggle
} { } {
hfactory $fermiPath/$chname/$field plain user float hfactory $fermiPath/$chname/$field plain user float
} }
hsetprop $chPath/system_status oldval "UNKNOWN"
hsetprop $chPath/intlck_status oldval "UNKNOWN"
hfactory $fermiPath/$chname/idle_toggle plain user int
hsetprop $chPath/idle_toggle P_oldval "UNKNOWN"
hfactory $fermiPath/$chname/system_status plain user none
hsetprop $chPath/system_status P_oldval "UNKNOWN"
foreach field { foreach field {
avc_on motdir phase_locked lev_complete alarm run up_to_speed ok avc_on motdir phase_locked lev_complete alarm run up_to_speed ok
} { } {
hfactory $fermiPath/$chname/system_status/$field plain user int hfactory $fermiPath/$chname/system_status/$field plain user int
} }
hfactory $fermiPath/$chname/intlck_status plain user none
hsetprop $chPath/intlck_status P_oldval "UNKNOWN"
foreach field $intlck_fields { foreach field $intlck_fields {
hfactory $fermiPath/$chname/intlck_status/$field plain user int hfactory $fermiPath/$chname/intlck_status/$field plain user int
} }
@@ -213,37 +192,45 @@ set chname ch$chN
} }
} }
} }
# Each Req chains to a rdVal proc which chains to the next req
# Add a next state property # Each Req chains to a rdVal proc which chains to the next req
# Add a next state property
#TODO Read idle_toggle status #TODO Read idle_toggle status
hsetprop $fermiPath nextSndReq "UNKNOWN" hsetprop $fermiPath nextSndReq "UNKNOWN"
hsetprop $fermiPath read ${scobjNS}::sndMBquery "RDSYSSTAT" "3:10:1:U16" "INTLKREQ" hsetprop $fermiPath read ${scobjNS}::sndMBquery "RDSYSSTAT" "3:10:1:U16" "INTLKREQ"
hsetprop $fermiPath "NXTCHOPPER" ${scobjNS}::sndMBquery "RDSYSSTAT" "3:10:1:U16" "INTLKREQ" hsetprop $fermiPath "NXTCHOPPER" ${scobjNS}::sndMBquery "RDSYSSTAT" "3:10:1:U16" "INTLKREQ"
hsetprop $fermiPath "INTLKREQ" ${scobjNS}::sndMBquery "RDINTLKSTAT" "3:12:1:U16" "ROTSPDREQ" hsetprop $fermiPath "INTLKREQ" ${scobjNS}::sndMBquery "RDINTLKSTAT" "3:12:1:U16" "IDLETOGGLE"
hsetprop $fermiPath "ROTSPDREQ" ${scobjNS}::sndMBquery "RDROTSPD" "3:14:1:U16" "VETOINF" hsetprop $fermiPath "IDLETOGGLE" ${scobjNS}::sndMBquery "RDIDLE" "1:3:1" "VETOINF"
hsetprop $fermiPath "VETOINF" ${scobjNS}::sndMBquery "RDVETOINF" "3:18:2:U32" "PHASEINF" hsetprop $fermiPath "VETOINF" ${scobjNS}::sndMBquery "RDVETOINF" "3:18:2:U32" "PHASEINF"
hsetprop $fermiPath "PHASEINF" ${scobjNS}::sndMBquery "RDPHASEINF" "3:24:3:F32" "VETO" hsetprop $fermiPath "PHASEINF" ${scobjNS}::sndMBquery "RDPHASEINF" "3:24:3:F32" "VETO"
hsetprop $fermiPath "VETO" ${scobjNS}::sndMBquery "RDVETO" "3:30:3:U32" "ROTSPSET" hsetprop $fermiPath "VETO" ${scobjNS}::sndMBquery "RDVETO" "3:30:3:U32" "ROTSPSET"
hsetprop $fermiPath "ROTSPSET" ${scobjNS}::sndMBquery "RDROTSPSET" "3:1000:1:U32" "GAINPHASE" hsetprop $fermiPath "ROTSPSET" ${scobjNS}::sndMBquery "RDROTSPSET" "3:1000:1:U32" "GAINPHASE"
hsetprop $fermiPath "GAINPHASE" ${scobjNS}::sndMBquery "RDGAINPHASE" "3:1004:3:F32" "SYNMOTDIR" hsetprop $fermiPath "GAINPHASE" ${scobjNS}::sndMBquery "RDGAINPHASE" "3:1004:3:F32" "SYNMOTDIR"
hsetprop $fermiPath "SYNMOTDIR" ${scobjNS}::sndMBquery "RDSYNMOTDIR" "3:1010:4:U32" "IDLETOGGLE" hsetprop $fermiPath "SYNMOTDIR" ${scobjNS}::sndMBquery "RDSYNMOTDIR" "3:1010:4:U32" "ROTSPDREQ"
hsetprop $fermiPath "IDLETOGGLE" ${scobjNS}::sndMBquery "RDIDLE" "1:3:1" "NXTCHOPPER" hsetprop $fermiPath "ROTSPDREQ" ${scobjNS}::sndMBquery "RDROTSPD" "3:14:1:U16" "NXTCHOPPER"
hsetprop $fermiPath "RDSYSSTAT" ${scobjNS}::rdStatus $fermiPath system_status {avc_on motdir phase_locked lev_complete alarm run up_to_speed ok} hsetprop $fermiPath "RDSYSSTAT" ${scobjNS}::rdStatus $fermiPath system_status {avc_on motdir phase_locked lev_complete alarm run up_to_speed ok}
hsetprop $fermiPath "RDINTLKSTAT" ${scobjNS}::rdStatus $fermiPath intlck_status $intlck_fields hsetprop $fermiPath "RDINTLKSTAT" ${scobjNS}::rdStatus $fermiPath intlck_status $intlck_fields
hsetprop $fermiPath "RDROTSPD" ${scobjNS}::rdVal $fermiPath rotation_speed hsetprop $fermiPath "RDROTSPD" ${scobjNS}::rdVal $fermiPath rotation_speed
hsetprop $fermiPath "RDVETOINF" ${scobjNS}::rdVal $fermiPath {phase_veto_count phase_nonveto_count} hsetprop $fermiPath "RDIDLE" ${scobjNS}::rdCoil $fermiPath idle_toggle 3
hsetprop $fermiPath "RDPHASEINF" ${scobjNS}::rdVal $fermiPath {phase_acc phase_rep phase_ok} hsetprop $fermiPath "RDPHASEINF" ${scobjNS}::rdVal $fermiPath {phase_acc phase_rep phase_ok}
hsetprop $fermiPath "RDVETO" ${scobjNS}::rdVal $fermiPath {vetowin100ns vetowin50ns mode} hsetprop $fermiPath "RDVETO" ${scobjNS}::rdVal $fermiPath {vetowin100ns vetowin50ns mode}
hsetprop $fermiPath "RDROTSPSET" ${scobjNS}::rdVal $fermiPath speed_setpt hsetprop $fermiPath "RDROTSPSET" ${scobjNS}::rdVal $fermiPath speed_setpt
hsetprop $fermiPath "RDGAINPHASE" ${scobjNS}::rdVal $fermiPath {prop_gain int_gain phase_gain} hsetprop $fermiPath "RDGAINPHASE" ${scobjNS}::rdVal $fermiPath {prop_gain int_gain phase_gain}
hsetprop $fermiPath "RDSYNMOTDIR" ${scobjNS}::rdVal $fermiPath {ref_delay ref_period sync_srce motdir} hsetprop $fermiPath "RDSYNMOTDIR" ${scobjNS}::rdVal $fermiPath {ref_delay ref_period sync_srce motdir}
hsetprop $fermiPath "RDIDLE" ${scobjNS}::rdVal $fermiPath idle_toggle hsetprop $fermiPath "RDVETOINF" ${scobjNS}::rdVal $fermiPath {phase_veto_count phase_nonveto_count}
if {$sim_mode == "false"} { if {$sim_mode == "false"} {
sct_fermi poll $fermiPath $pollrate sct_fermi poll $fermiPath $pollrate
sct_fermi queue $fermiPath progress read sct_fermi queue $fermiPath progress read
} }
return $fermiPath
}
namespace export mkChoppers
} }
namespace import ::scobj::chopper::*
# mkChoppers { mch 1 sch 2 }