package require XOTcl package require BLT package require swt package require usb wm minsize . 900 720 namespace eval ::mca { namespace import ::xotcl::* namespace import ::blt::vector namespace import ::blt::graph namespace import ::blt::tabnotebook proc validate {value} { if {![regexp {^[1-9][0-9]*$} $value]} { return 0 } elseif {$value > 4095} { return 0 } elseif {[string length $value] > 4} { return 0 } else { return 1 } } # ------------------------------------------------------------------------- Class OscDisplay -parameter { {number} {master} } # ------------------------------------------------------------------------- OscDisplay instproc init {} { my instvar data xvec yvec set xvec [vector #auto] set yvec [vector #auto] # fill one vector for the x axis with 1025 points $xvec seq 0 1024 my reset my setup next } # ------------------------------------------------------------------------- OscDisplay instproc destroy {} { next } # ------------------------------------------------------------------------- OscDisplay instproc reset {} { my instvar data xvec yvec dict set data none {} dict set data uwt1 {} dict set data uwt2 {} dict set data uwt3 {} # dict set data sum8 {} $yvec set {} } # ------------------------------------------------------------------------- OscDisplay instproc start {} { my instvar config trace add variable [myvar auto] write [myproc auto_update] trace add variable [myvar thrs] write [myproc thrs_update] trace add variable [myvar fltr_val] write [myproc fltr_val_update] ${config}.thrs_check deselect ${config}.thrs_field set 10 ${config}.none select } # ------------------------------------------------------------------------- OscDisplay instproc setup {} { my instvar number master my instvar data xvec yvec my instvar config auto thrs thrs_val fltr_val my set restart_command [usb::convert 0001000${number}00000000] my set acquire_command [usb::convert 0002000${number}00000000] # create a graph widget and show a grid set graph [graph ${master}.graph -height 250 -leftmargin 80] $graph crosshairs configure -hide no -linewidth 2 -dashes { 1 1 } $graph grid configure -hide no $graph legend configure -hide yes $graph axis configure x -min 0 -max 1024 set config [frame ${master}.config] checkbutton ${config}.auto_check -text {auto update} -variable [myvar auto] frame ${config}.spc1 -width 10 -height 10 checkbutton ${config}.thrs_check -text threshold -variable [myvar thrs] spinbox ${config}.thrs_field -from 1 -to 4095 \ -increment 5 -width 10 -textvariable [myvar thrs_val] \ -validate all -vcmd {::mca::validate %P} frame ${config}.spc2 -width 10 -height 10 label ${config}.fltr -text {low-pass filter} radiobutton ${config}.none -text none -variable [myvar fltr_val] -value none radiobutton ${config}.uwt1 -text uwt1 -variable [myvar fltr_val] -value uwt1 radiobutton ${config}.uwt2 -text uwt2 -variable [myvar fltr_val] -value uwt2 radiobutton ${config}.uwt3 -text uwt3 -variable [myvar fltr_val] -value uwt3 # radiobutton ${config}.sum8 -text sum8 -variable [myvar fltr_val] -value sum8 frame ${config}.spc3 -width 10 -height 10 button ${config}.acquire -text Acquire \ -bg green -activebackground green -command [myproc acquire] button ${config}.restart -text Restart \ -bg yellow -activebackground yellow -command [myproc restart] button ${config}.register -text Register \ -bg lightblue -activebackground lightblue -command [myproc register] grid ${config}.auto_check -sticky w grid ${config}.spc1 grid ${config}.thrs_check -sticky w grid ${config}.thrs_field -sticky ew -pady 1 -padx 5 grid ${config}.spc2 grid ${config}.fltr -sticky w -pady 1 -padx 3 grid ${config}.none -sticky w grid ${config}.uwt1 -sticky w grid ${config}.uwt2 -sticky w grid ${config}.uwt3 -sticky w # grid ${config}.sum8 -sticky w grid ${config}.spc3 grid ${config}.acquire -sticky ew -pady 3 -padx 5 grid ${config}.restart -sticky ew -pady 3 -padx 5 grid ${config}.register -sticky ew -pady 3 -padx 5 grid ${graph} -row 0 -column 0 -sticky news grid ${config} -row 0 -column 1 # enable zooming Blt_ZoomStack $graph #bind .graph {%W crosshairs configure -position @%x,%y} # create one element with data for the x and y axis, no dots $graph element create Spectrum1 -symbol none -xdata $xvec -ydata $yvec } # ------------------------------------------------------------------------- OscDisplay instproc auto_update args { my instvar auto after_handle if {$auto} { ${config}.acquire configure -state disabled ${config}.restart configure -state disabled ${config}.register configure -state disabled my acquire_restart_loop } else { if {[my exists after_handle]} { after cancel $after_handle } ${config}.acquire configure -state active ${config}.restart configure -state active ${config}.register configure -state active } } # ------------------------------------------------------------------------- OscDisplay instproc thrs_update args { my instvar config thrs if {$thrs} { ${config}.thrs_field configure -state normal } else { ${config}.thrs_field configure -state disabled } } # ------------------------------------------------------------------------- OscDisplay instproc fltr_val_update args { my instvar yvec data fltr_val $yvec set [dict get $data $fltr_val] } # ------------------------------------------------------------------------- OscDisplay instproc save_data {data} { set file [tk_getSaveFile] if {[string equal $file {}]} { return } set x [catch {set fid [open $file w+]}] set y [catch {puts $fid $data}] set z [catch {close $fid}] if { $x || $y || $z || ![file exists $file] || ![file isfile $file] || ![file readable $file] } { tk_messageBox -icon error \ -message "An error occurred while writing to \"$file\"" } else { tk_messageBox -icon info \ -message "File \"$file\" written successfully" } } # ------------------------------------------------------------------------- OscDisplay instproc register {} { my save_data [my set data] } # ------------------------------------------------------------------------- OscDisplay instproc send_data {data} { global usb_handle if {[catch {$usb_handle writeRaw $data} result]} { puts {Error during write} puts $result } } # ------------------------------------------------------------------------- OscDisplay instproc restart {} { my instvar restart_command my send_data $restart_command } # ------------------------------------------------------------------------- OscDisplay instproc acquire {} { global usb_handle my instvar xvec yvec data fltr_val my instvar acquire_command my send_data $acquire_command set usb_data {} if {[catch {$usb_handle readHex 2 1024} usb_data]} { puts {Error during read} puts $usb_data set usb_data {} } dict set data none $usb_data dict set data uwt1 [lindex [uwt 1 $usb_data] 1] dict set data uwt2 [lindex [uwt 2 $usb_data] 1] dict set data uwt3 [lindex [uwt 3 $usb_data] 1] # dict set data sum8 [sum8 $usb_data] $yvec set [dict get $data $fltr_val] } # ------------------------------------------------------------------------- OscDisplay instproc acquire_restart_loop {} { my instvar after_handle my acquire my restart set after_handle [after 1000 [myproc acquire_restart_loop]] } # ------------------------------------------------------------------------- Class HstDisplay -parameter { {number} {master} } # ------------------------------------------------------------------------- HstDisplay instproc init {} { my instvar data xvec yvec set xvec [vector #auto] set yvec [vector #auto] # fill one vector for the x axis with 4097 points $xvec seq 0 4096 my reset my setup next } # ------------------------------------------------------------------------- HstDisplay instproc destroy {} { next } # ------------------------------------------------------------------------- HstDisplay instproc reset {} { my instvar data xvec yvec dict set data none {} dict set data uwt1 {} dict set data uwt2 {} dict set data uwt3 {} # dict set data sum8 {} $yvec set {} } # ------------------------------------------------------------------------- HstDisplay instproc start {} { my instvar config peak_mux base_mux set peak_mux 1 set base_mux 0 trace add variable [myvar auto] write [myproc auto_update] trace add variable [myvar peak] write [myproc peak_update] trace add variable [myvar thrs] write [myproc thrs_update] trace add variable [myvar base] write [myproc base_update] trace add variable [myvar base_typ] write [myproc base_typ_update] trace add variable [myvar base_val] write [myproc base_val_update] ${config}.auto_check select ${config}.peak_check select ${config}.thrs_check select ${config}.thrs_field set 10 ${config}.base_check select ${config}.base_const select ${config}.base_field set 35 } # ------------------------------------------------------------------------- HstDisplay instproc setup {} { my instvar number master my instvar data xvec yvec my instvar config auto thrs thrs_val base base_typ base_val my set restart_command [usb::convert 0001001${number}00000000] my set acquire_command [usb::convert 0002001${number}00000000] # create a graph widget and show a grid set graph [graph ${master}.graph -height 250 -leftmargin 80] $graph crosshairs configure -hide no -linewidth 2 -dashes { 1 1 } $graph grid configure -hide no $graph legend configure -hide yes $graph axis configure x -min 0 -max 4096 set config [frame ${master}.config] checkbutton ${config}.auto_check -text {auto update} -variable [myvar auto] frame ${config}.spc1 -width 10 -height 10 checkbutton ${config}.peak_check -text {peak detect} -variable [myvar peak] frame ${config}.spc2 -width 10 -height 10 checkbutton ${config}.thrs_check -text threshold -variable [myvar thrs] spinbox ${config}.thrs_field -from 1 -to 4095 \ -increment 5 -width 10 -textvariable [myvar thrs_val] \ -validate all -vcmd {::mca::validate %P} frame ${config}.spc3 -width 10 -height 10 checkbutton ${config}.base_check -text baseline -variable [myvar base] radiobutton ${config}.base_auto -text automatic -variable [myvar base_typ] -value auto radiobutton ${config}.base_const -text constant -variable [myvar base_typ] -value const spinbox ${config}.base_field -from 1 -to 4095 \ -increment 5 -width 10 -textvariable [myvar base_val] \ -validate all -vcmd {::mca::validate %P} frame ${config}.spc4 -width 10 -height 10 button ${config}.acquire -text Acquire \ -bg green -activebackground green -command [myproc acquire] button ${config}.restart -text Restart \ -bg yellow -activebackground yellow -command [myproc restart] button ${config}.register -text Register \ -bg lightblue -activebackground lightblue -command [myproc register] grid ${config}.auto_check -sticky w grid ${config}.spc1 grid ${config}.peak_check -sticky w grid ${config}.spc2 grid ${config}.thrs_check -sticky w grid ${config}.thrs_field -sticky ew -pady 1 -padx 5 grid ${config}.spc3 grid ${config}.base_check -sticky w grid ${config}.base_auto -sticky w grid ${config}.base_const -sticky w grid ${config}.base_field -sticky ew -pady 1 -padx 5 grid ${config}.spc4 grid ${config}.acquire -sticky ew -pady 3 -padx 5 grid ${config}.restart -sticky ew -pady 3 -padx 5 grid ${config}.register -sticky ew -pady 3 -padx 5 grid ${graph} -row 0 -column 0 -sticky news grid ${config} -row 0 -column 1 # enable zooming Blt_ZoomStack $graph #bind .graph {%W crosshairs configure -position @%x,%y} # create one element with data for the x and y axis, no dots $graph element create Spectrum1 -symbol none -smooth step -xdata $xvec -ydata $yvec } # ------------------------------------------------------------------------- HstDisplay instproc auto_update args { my instvar auto after_handle my instvar config if {$auto} { ${config}.acquire configure -state disabled ${config}.register configure -state disabled my acquire_loop } else { if {[my exists after_handle]} { after cancel $after_handle } ${config}.acquire configure -state active ${config}.register configure -state active } } # ------------------------------------------------------------------------- HstDisplay instproc mux {} { my instvar peak_mux base_mux format {%x%x%x%x} $base_mux $peak_mux 0 0 } # ------------------------------------------------------------------------- HstDisplay instproc peak_update args { my instvar number peak peak_mux set mux_addr [format %04x [expr {20 + ${number}}]] if {$peak} { set peak_mux 1 my send_data [usb::convert ${mux_addr}[my mux]00000000] } else { set peak_mux 0 my send_data [usb::convert ${mux_addr}[my mux]00000000] } } # ------------------------------------------------------------------------- HstDisplay instproc thrs_update args { my instvar config number thrs thrs_val set val_addr [format %04x [expr {14 + ${number}}]] set value [format %04x $thrs_val] if {$thrs} { ${config}.thrs_field configure -state normal my send_data [usb::convert ${val_addr}${value}00000000] } else { ${config}.thrs_field configure -state disabled my send_data [usb::convert ${val_addr}000000000000] } } # ------------------------------------------------------------------------- HstDisplay instproc thrs_val_update args { my instvar config number thrs_val set val_addr [format %04x [expr {14 + ${number}}]] set value [format %04x $thrs_val] ${config}.base_field configure -state normal my send_data [usb::convert ${val_addr}${value}00000000] } # ------------------------------------------------------------------------- HstDisplay instproc base_update args { my instvar config number base base_val base_mux set mux_addr [format %04x [expr {20 + ${number}}]] set val_addr [format %04x [expr {11 + ${number}}]] if {$base} { ${config}.base_auto configure -state normal ${config}.base_const configure -state normal my base_typ_update } else { ${config}.base_auto configure -state disabled ${config}.base_const configure -state disabled ${config}.base_field configure -state disabled set base_mux 0 my send_data [usb::convert ${mux_addr}[my mux]00000000${val_addr}000000000000] } } # ------------------------------------------------------------------------- HstDisplay instproc base_typ_update args { my instvar config number base_typ base_val base_mux set mux_addr [format %04x [expr {20 + ${number}}]] set val_addr [format %04x [expr {11 + ${number}}]] set value [format %04x $base_val] switch -- $base_typ { auto { ${config}.base_field configure -state disabled set base_mux 1 my send_data [usb::convert ${mux_addr}[my mux]00000000] } const { ${config}.base_field configure -state normal set base_mux 0 my send_data [usb::convert ${mux_addr}[my mux]00000000${val_addr}${value}00000000] } } } # ------------------------------------------------------------------------- HstDisplay instproc base_val_update args { my instvar number base_val set val_addr [format %04x [expr {11 + ${number}}]] set value [format %04x $base_val] my send_data [usb::convert ${val_addr}${value}00000000] } # ------------------------------------------------------------------------- HstDisplay instproc save_data {data} { set file [tk_getSaveFile] if {[string equal $file {}]} { return } set x [catch {set fid [open $file w+]}] set y [catch {puts $fid $data}] set z [catch {close $fid}] if { $x || $y || $z || ![file exists $file] || ![file isfile $file] || ![file readable $file] } { tk_messageBox -icon error \ -message "An error occurred while writing to \"$file\"" } else { tk_messageBox -icon info \ -message "File \"$file\" written successfully" } } # ------------------------------------------------------------------------- HstDisplay instproc register {} { my save_data [my set data] } # ------------------------------------------------------------------------- HstDisplay instproc send_data {data} { global usb_handle if {[catch {$usb_handle writeRaw $data} result]} { puts {Error during write} puts $result } } # ------------------------------------------------------------------------- HstDisplay instproc restart {} { my instvar restart_command my send_data $restart_command } # ------------------------------------------------------------------------- HstDisplay instproc acquire {} { global usb_handle my instvar xvec yvec data fltr_val my instvar acquire_command my send_data $acquire_command set usb_data {} if {[catch {$usb_handle readHex 4 4096} usb_data]} { puts {Error during read} puts $usb_data set usb_data {} } set data $usb_data $yvec set $usb_data } # ------------------------------------------------------------------------- HstDisplay instproc acquire_loop {} { my instvar after_handle my acquire set after_handle [after 1000 [myproc acquire_loop]] } # ------------------------------------------------------------------------- namespace export HstDisplay namespace export OscDisplay } set notebook [::blt::tabnotebook .notebook -side bottom] pack $notebook -expand 1 -fill both set window [frame ${notebook}.hst_2] $notebook insert end -text "Histogram" -window $window -fill both ::mca::HstDisplay hst_2 -number 2 -master $window grid rowconfigure $window 0 -weight 1 grid columnconfigure $window 0 -weight 1 grid columnconfigure $window 1 -weight 0 -minsize 80 set window [frame ${notebook}.osc_2] $notebook insert end -text "Pulse shape" -window $window -fill both ::mca::OscDisplay osc_2 -number 2 -master $window grid rowconfigure $window 0 -weight 1 grid columnconfigure $window 0 -weight 1 grid columnconfigure $window 1 -weight 0 -minsize 80 set usb_handle {} while {[catch {usb::connect 0x09FB 0x6001 1 1 0} usb_handle]} { set answer [tk_messageBox -icon error -type retrycancel \ -message {Cannot access USB device} -detail $usb_handle] if {[string equal $answer cancel]} break } hst_2 restart osc_2 restart hst_2 start osc_2 start # configure polarity # set polarity_command [usb::convert 000A011100000000] set polarity_command [usb::convert 000A001100000000] if {[catch {$usb_handle writeRaw $polarity_command} result]} { puts {Error during write} puts $result } hst_2 restart osc_2 restart