package require XOTcl package require BLT package require swt package require usb package require zlib wm minsize . 1000 700 namespace eval ::mca { namespace import ::xotcl::* namespace import ::blt::vector namespace import ::blt::graph namespace import ::blt::tabnotebook # ------------------------------------------------------------------------- variable oscCodes array set oscCodes { 1 {Channel 1} 2 {Channel 2} 3 {Channel 3} 4 {Channel 4} 5 {Channel 5} 6 {Trigger} } # ------------------------------------------------------------------------- variable adcCodes array set adcCodes { 1 {ADC 1} 2 {ADC 2} 3 {ADC 3} 4 {ADC 4} 5 {ADC 5} 6 {ADC 6} 7 {ADC 7} 8 {ADC 8} 9 {ADC 9} 10 {ADC 10} 11 {ADC 11} 12 {ADC 12} } # ------------------------------------------------------------------------- variable inpCodes array set inpCodes { 0 {r} 1 {f} 2 {d} 3 {c} } # ------------------------------------------------------------------------- proc validate {max size value} { if {![regexp {^[0-9]*$} $value]} { return 0 } elseif {[regexp {^0[0-9]+$} $value]} { return 0 } elseif {$value > $max} { return 0 } elseif {[string length $value] > $size} { return 0 } else { return 1 } } # ------------------------------------------------------------------------- proc doublevalidate {max value} { if {![regexp {^[0-9]{0,2}\.?[0-9]{0,3}$} $value]} { return 0 } elseif {[regexp {^0[0-9]+$} $value]} { return 0 } elseif {$value > $max} { return 0 } else { return 1 } } # ------------------------------------------------------------------------- proc legendLabel {master row key title} { label ${master}.${key}_label -anchor w -text ${title} label ${master}.${key}_value -width 10 -anchor e -text {} grid ${master}.${key}_label -row ${row} -column 1 -sticky w grid ${master}.${key}_value -row ${row} -column 2 -sticky ew } # ------------------------------------------------------------------------- proc legendButton {master row key title var bg {fg black}} { checkbutton ${master}.${key}_check -variable $var label ${master}.${key}_label -anchor w -text ${title} -bg ${bg} -fg $fg label ${master}.${key}_value -width 10 -anchor e -text {} -bg ${bg} -fg $fg grid ${master}.${key}_check -row ${row} -column 0 -sticky w grid ${master}.${key}_label -row ${row} -column 1 -sticky w grid ${master}.${key}_value -row ${row} -column 2 -sticky ew } # ------------------------------------------------------------------------- Class UsbController # ------------------------------------------------------------------------- UsbController instproc usbConnect {} { my instvar handle puts usbConnect if {[my exists handle]} { $handle disconnect unset handle } if {1} { while {[catch {usb::connect 0x09FB 0x6001 1 1 0} result]} { set answer [tk_messageBox -icon error -type retrycancel \ -message {Cannot access USB device} -detail $result] # puts $result if {[string equal $answer cancel]} exit } set handle $result } } # ------------------------------------------------------------------------- UsbController instproc usbHandle {} { my instvar handle if {[my exists handle]} { return $handle } else { my usbConnect } } # ------------------------------------------------------------------------- UsbController instproc usbCmd {command} { set code [catch {[my usbHandle] writeRaw [usb::convert $command]} result] switch -- $code { 1 { # puts $result my usbConnect } } } # ------------------------------------------------------------------------- UsbController instproc usbCmdReadRaw {command size data} { my usbCmd $command set code [catch {[my usbHandle] readRaw $size} result] switch -- $code { 0 { set $data $result } 1 { # puts $result my usbConnect } 5 { # puts Busy } } } # ------------------------------------------------------------------------- UsbController instproc usbCmdReadRaw {command size data} { my usbCmd $command set code [catch {[my usbHandle] readRaw $size} result] switch -- $code { 0 { set $data $result } 1 { # puts $result my usbConnect } 5 { # puts Busy } } } # ------------------------------------------------------------------------- UsbController instproc usbCmdReadHex {command width size data} { my usbCmd $command set code [catch {[my usbHandle] readHex $width $size} result] switch -- $code { 0 { set $data $result } 1 { # puts $result my usbConnect } 5 { # puts Busy } } } # ------------------------------------------------------------------------- Class SpiDisplay -parameter { {master} {controller} } # ------------------------------------------------------------------------- SpiDisplay instproc init {} { my setup next } # ------------------------------------------------------------------------- SpiDisplay instproc destroy {} { next } # ------------------------------------------------------------------------- SpiDisplay instproc start {} { my instvar config trace add variable [myvar dac1] write [myproc dac1_update] trace add variable [myvar dac2] write [myproc dac2_update] ${config(1)}.dac1 set 0 ${config(1)}.dac2 set 0 } # ------------------------------------------------------------------------- SpiDisplay instproc setup {} { my instvar number master my instvar config set config(1) [labelframe ${master}.cfg1 -borderwidth 1 -relief sunken -text {DAC}] frame ${config(1)}.limits label ${config(1)}.limits.min -text {2.5V} label ${config(1)}.limits.max -text {0.0V} scale ${config(1)}.dac1 -orient vertical -from 4095 -to 0 -tickinterval 0 -variable [myvar dac1] scale ${config(1)}.dac2 -orient vertical -from 4095 -to 0 -tickinterval 0 -variable [myvar dac2] pack ${config(1)}.limits.min -anchor n -side top -pady 10 pack ${config(1)}.limits.max -anchor s -side bottom -pady 9 grid ${config(1)}.dac1 ${config(1)}.dac2 ${config(1)}.limits -sticky ns -pady 7 set config(2) [labelframe ${master}.cfg2 -borderwidth 1 -relief sunken -text {ADC}] frame ${config(2)}.spc1 -width 130 -height 10 frame ${config(2)}.spc2 -width 130 -height 10 frame ${config(2)}.spc3 -width 130 -height 10 button ${config(2)}.reset -text {Reset} -command [myproc adc_reset] button ${config(2)}.pattern -text {Test pattern} -command [myproc adc_pattern] button ${config(2)}.ramp -text {Test ramp} -command [myproc adc_ramp] button ${config(2)}.100mV -text {Test 100 mV} -command [myproc adc_100mV] button ${config(2)}.150mV -text {Test 150 mV} -command [myproc adc_150mV] button ${config(2)}.fltr0 -text {Filter 14MHz} -command [myproc adc_fltr0] button ${config(2)}.fltr1 -text {Filter 10MHz} -command [myproc adc_fltr1] button ${config(2)}.fltr2 -text {Filter 7.5MHz} -command [myproc adc_fltr2] grid ${config(2)}.spc1 grid ${config(2)}.reset -sticky ew -pady 3 -padx 5 grid ${config(2)}.spc2 grid ${config(2)}.pattern -sticky ew -pady 3 -padx 5 grid ${config(2)}.ramp -sticky ew -pady 3 -padx 5 grid ${config(2)}.100mV -sticky ew -pady 3 -padx 5 grid ${config(2)}.150mV -sticky ew -pady 3 -padx 5 grid ${config(2)}.spc3 grid ${config(2)}.fltr0 -sticky ew -pady 3 -padx 5 grid ${config(2)}.fltr1 -sticky ew -pady 3 -padx 5 grid ${config(2)}.fltr2 -sticky ew -pady 3 -padx 5 grid ${config(1)} -row 1 -column 1 -sticky ns grid ${config(2)} -row 1 -column 2 -sticky ns grid columnconfigure ${master} 0 -weight 1 grid columnconfigure ${master} 1 -weight 1 grid columnconfigure ${master} 2 -weight 1 grid columnconfigure ${master} 3 -weight 1 grid rowconfigure ${master} 0 -weight 0 grid rowconfigure ${master} 1 -weight 1 grid rowconfigure ${master} 2 -weight 0 grid rowconfigure ${config(1)} 0 -weight 1 } # ------------------------------------------------------------------------- SpiDisplay instproc dac1_update args { my instvar controller dac1 set value [format {3%03x} $dac1] set prefix [format {%x} 12] set command {} append command 0001${prefix}00000020000000402[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 3]00 $controller usbCmd $command } # ------------------------------------------------------------------------- SpiDisplay instproc dac2_update args { my instvar controller dac2 set value [format {b%03x} $dac1] set prefix [format {%x} 12] set command {} append command 0001${prefix}00000020000000402[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 3]00 $controller usbCmd $command } # ------------------------------------------------------------------------- SpiDisplay instproc adc_reset args { my instvar controller set prefix [format {%x} 12] set command {} set value {000001} append command 0001${prefix}00000020000000401[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 5] set value {040008} append command 0001${prefix}00000020000000401[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 5] $controller usbCmd $command } # ------------------------------------------------------------------------- SpiDisplay instproc adc_pattern args { my instvar controller set value {022000} set prefix [format {%x} 12] set command {} append command 0001${prefix}00000020000000401[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 5] $controller usbCmd $command } # ------------------------------------------------------------------------- SpiDisplay instproc adc_ramp args { my instvar controller set value {02E000} set prefix [format {%x} 12] set command {} append command 0001${prefix}00000020000000401[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 5] $controller usbCmd $command } # ------------------------------------------------------------------------- SpiDisplay instproc adc_100mV args { my instvar controller set value {070080} set prefix [format {%x} 12] set command {} append command 0001${prefix}00000020000000401[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 5] $controller usbCmd $command } # ------------------------------------------------------------------------- SpiDisplay instproc adc_150mV args { my instvar controller set value {070180} set prefix [format {%x} 12] set command {} append command 0001${prefix}00000020000000401[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 5] $controller usbCmd $command } # ------------------------------------------------------------------------- SpiDisplay instproc adc_fltr0 args { my instvar controller set value {070000} set prefix [format {%x} 12] set command {} append command 0001${prefix}00000020000000401[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 5] $controller usbCmd $command } # ------------------------------------------------------------------------- SpiDisplay instproc adc_fltr1 args { my instvar controller set value {070004} set prefix [format {%x} 12] set command {} append command 0001${prefix}00000020000000401[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 5] $controller usbCmd $command } # ------------------------------------------------------------------------- SpiDisplay instproc adc_fltr2 args { my instvar controller set value {070008} set prefix [format {%x} 12] set command {} append command 0001${prefix}00000020000000401[string range $value 0 1] append command 0001${prefix}000000200000004[string range $value 2 5] $controller usbCmd $command } # ------------------------------------------------------------------------- Class MuxDisplay -parameter { {master} {controller} } # ------------------------------------------------------------------------- MuxDisplay instproc init {} { my setup next } # ------------------------------------------------------------------------- MuxDisplay instproc destroy {} { next } # ------------------------------------------------------------------------- MuxDisplay instproc start {} { variable adcCodes my instvar config chan_val set chan_val(1) 0 set chan_val(2) 0 set chan_val(3) 0 set chan_val(4) 0 set chan_val(5) 0 set chan_val(6) 0 trace add variable [myvar chan_val] write [myproc chan_val_update] trace add variable [myvar polar] write [myproc polar_update] $config(1).chan_0_1 select $config(2).chan_0_2 select $config(3).chan_0_3 select $config(4).chan_0_4 select $config(5).chan_0_5 select $config(6).chan_0_1 select foreach {ch dummy} [array get adcCodes] { $config(inv).polar_${ch} deselect } } # ------------------------------------------------------------------------- MuxDisplay instproc setup {} { variable oscCodes variable adcCodes variable inpCodes my instvar master my instvar config set size [array size inpCodes] set oscList [array get oscCodes] set adcList [array get adcCodes] set inpList [array get inpCodes] set mux [frame ${master}.mux] set key [frame ${master}.key] set inv [frame ${master}.inv] foreach {osc title} $oscList { set config($osc) [labelframe ${mux}.$osc -borderwidth 1 -relief sunken -text $title] set column 1 foreach {code input} $inpList { label $config($osc).input_${input} -text " ${input}" grid $config($osc).input_${input} -row 0 -column ${column} -sticky w incr column } foreach {ch dummy} $adcList { label $config($osc).chan_${ch} -text "${ch} " grid $config($osc).chan_${ch} -row ${ch} -column 0 -sticky ew foreach {code input} $inpList { set column [expr {$code + 1}] set value [expr {$size * ($ch - 1) + $code}] radiobutton $config($osc).chan_${code}_${ch} -variable [myvar chan_val($osc)] -value ${value} grid $config($osc).chan_${code}_${ch} -row ${ch} -column ${column} -sticky w } } set column [expr {($osc - 1) % 6}] set row [expr {($osc - 1) / 6}] grid $config($osc) -row ${row} -column ${column} -sticky news -padx 10 } set config(key) [labelframe ${key}.frame -borderwidth 1 -relief sunken -text {legend}] label $config(key).r -text "r - raw signal" grid $config(key).r -row 0 -column 0 -sticky news label $config(key).f -text "f - filtered signal" grid $config(key).f -row 0 -column 1 -sticky news label $config(key).d -text "d - deconvoluted signal" grid $config(key).d -row 0 -column 2 -sticky news label $config(key).c -text "c - clipped signal" grid $config(key).c -row 0 -column 3 -sticky news grid $config(key) -row 0 -column 0 -sticky news -padx 10 set config(inv) [labelframe ${inv}.frame -borderwidth 1 -relief sunken -text {polarity inversion}] label $config(inv).chan_label -text "channel " grid $config(inv).chan_label -row 0 -column 0 -sticky e label $config(inv).polar_label -text "polarity" grid $config(inv).polar_label -row 1 -column 0 -sticky e foreach {ch dummy} $adcList { label $config(inv).chan_${ch} -text "${ch} " grid $config(inv).chan_${ch} -row 0 -column ${ch} -sticky ew checkbutton $config(inv).polar_${ch} -variable [myvar polar($ch)] grid $config(inv).polar_${ch} -row 1 -column ${ch} -sticky w } grid $config(inv) -row 0 -column 0 -sticky news -padx 10 grid ${key} -row 0 -column 0 -sticky news grid ${mux} -row 1 -column 0 -sticky news grid ${inv} -row 2 -column 0 -sticky news grid columnconfigure ${master} 0 -weight 1 grid rowconfigure ${master} 0 -weight 1 grid rowconfigure ${master} 1 -weight 1 grid rowconfigure ${master} 2 -weight 1 grid columnconfigure ${inv} 0 -weight 1 grid columnconfigure ${key} 0 -weight 1 grid columnconfigure $config(key) 0 -weight 1 grid columnconfigure $config(key) 1 -weight 1 grid columnconfigure $config(key) 2 -weight 1 grid columnconfigure $config(key) 3 -weight 1 grid columnconfigure ${mux} 0 -weight 1 grid columnconfigure ${mux} 1 -weight 1 grid columnconfigure ${mux} 2 -weight 1 grid columnconfigure ${mux} 3 -weight 1 grid columnconfigure ${mux} 4 -weight 1 grid columnconfigure ${mux} 5 -weight 1 } # ------------------------------------------------------------------------ MuxDisplay instproc chan_val_update args { my instvar controller chan_val set byte1 [format {%02x%02x} $chan_val(2) $chan_val(1)] set byte2 [format {%02x%02x} $chan_val(4) $chan_val(3)] set byte3 [format {%02x%02x} $chan_val(6) $chan_val(5)] $controller usbCmd 000200020004${byte1}000200030004${byte2}000200040004${byte3} } # ------------------------------------------------------------------------- MuxDisplay instproc polar_update args { my instvar controller polar set value {0b} for {set i 12} {$i >= 1} {incr i -1} { append value $polar($i) } set value [format {%04x} $value] $controller usbCmd 000200010004${value} } # ------------------------------------------------------------------------- Class HstDisplay -parameter { {number} {master} {controller} } # ------------------------------------------------------------------------- HstDisplay instproc init {} { my set data {} vector create [myvar xvec](4096) vector create [myvar yvec](4096) # fill one vector for the x axis with 4096 points [myvar xvec] seq -0.5 4095.5 my setup next } # ------------------------------------------------------------------------- HstDisplay instproc destroy {} { next } # ------------------------------------------------------------------------- HstDisplay instproc start {} { my instvar config trace add variable [myvar data] write [myproc data_update] trace add variable [myvar cntr_val] write [myproc cntr_val_update] trace add variable [myvar rate_val] write [myproc rate_val_update] trace add variable [myvar axis] write [myproc axis_update] trace add variable [myvar thrs] write [myproc thrs_update] trace add variable [myvar thrs_val] 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}.axis_check select ${config}.thrs_check select ${config}.thrs_field set 25 ${config}.base_auto select ${config}.base_field set 20 ${config}.base_check select set cntr_tmp 1200000000 my set cntr_val $cntr_tmp my set cntr_bak $cntr_tmp my set cntr_old $cntr_tmp my set yvec_bak 0.0 my set yvec_old 0.0 my set rate_val(inst) 0.0 my set rate_val(mean) 0.0 # my cntr_reset } # ------------------------------------------------------------------------- HstDisplay instproc setup {} { my instvar number master my instvar xvec yvec graph my instvar config thrs thrs_val base base_typ base_val my instvar cntr_h cntr_m cntr_s # create a graph widget and show a grid set graph [graph ${master}.graph -height 250 -leftmargin 80] $graph crosshairs configure -hide no -linewidth 1 -color darkblue -dashes {2 2} $graph grid configure -hide no $graph legend configure -hide yes $graph axis configure x -min 0 -max 4096 set config [frame ${master}.config -width 170] checkbutton ${config}.axis_check -text {log scale} -variable [myvar axis] frame ${config}.spc1 -width 170 -height 30 frame ${config}.rate_frame -borderwidth 0 -width 170 legendLabel ${config}.rate_frame 0 inst {Inst. rate, 1/s} legendLabel ${config}.rate_frame 1 mean {Avg. rate, 1/s} frame ${config}.spc2 -width 170 -height 30 frame ${config}.chan_frame -borderwidth 0 -width 170 legendLabel ${config}.chan_frame 0 axisy {Bin entries} legendLabel ${config}.chan_frame 1 axisx {Bin number} frame ${config}.spc3 -width 170 -height 30 frame ${config}.cntr_frame -borderwidth 0 -width 170 label ${config}.cntr_frame.h -width 3 -anchor w -text {h} entry ${config}.cntr_frame.h_field -width 3 -textvariable [myvar cntr_h] \ -validate all -vcmd {::mca::validate 999 3 %P} label ${config}.cntr_frame.m -width 3 -anchor w -text {m} entry ${config}.cntr_frame.m_field -width 3 -textvariable [myvar cntr_m] \ -validate all -vcmd {::mca::validate 59 2 %P} label ${config}.cntr_frame.s -width 3 -anchor w -text {s} entry ${config}.cntr_frame.s_field -width 6 -textvariable [myvar cntr_s] \ -validate all -vcmd {::mca::doublevalidate 59.999 %P} grid ${config}.cntr_frame.h_field ${config}.cntr_frame.h \ ${config}.cntr_frame.m_field ${config}.cntr_frame.m ${config}.cntr_frame.s_field ${config}.cntr_frame.s frame ${config}.spc4 -width 170 -height 10 button ${config}.start -text Start \ -bg yellow -activebackground yellow -command [myproc cntr_start] button ${config}.reset -text Reset \ -bg red -activebackground red -command [myproc cntr_reset] frame ${config}.spc5 -width 170 -height 30 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 4095 4 %P} frame ${config}.spc6 -width 170 -height 30 checkbutton ${config}.base_check -text baseline -variable [myvar base] radiobutton ${config}.base_auto -text automatic -variable [myvar base_typ] -value 1 radiobutton ${config}.base_const -text constant -variable [myvar base_typ] -value 0 spinbox ${config}.base_field -from 1 -to 4095 \ -increment 5 -width 10 -textvariable [myvar base_val] \ -validate all -vcmd {::mca::validate 4095 4 %P} frame ${config}.spc7 -width 170 -height 30 button ${config}.register -text Register \ -bg lightblue -activebackground lightblue -command [myproc register] grid ${config}.axis_check -sticky w grid ${config}.spc1 grid ${config}.rate_frame -sticky ew -padx 5 grid ${config}.spc2 grid ${config}.chan_frame -sticky ew -padx 5 grid ${config}.spc3 grid ${config}.cntr_frame -sticky ew -padx 5 grid ${config}.spc4 grid ${config}.start -sticky ew -pady 3 -padx 5 grid ${config}.reset -sticky ew -pady 3 -padx 5 grid ${config}.spc5 grid ${config}.thrs_check -sticky w grid ${config}.thrs_field -sticky ew -pady 1 -padx 5 grid ${config}.spc6 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}.spc7 grid ${config}.register -sticky ew -pady 3 -padx 5 grid ${graph} -row 0 -column 0 -sticky news grid ${config} -row 0 -column 1 grid rowconfigure ${master} 0 -weight 1 grid columnconfigure ${master} 0 -weight 1 grid columnconfigure ${master} 1 -weight 0 -minsize 80 grid columnconfigure ${config}.rate_frame 1 -weight 1 grid columnconfigure ${config}.chan_frame 1 -weight 1 # enable zooming Blt_ZoomStack $graph my crosshairs $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 -color blue -linewidth 2 -symbol none -smooth step -xdata [myvar xvec] -ydata [myvar yvec] } # ------------------------------------------------------------------------- HstDisplay instproc coor_update {W x y} { my instvar config graph $W crosshairs configure -position @${x},${y} set index [$W axis invtransform x $x] set index [::tcl::mathfunc::round $index] catch { ${config}.chan_frame.axisy_value configure -text [[myvar yvec] index $index] ${config}.chan_frame.axisx_value configure -text ${index}.0 } } # ------------------------------------------------------------------------- HstDisplay instproc crosshairs {graph} { set method [myproc coor_update] bind $graph [list [self] coor_update %W %x %y] bind $graph { %W crosshairs off } bind $graph { %W crosshairs on } } # ------------------------------------------------------------------------- HstDisplay instproc axis_update args { my instvar axis graph if {$axis} { $graph axis configure y -min 1 -max 1E10 -logscale yes } else { $graph axis configure y -min {} -max {} -logscale no } } # ------------------------------------------------------------------------- HstDisplay instproc thrs_update args { my instvar controller config number thrs thrs_val if {[string equal $thrs_val {}]} { set thrs_val 0 } set val_addr [format %02x [expr {6 + 2 * ${number}}]] if {$thrs} { ${config}.thrs_field configure -state normal set value [format %03x $thrs_val] } else { ${config}.thrs_field configure -state disabled set value 000 } $controller usbCmd 000200${val_addr}00040${value} } # ------------------------------------------------------------------------- HstDisplay instproc base_update args { my instvar controller config number base base_typ set val_addr [format %02x [expr {7 + 2 * ${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 $controller usbCmd 000200${val_addr}0004${base_typ}000 } } # ------------------------------------------------------------------------- HstDisplay instproc base_typ_update args { my instvar config base_typ switch -- $base_typ { 1 { ${config}.base_field configure -state disabled } 0 { ${config}.base_field configure -state normal } } my base_val_update } # ------------------------------------------------------------------------- HstDisplay instproc base_val_update args { my instvar controller number base_typ base_val if {[string equal $base_val {}]} { set base_val 0 } set val_addr [format %02x [expr {7 + 2 * ${number}}]] set value [format %03x $base_val] $controller usbCmd 000200${val_addr}0004${base_typ}${value} } # ------------------------------------------------------------------------- HstDisplay instproc rate_val_update {name key op} { my instvar config rate_val ${config}.rate_frame.${key}_value configure -text [format {%.2e} $rate_val(${key})] } # ------------------------------------------------------------------------- HstDisplay instproc cntr_val_update args { my instvar cntr_val cntr_h cntr_m cntr_s set cntr_tmp [expr {${cntr_val}/20000}] set cntr_h [expr {${cntr_tmp}/3600000}] set cntr_m [expr {${cntr_tmp}%3600000/60000}] set cntr_s [expr {${cntr_tmp}%3600000%60000/1000.0}] } # ------------------------------------------------------------------------- HstDisplay instproc cntr_setup {} { my instvar controller number cntr_val set word0 [format %08x [expr {${cntr_val} & 0xFFFFFFFF}]] set word1 [format %08x [expr {${cntr_val} >> 32}]] set prefix [format %x [expr {5 + ${number}}]] set command {} append command 0001${prefix}000000200000004[string range $word0 4 7] append command 0001${prefix}000000200010004[string range $word0 0 3] append command 0001${prefix}000000200020004[string range $word1 4 7] append command 0001${prefix}000000200030004[string range $word1 0 3] # send counter value $controller usbCmd $command # load counter value # set val_addr [format %02x [expr {12 + ${number}}]] # $controller usbCmd 000200${val_addr}00040001000200${val_addr}00040000 } # ------------------------------------------------------------------------- HstDisplay instproc cntr_reset {} { my instvar controller number after_handle my instvar cntr_val cntr_bak cntr_old yvec_bak yvec_old my cntr_stop set value [format %04x [expr {1 << (5 + ${number})}]] $controller usbCmd 000200000004${value}0002000000040000 set cntr_val $cntr_bak my cntr_setup set cntr_old $cntr_bak set yvec_bak 0.0 set yvec_old 0.0 my acquire my cntr_ready } # ------------------------------------------------------------------------- HstDisplay instproc cntr_ready {} { my instvar config cntr_val cntr_bak set cntr_val $cntr_bak ${config}.start configure -text Start -command [myproc cntr_start] ${config}.reset configure -state active ${config}.cntr_frame.h_field configure -state normal ${config}.cntr_frame.m_field configure -state normal ${config}.cntr_frame.s_field configure -state normal } # ------------------------------------------------------------------------- HstDisplay instproc cntr_start {} { my instvar config my instvar cntr_h cntr_m cntr_s my instvar cntr_val cntr_bak cntr_old yvec_bak yvec_old set h $cntr_h set m $cntr_m set s $cntr_s if {[string equal $h {}]} { set h 0 } if {[string equal $m {}]} { set m 0 } if {[string equal $s {}]} { set s 0 } set cntr_tmp [expr {${h}*3600000 + ${m}*60000 + ${s}*1000}] set cntr_tmp [expr {entier(20000 * ${cntr_tmp})}] if {$cntr_tmp > 0} { ${config}.cntr_frame.h_field configure -state disabled ${config}.cntr_frame.m_field configure -state disabled ${config}.cntr_frame.s_field configure -state disabled set cntr_val $cntr_tmp set cntr_bak $cntr_tmp set cntr_old $cntr_tmp set yvec_bak [usb::integrateBlt [myvar yvec] 0] set yvec_old $yvec_bak my cntr_setup my cntr_resume } } # ------------------------------------------------------------------------- HstDisplay instproc cntr_pause {} { my instvar config my cntr_stop ${config}.start configure -text Resume -command [myproc cntr_resume] # ${config}.reset configure -state active } # ------------------------------------------------------------------------- HstDisplay instproc cntr_resume {} { my instvar controller config number auto set val_addr [format %02x [expr {13 + ${number}}]] ${config}.start configure -text Pause -command [myproc cntr_pause] # ${config}.reset configure -state disabled $controller usbCmd 000200${val_addr}00040002 set auto 1 after 100 [myproc acquire_loop] } # ------------------------------------------------------------------------- HstDisplay instproc cntr_stop {} { my instvar controller config number auto set val_addr [format %02x [expr {13 + ${number}}]] $controller usbCmd 000200${val_addr}00040000 set auto 0 } # ------------------------------------------------------------------------- HstDisplay instproc data_update args { my instvar data usb::convertBlt $data 4 [myvar yvec] } # ------------------------------------------------------------------------- HstDisplay instproc acquire_loop {} { my instvar cntr_val auto my acquire if {$cntr_val == 0} { my cntr_stop my cntr_ready } elseif {$auto} { after 1000 [myproc acquire_loop] } } # ------------------------------------------------------------------------- HstDisplay instproc acquire {} { my instvar controller config number my instvar cntr_val cntr_bak cntr_old yvec_bak yvec_old rate_val set size 4096 set prefix [format {%x} [expr {$number + 2}]] set value [format {%08x} [expr {$size * 2}]] set command 0001${prefix}000000200000001[string range $value 0 3]0003[string range $value 4 7]00050000 $controller usbCmdReadRaw $command [expr {$size * 4}] [myvar data] set yvec_new [usb::integrateBlt [myvar yvec]] set prefix [format {%x} [expr {$number + 5}]] set command 0001${prefix}000000200000003000400050000 $controller usbCmdReadHex $command 8 1 [myvar cntr_val] set cntr_new $cntr_val if {$cntr_new < $cntr_old} { set rate_val(inst) [expr {($yvec_new - $yvec_old)*20000000/($cntr_old - $cntr_new)}] set rate_val(mean) [expr {($yvec_new - $yvec_bak)*20000000/($cntr_bak - $cntr_new)}] set yvec_old $yvec_new set cntr_old $cntr_new } } # ------------------------------------------------------------------------- HstDisplay instproc save_data {data} { my instvar number set types { {{Data Files} {.dat} } {{All Files} * } } set stamp [clock format [clock seconds] -format %Y%m%d_%H%M%S] set fname spectrum_[expr {$number + 1}]_${stamp}.dat set fname [tk_getSaveFile -filetypes $types -initialfile $fname] if {[string equal $fname {}]} { return } set x [catch { set fid [open $fname w+] puts $fid $data close $fid }] if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } { tk_messageBox -icon error \ -message "An error occurred while writing to \"$fname\"" } else { tk_messageBox -icon info \ -message "File \"$fname\" written successfully" } } # ------------------------------------------------------------------------- HstDisplay instproc register {} { my save_data [join [[myvar yvec] range 0 4095] \n] } # ------------------------------------------------------------------------- Class CntDisplay -parameter { {master} {controller} } # ------------------------------------------------------------------------- CntDisplay instproc init {} { my set data {} my set cntr 0 my set recs 0 vector create [myvar xvec](16384) vector create [myvar yvec](16384) # fill one vector for the x axis with 16384 points [myvar xvec] seq -0.5 16384.5 my setup next } # ------------------------------------------------------------------------- CntDisplay instproc destroy {} { next } # ------------------------------------------------------------------------- CntDisplay instproc start {} { my instvar config trace add variable [myvar data] write [myproc data_update] trace add variable [myvar thrs_val] write [myproc thrs_val_update] trace add variable [myvar cntr] write [myproc cntr_update] trace add variable [myvar recs] write [myproc recs_update] trace add variable [myvar axis] write [myproc axis_update] ${config}.axis_check select my set thrs_val 100 my set cntr_val 100 my set cntr_bak 100 my set recs_val 100 my set recs_bak 100 # my cntr_reset } # ------------------------------------------------------------------------- CntDisplay instproc setup {} { my instvar master my instvar xvec yvec graph my instvar config my instvar cntr_ms # create a graph widget and show a grid set graph [graph ${master}.graph -height 250 -leftmargin 80] $graph crosshairs configure -hide no -linewidth 1 -color darkblue -dashes {2 2} $graph grid configure -hide no $graph legend configure -hide yes $graph axis configure x -min 0 -max 16384 set config [frame ${master}.config -width 170] checkbutton ${config}.axis_check -text {log scale} -variable [myvar axis] frame ${config}.spc1 -width 170 -height 30 frame ${config}.chan_frame -borderwidth 0 -width 170 legendLabel ${config}.chan_frame 0 mean {Mean value} legendLabel ${config}.chan_frame 1 entr {Total entries} legendLabel ${config}.chan_frame 2 empty {} legendLabel ${config}.chan_frame 3 axisy {Bin entries} legendLabel ${config}.chan_frame 4 axisx {Bin number} frame ${config}.spc3 -width 170 -height 30 label ${config}.thrs -text {amplitude threshold} spinbox ${config}.thrs_field -from 1 -to 4095 \ -increment 5 -width 10 -textvariable [myvar thrs_val] \ -validate all -vcmd {::mca::validate 4095 4 %P} frame ${config}.spc4 -width 170 -height 30 label ${config}.cntr -text {time of exposure (s)} spinbox ${config}.cntr_field -from 0 -to 9999 \ -increment 10 -width 10 -textvariable [myvar cntr_val] \ -validate all -vcmd {::mca::validate 9999 4 %P} frame ${config}.spc5 -width 170 -height 10 label ${config}.recs -text {number of exposures} spinbox ${config}.recs_field -from 0 -to 99999 \ -increment 10 -width 10 -textvariable [myvar recs_val] \ -validate all -vcmd {::mca::validate 99999 5 %P} frame ${config}.spc6 -width 170 -height 10 button ${config}.start -text {Start} \ -bg yellow -activebackground yellow -command [myproc recs_start] button ${config}.reset -text Reset \ -bg red -activebackground red -command [myproc cntr_reset] frame ${config}.spc7 -width 170 -height 30 button ${config}.register -text Register \ -bg lightblue -activebackground lightblue -command [myproc register] grid ${config}.axis_check -sticky w grid ${config}.spc1 grid ${config}.chan_frame -sticky ew -padx 5 grid ${config}.spc3 grid ${config}.thrs -sticky w -pady 1 -padx 3 grid ${config}.thrs_field -sticky ew -pady 1 -padx 5 grid ${config}.spc4 grid ${config}.cntr -sticky w -pady 1 -padx 3 grid ${config}.cntr_field -sticky ew -pady 1 -padx 5 grid ${config}.spc5 grid ${config}.recs -sticky w -pady 1 -padx 3 grid ${config}.recs_field -sticky ew -pady 1 -padx 5 grid ${config}.spc6 grid ${config}.start -sticky ew -pady 3 -padx 5 grid ${config}.reset -sticky ew -pady 3 -padx 5 grid ${config}.spc7 grid ${config}.register -sticky ew -pady 3 -padx 5 grid ${graph} -row 0 -column 0 -sticky news grid ${config} -row 0 -column 1 grid rowconfigure ${master} 0 -weight 1 grid columnconfigure ${master} 0 -weight 1 grid columnconfigure ${master} 1 -weight 0 -minsize 80 grid columnconfigure ${config}.chan_frame 1 -weight 1 # enable zooming Blt_ZoomStack $graph my crosshairs $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 -color blue -linewidth 2 -symbol none -smooth step -xdata [myvar xvec] -ydata [myvar yvec] } # ------------------------------------------------------------------------- CntDisplay instproc coor_update {W x y} { my instvar config graph $W crosshairs configure -position @${x},${y} set index [$W axis invtransform x $x] set index [::tcl::mathfunc::round $index] catch { ${config}.chan_frame.axisy_value configure -text [[myvar yvec] index $index] ${config}.chan_frame.axisx_value configure -text ${index}.0 } } # ------------------------------------------------------------------------- CntDisplay instproc crosshairs {graph} { set method [myproc coor_update] bind $graph [list [self] coor_update %W %x %y] bind $graph { %W crosshairs off } bind $graph { %W crosshairs on } } # ------------------------------------------------------------------------- CntDisplay instproc thrs_val_update args { my instvar controller config thrs_val if {[string equal $thrs_val {}]} { set thrs_val 0 } set val_addr [format %02x 12] ${config}.thrs_field configure -state normal set value [format %03x $thrs_val] $controller usbCmd 000200${val_addr}00040${value} } # ------------------------------------------------------------------------- CntDisplay instproc cntr_update args { my instvar cntr cntr_val set cntr_val [expr {${cntr}/20000000}] } # ------------------------------------------------------------------------- CntDisplay instproc recs_update args { my instvar recs recs_val set recs_val [expr {${recs}*1}] } # ------------------------------------------------------------------------- CntDisplay instproc cntr_setup {} { my instvar controller cntr_val set cntr_tmp [expr {${cntr_val} * 20000000}] set word0 [format {%08x} [expr {${cntr_tmp} & 0xFFFFFFFF}]] set word1 [format {%08x} [expr {${cntr_tmp} >> 32}]] set prefix [format {%x} 9] set command {} append command 0001${prefix}000000200000004[string range $word0 4 7] append command 0001${prefix}000000200010004[string range $word0 0 3] append command 0001${prefix}000000200020004[string range $word1 4 7] append command 0001${prefix}000000200030004[string range $word1 0 3] # send counter value $controller usbCmd $command } # ------------------------------------------------------------------------- CntDisplay instproc recs_setup {} { my instvar controller recs_val set word0 [format {%08x} [expr {${recs_val} & 0xFFFFFFFF}]] set word1 [format {%08x} [expr {${recs_val} >> 32}]] set prefix [format {%x} 10] set command {} append command 0001${prefix}000000200000004[string range $word0 4 7] append command 0001${prefix}000000200010004[string range $word0 0 3] append command 0001${prefix}000000200020004[string range $word1 4 7] append command 0001${prefix}000000200030004[string range $word1 0 3] # send counter value $controller usbCmd $command } # ------------------------------------------------------------------------- CntDisplay instproc cntr_reset {} { my instvar controller after_handle my instvar cntr_val cntr_bak recs_val recs_bak my cntr_stop set value [format {%04x} [expr {1 << 11}]] $controller usbCmd 000200000004${value}0002000000040000 my recs_stop } # ------------------------------------------------------------------------- CntDisplay instproc cntr_ready {} { my instvar config cntr_val cntr_bak recs_val recs_bak set cntr_val $cntr_bak set recs_val $recs_bak ${config}.start configure -text Start -command [myproc recs_start] ${config}.reset configure -state active ${config}.start configure -state active ${config}.cntr_field configure -state normal ${config}.recs_field configure -state normal } # ------------------------------------------------------------------------- CntDisplay instproc recs_start {} { my instvar controller config auto my instvar cntr_val cntr_bak recs_val recs_bak if {$cntr_val > 0 && $recs_val > 0} { ${config}.start configure -text {Stop} -command [myproc recs_stop] ${config}.cntr_field configure -state disabled ${config}.recs_field configure -state disabled set cntr_bak $cntr_val set recs_bak $recs_val my cntr_setup my recs_setup set val_addr [format {%02x} 16] $controller usbCmd 000200${val_addr}00040002 set auto 1 after 100 [myproc acquire_loop] } } # ------------------------------------------------------------------------- CntDisplay instproc recs_stop {} { my instvar cntr_val cntr_bak recs_val recs_bak my cntr_stop set cntr_val $cntr_bak my cntr_setup set recs_val $recs_bak my recs_setup my acquire my cntr_ready } # ------------------------------------------------------------------------- CntDisplay instproc cntr_stop {} { my instvar controller config auto set val_addr [format {%02x} 16] $controller usbCmd 000200${val_addr}00040000 set auto 0 } # ------------------------------------------------------------------------- CntDisplay instproc acquire_loop {} { my instvar recs_val auto my acquire if {$recs_val == 0} { my cntr_stop my cntr_ready } elseif {$auto} { after 1000 [myproc acquire_loop] } } # ------------------------------------------------------------------------- CntDisplay instproc data_update args { my instvar config data usb::convertBlt $data 2 [myvar yvec] ${config}.chan_frame.mean_value configure \ -text [format {%.2e} [usb::integrateBlt [myvar yvec] 1]] ${config}.chan_frame.entr_value configure \ -text [usb::integrateBlt [myvar yvec] 0] } # ------------------------------------------------------------------------- CntDisplay instproc axis_update args { my instvar axis graph if {$axis} { $graph axis configure y -min 1 -max 1E5 -logscale yes } else { $graph axis configure y -min {} -max {} -logscale no } } # ------------------------------------------------------------------------- CntDisplay instproc acquire {} { my instvar controller config my instvar cntr cntr_val recs recs_val set size 16384 set prefix [format {%x} 8] set value [format {%08x} $size] set command 0001${prefix}000000200000001[string range $value 0 3]0003[string range $value 4 7]00050000 $controller usbCmdReadRaw $command [expr {$size * 2}] [myvar data] set prefix [format {%x} 9] set command 0001${prefix}000000200000003000400050000 $controller usbCmdReadHex $command 8 1 [myvar cntr] set prefix [format {%x} 10] set command 0001${prefix}000000200000003000400050000 $controller usbCmdReadHex $command 8 1 [myvar recs] } # ------------------------------------------------------------------------- CntDisplay instproc save_data {data} { set types { {{Data Files} {.dat} } {{All Files} * } } set stamp [clock format [clock seconds] -format %Y%m%d_%H%M%S] set fname counts_${stamp}.dat set fname [tk_getSaveFile -filetypes $types -initialfile $fname] if {[string equal $fname {}]} { return } set x [catch { set fid [open $fname w+] puts $fid $data close $fid }] if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } { tk_messageBox -icon error \ -message "An error occurred while writing to \"$fname\"" } else { tk_messageBox -icon info \ -message "File \"$fname\" written successfully" } } # ------------------------------------------------------------------------- CntDisplay instproc register {} { my save_data [join [[myvar yvec] range 0 16383] \n] } # ------------------------------------------------------------------------- Class OscDisplay -parameter { {master} {controller} } # ------------------------------------------------------------------------- OscDisplay instproc init {} { my instvar sequence data xvec yvec set data {} set sequence 0 # set xvec [vector create #auto(262144)] set xvec [vector create #auto(10000)] for {set i 1} {$i <= 9} {incr i} { # dict set yvec $i [vector create #auto(262144)] dict set yvec $i [vector create #auto(10000)] } # fill one vector for the x axis # $xvec seq 0 262143 $xvec seq 0 10000 my setup next } # ------------------------------------------------------------------------- OscDisplay instproc destroy {} { next } # ------------------------------------------------------------------------- OscDisplay instproc start {} { my instvar config my instvar recs_val directory set directory $::env(HOMEPATH) set recs_val 100 trace add variable [myvar chan] write [myproc chan_update] trace add variable [myvar data] write [myproc data_update] trace add variable [myvar auto] write [myproc auto_update] trace add variable [myvar thrs] write [myproc thrs_update 0] trace add variable [myvar thrs_val] write [myproc thrs_update 0] trace add variable [myvar recs_val] write [myproc recs_val_update] trace add variable [myvar last] write [myproc last_update] ${config}.chan_frame.chan1_check select ${config}.chan_frame.chan2_check select ${config}.chan_frame.chan3_check select ${config}.chan_frame.chan4_check select ${config}.chan_frame.chan5_check select ${config}.chan_frame.chan6_check select ${config}.thrs_check select ${config}.thrs_field set 100 } # ------------------------------------------------------------------------- OscDisplay instproc setup {} { my instvar master my instvar xvec yvec graph my instvar config # create a graph widget and show a grid set graph [graph ${master}.graph -height 250 -leftmargin 80] $graph crosshairs configure -hide no -linewidth 1 -color darkblue -dashes {2 2} $graph grid configure -hide no $graph legend configure -hide yes $graph axis configure x -min 0 -max 10000 $graph axis configure y -min 0 -max 4100 # scale ${master}.last -orient horizontal -from 1 -to 27 -tickinterval 0 -showvalue no -variable [myvar last] set config [frame ${master}.config -width 170] frame ${config}.chan_frame -width 170 legendButton ${config}.chan_frame 0 chan1 {Channel 1} [myvar chan(1)] turquoise2 legendButton ${config}.chan_frame 1 chan2 {Channel 2} [myvar chan(2)] SpringGreen2 legendButton ${config}.chan_frame 2 chan3 {Channel 3} [myvar chan(3)] orchid2 legendButton ${config}.chan_frame 3 chan4 {Channel 4} [myvar chan(4)] orange2 legendButton ${config}.chan_frame 4 chan5 {Channel 5} [myvar chan(5)] blue1 white legendButton ${config}.chan_frame 5 chan6 {Channel 6} [myvar chan(6)] gray65 white legendLabel ${config}.chan_frame 6 axisx {Time axis} frame ${config}.spc1 -width 170 -height 30 checkbutton ${config}.auto_check -text {auto update} -variable [myvar auto] frame ${config}.spc2 -width 170 -height 30 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 4095 4 %P} frame ${config}.spc3 -width 170 -height 30 button ${config}.acquire -text Acquire \ -bg green -activebackground green -command [myproc acquire_start] button ${config}.register -text Register \ -bg lightblue -activebackground lightblue -command [myproc register] frame ${config}.spc4 -width 170 -height 30 label ${config}.recs -text {number of records} spinbox ${config}.recs_field -from 0 -to 10000 \ -increment 10 -width 10 -textvariable [myvar recs_val] \ -validate all -vcmd {::mca::validate 10000 5 %P} frame ${config}.spc5 -width 170 -height 10 button ${config}.sequence -text {Start Recording} -command [myproc sequence_start] \ -bg yellow -activebackground yellow frame ${config}.spc6 -width 170 -height 10 button ${config}.recover -text {Read file} \ -bg lightblue -activebackground lightblue -command [myproc recover] grid ${config}.chan_frame -sticky ew grid ${config}.spc1 grid ${config}.auto_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}.acquire -sticky ew -pady 3 -padx 5 grid ${config}.register -sticky ew -pady 3 -padx 5 grid ${config}.spc4 grid ${config}.recs -sticky w -pady 1 -padx 3 grid ${config}.recs_field -sticky ew -pady 1 -padx 5 grid ${config}.spc5 grid ${config}.sequence -sticky ew -pady 3 -padx 5 grid ${config}.spc6 grid ${config}.recover -sticky ew -pady 3 -padx 5 grid ${graph} -row 0 -column 0 -sticky news grid ${config} -row 0 -column 1 # grid ${master}.last -row 1 -column 0 -columnspan 2 -sticky ew grid rowconfigure ${master} 0 -weight 1 grid columnconfigure ${master} 0 -weight 1 grid columnconfigure ${master} 1 -weight 0 -minsize 120 grid columnconfigure ${config}.chan_frame 2 -weight 1 # enable zooming Blt_ZoomStack $graph my crosshairs $graph # create one element with data for the x and y axis, no dots $graph pen create pen1 -color turquoise3 -linewidth 2 -symbol none $graph pen create pen2 -color SpringGreen3 -linewidth 2 -symbol none $graph pen create pen3 -color orchid3 -linewidth 2 -symbol none $graph pen create pen4 -color orange3 -linewidth 2 -symbol none $graph pen create pen5 -color blue2 -linewidth 2 -symbol none $graph pen create pen6 -color gray55 -linewidth 2 -symbol none $graph element create Spectrum1 -pen pen1 -xdata $xvec -ydata [dict get $yvec 1] $graph element create Spectrum2 -pen pen2 -xdata $xvec -ydata [dict get $yvec 2] $graph element create Spectrum3 -pen pen3 -xdata $xvec -ydata [dict get $yvec 3] $graph element create Spectrum4 -pen pen4 -xdata $xvec -ydata [dict get $yvec 4] $graph element create Spectrum5 -pen pen5 -xdata $xvec -ydata [dict get $yvec 5] $graph element create Spectrum6 -pen pen6 -xdata $xvec -ydata [dict get $yvec 6] } # ------------------------------------------------------------------------- OscDisplay instproc coor_update {W x y} { my instvar xvec yvec graph my instvar config $W crosshairs configure -position @${x},${y} set index [$W axis invtransform x $x] set index [::tcl::mathfunc::round $index] catch { ${config}.chan_frame.chan1_value configure -text [[dict get $yvec 1] index $index] ${config}.chan_frame.chan2_value configure -text [[dict get $yvec 2] index $index] ${config}.chan_frame.chan3_value configure -text [[dict get $yvec 3] index $index] ${config}.chan_frame.chan4_value configure -text [[dict get $yvec 4] index $index] ${config}.chan_frame.chan5_value configure -text [[dict get $yvec 5] index $index] ${config}.chan_frame.chan6_value configure -text [[dict get $yvec 6] index $index] ${config}.chan_frame.axisx_value configure -text ${index}.0 } } # ------------------------------------------------------------------------- OscDisplay instproc crosshairs {graph} { set method [myproc coor_update] bind $graph [list [self] coor_update %W %x %y] bind $graph { %W crosshairs off } bind $graph { %W crosshairs on } } # ------------------------------------------------------------------------- OscDisplay instproc chan_update {name key op} { my instvar config graph chan if {$chan(${key})} { $graph pen configure pen${key} -linewidth 2 } else { $graph pen configure pen${key} -linewidth 0 } } # ------------------------------------------------------------------------- OscDisplay instproc recs_val_update args { my instvar recs_val if {[string equal $recs_val {}]} { set recs_val 0 } } # ------------------------------------------------------------------------- OscDisplay instproc last_update args { my instvar graph last set first [expr {$last - 1}] $graph axis configure x -min ${first}0000 -max ${last}0000 } # ------------------------------------------------------------------------- OscDisplay instproc thrs_update {reset args} { my instvar controller config thrs thrs_val if {[string equal $thrs_val {}]} { set thrs_val 0 } if {$thrs} { ${config}.thrs_field configure -state normal set value [format %03x $thrs_val] } else { ${config}.thrs_field configure -state disabled set value 000 } set command {} if {$reset} { append command 0002000500041${value} } append command 0002000500040${value} $controller usbCmd $command } # ------------------------------------------------------------------------- OscDisplay instproc data_update args { my instvar data yvec my instvar graph chan waiting sequence auto usb::convertOsc $data $yvec foreach {key value} [array get chan] { $graph pen configure pen${key} -dashes 0 } set waiting 0 if {$sequence} { my sequence_register } elseif {$auto} { after 1000 [myproc acquire_start] } } # ------------------------------------------------------------------------- OscDisplay instproc acquire_start {} { my instvar graph chan controller waiting foreach {key value} [array get chan] { $graph pen configure pen${key} -dashes dot } # restart my thrs_update 1 set waiting 1 after 200 [myproc acquire_loop] } # ------------------------------------------------------------------------- OscDisplay instproc acquire_loop {} { my instvar controller waiting # set size 262144 set size 10000 set value [format {%08x} [expr {$size * 4}]] set command 00011000000200000001[string range $value 0 3]0003[string range $value 4 7]00050000 $controller usbCmdReadRaw $command [expr {$size * 8}] [myvar data] if {$waiting} { after 200 [myproc acquire_loop] } } # ------------------------------------------------------------------------- OscDisplay instproc auto_update args { my instvar config auto if {$auto} { ${config}.recs_field configure -state disabled ${config}.sequence configure -state disabled ${config}.acquire configure -state disabled ${config}.register configure -state disabled ${config}.recover configure -state disabled my acquire_start } else { ${config}.recs_field configure -state normal ${config}.sequence configure -state active ${config}.acquire configure -state active ${config}.register configure -state active ${config}.recover configure -state active } } # ------------------------------------------------------------------------- OscDisplay instproc save_data {fname} { my instvar data set fid [open $fname w+] fconfigure $fid -translation binary -encoding binary # puts -nonewline $fid [binary format "H*iH*" "1f8b0800" [clock seconds] "0003"] # puts -nonewline $fid [zlib deflate $data] puts -nonewline $fid $data # puts -nonewline $fid [binary format i [zlib crc32 $data]] # puts -nonewline $fid [binary format i [string length $data]] close $fid } # ------------------------------------------------------------------------- OscDisplay instproc open_data {} { set types { {{Data Files} {.dat} } {{All Files} * } } set fname [tk_getOpenFile -filetypes $types] if {[string equal $fname {}]} { return } set x [catch { set fid [open $fname r+] fconfigure $fid -translation binary -encoding binary # set size [file size $fname] # seek $fid 10 # my set data [zlib inflate [read $fid [expr {$size - 18}]]] my set data [read $fid] close $fid }] if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } { tk_messageBox -icon error \ -message "An error occurred while reading \"$fname\"" } else { tk_messageBox -icon info \ -message "File \"$fname\" read successfully" } } # ------------------------------------------------------------------------- OscDisplay instproc register {} { set types { {{Data Files} {.dat} } {{All Files} * } } set stamp [clock format [clock seconds] -format %Y%m%d_%H%M%S] set fname oscillogram_${stamp}.dat set fname [tk_getSaveFile -filetypes $types -initialfile $fname] if {[string equal $fname {}]} { return } if {[catch {my save_data $fname} result]} { tk_messageBox -icon error \ -message "An error occurred while writing to \"$fname\"" } else { tk_messageBox -icon info \ -message "File \"$fname\" written successfully" } } # ------------------------------------------------------------------------- OscDisplay instproc recover {} { my open_data } # ------------------------------------------------------------------------- OscDisplay instproc sequence_start {} { my instvar config recs_val recs_bak directory counter sequence set counter 1 if {$counter > $recs_val} { return } set directory [tk_chooseDirectory -initialdir $directory -title {Choose a directory}] if {[string equal $directory {}]} { return } ${config}.recs_field configure -state disabled ${config}.sequence configure -text {Stop Recording} -command [myproc sequence_stop] ${config}.acquire configure -state disabled ${config}.register configure -state disabled ${config}.recover configure -state disabled set recs_bak $recs_val set sequence 1 my acquire_start } # ------------------------------------------------------------------------- OscDisplay instproc sequence_register {} { my instvar config recs_val recs_bak directory counter set fname [file join $directory oscillogram_$counter.dat] my incr counter if {[catch {my save_data $fname} result]} { tk_messageBox -icon error \ -message "An error occurred while writing to \"$fname\"" } elseif {$counter <= $recs_bak} { set recs_val [expr {$recs_bak - $counter}] my acquire_start return } my sequence_stop } # ------------------------------------------------------------------------- OscDisplay instproc sequence_stop {} { my instvar config recs_val recs_bak sequence set sequence 0 set recs_val $recs_bak ${config}.recs_field configure -state normal ${config}.sequence configure -text {Start Recording} -command [myproc sequence_start] ${config}.acquire configure -state active ${config}.register configure -state active ${config}.recover configure -state active } # ------------------------------------------------------------------------- namespace export MuxDisplay namespace export HstDisplay namespace export CntDisplay namespace export OscDisplay } set notebook [::blt::tabnotebook .notebook -borderwidth 1 -selectforeground black -side bottom] grid ${notebook} -row 0 -column 0 -sticky news -pady 5 grid rowconfigure . 0 -weight 1 grid columnconfigure . 0 -weight 1 ::mca::UsbController usb usb usbCmd 00000000 set window [frame ${notebook}.spi] $notebook insert end -text "DAC & ADC control" -window $window -fill both ::mca::SpiDisplay spi -master $window -controller usb set window [frame ${notebook}.mux] $notebook insert end -text "Interconnect" -window $window -fill both ::mca::MuxDisplay mux -master $window -controller usb set window [frame ${notebook}.ept] $notebook insert end -text "Oscilloscope" -window $window -fill both ::mca::OscDisplay osc -master $window -controller usb update spi start mux start osc start spi adc_reset