source: trunk/3DEES/UserInterface.tcl@ 182

Last change on this file since 182 was 182, checked in by demin, 11 years ago

reorder channels

File size: 46.1 KB
Line 
1package require XOTcl
2
3package require BLT
4package require swt
5package require usb
6
7package require zlib
8
9wm minsize . 1000 700
10
11namespace eval ::mca {
12 namespace import ::xotcl::*
13
14 namespace import ::blt::vector
15 namespace import ::blt::graph
16 namespace import ::blt::tabnotebook
17
18# -------------------------------------------------------------------------
19
20 variable oscCodes
21 array set oscCodes {
22 1 {Channel 1}
23 2 {Channel 2}
24 3 {Channel 3}
25 4 {Channel 4}
26 5 {Channel 5}
27 6 {Trigger}
28 }
29
30# -------------------------------------------------------------------------
31
32 variable adcCodes
33 array set adcCodes {
34 1 {S1_F}
35 2 {S1_S}
36 3 {S2}
37 4 {D1}
38 5 {D2}
39 6 {D3}
40 }
41
42# -------------------------------------------------------------------------
43
44 variable cfgCodes
45 array set cfgCodes {
46 {1_0} 0
47 {1_1} 6
48 {2_0} 1
49 {2_1} 7
50 {3_0} 2
51 {3_1} 8
52 {3_2} 9
53 {3_3} 10
54 {4_0} 3
55 {4_1} 11
56 {4_2} 12
57 {4_3} 13
58 {5_0} 4
59 {5_1} 14
60 {5_2} 15
61 {5_3} 16
62 {6_0} 5
63 {6_1} 17
64 {6_2} 18
65 {6_3} 19
66 }
67# -------------------------------------------------------------------------
68
69 variable cfgThrs
70 array set cfgThrs {
71 0 8
72 6 50
73 1 8
74 7 50
75 2 10
76 8 31
77 9 52
78 10 79
79 3 60
80 11 135
81 12 171
82 13 233
83 4 249
84 14 348
85 15 495
86 16 693
87 5 505
88 17 606
89 18 707
90 19 808
91 }
92
93
94# -------------------------------------------------------------------------
95
96 variable inpCodes
97 array set inpCodes {
98 0 {r}
99 1 {c}
100 2 {a}
101 3 {f}
102 }
103
104# -------------------------------------------------------------------------
105
106 proc validate {max size value} {
107 if {![regexp {^[0-9]*$} $value]} {
108 return 0
109 } elseif {[regexp {^0[0-9]+$} $value]} {
110 return 0
111 } elseif {$value > $max} {
112 return 0
113 } elseif {[string length $value] > $size} {
114 return 0
115 } else {
116 return 1
117 }
118 }
119
120# -------------------------------------------------------------------------
121
122 proc doublevalidate {max value} {
123 if {![regexp {^[0-9]{0,2}\.?[0-9]{0,3}$} $value]} {
124 return 0
125 } elseif {[regexp {^0[0-9]+$} $value]} {
126 return 0
127 } elseif {$value > $max} {
128 return 0
129 } else {
130 return 1
131 }
132 }
133
134# -------------------------------------------------------------------------
135
136 proc legendLabel {master row key title} {
137 label ${master}.${key}_label -anchor w -text ${title}
138 label ${master}.${key}_value -width 10 -anchor e -text {}
139
140 grid ${master}.${key}_label -row ${row} -column 1 -sticky w
141 grid ${master}.${key}_value -row ${row} -column 2 -sticky ew
142 }
143
144# -------------------------------------------------------------------------
145
146 proc legendButton {master row key title var bg {fg black}} {
147 checkbutton ${master}.${key}_check -variable $var
148 label ${master}.${key}_label -anchor w -text ${title} -bg ${bg} -fg $fg
149 label ${master}.${key}_value -width 10 -anchor e -text {} -bg ${bg} -fg $fg
150
151 grid ${master}.${key}_check -row ${row} -column 0 -sticky w
152 grid ${master}.${key}_label -row ${row} -column 1 -sticky w
153 grid ${master}.${key}_value -row ${row} -column 2 -sticky ew
154 }
155
156# -------------------------------------------------------------------------
157
158 Class UsbController
159
160# -------------------------------------------------------------------------
161
162 UsbController instproc init {} {
163
164 my set ignore false
165
166 next
167 }
168
169# -------------------------------------------------------------------------
170
171 UsbController instproc usbConnect {} {
172 my instvar handle ignore
173
174 puts usbConnect
175
176 if {[my exists handle]} {
177 $handle disconnect
178 unset handle
179 }
180 if {!$ignore} {
181 while {[catch {usb::connect 0x09FB 0x6001 1 1 0} result]} {
182 set answer [tk_messageBox -icon error -type abortretryignore \
183 -message {Cannot access USB device} -detail $result]
184 if {[string equal $answer abort]} exit
185 if {[string equal $answer ignore]} {
186 set ignore true
187 return
188 }
189 }
190
191 set handle $result
192
193 }
194 }
195
196# -------------------------------------------------------------------------
197
198 UsbController instproc usbHandle {} {
199 my instvar handle ignore
200
201 if {[my exists handle]} {
202 return $handle
203 } elseif {!$ignore} {
204 my usbConnect
205 }
206 }
207
208# -------------------------------------------------------------------------
209
210 UsbController instproc usbCmd {command} {
211 set code [catch {[my usbHandle] writeRaw [usb::convert $command]} result]
212 switch -- $code {
213 1 {
214# puts $result
215 my usbConnect
216 }
217 }
218
219 }
220
221# -------------------------------------------------------------------------
222
223 UsbController instproc usbCmdReadRaw {command size data} {
224 my usbCmd $command
225
226 set code [catch {[my usbHandle] readRaw $size} result]
227 switch -- $code {
228 0 {
229 set $data $result
230 }
231 1 {
232# puts $result
233 my usbConnect
234 }
235 5 {
236# puts Busy
237 }
238 }
239 }
240
241# -------------------------------------------------------------------------
242
243 UsbController instproc usbCmdReadRaw {command size data} {
244 my usbCmd $command
245
246 set code [catch {[my usbHandle] readRaw $size} result]
247 switch -- $code {
248 0 {
249 set $data $result
250 }
251 1 {
252# puts $result
253 my usbConnect
254 }
255 5 {
256# puts Busy
257 }
258 }
259 }
260
261# -------------------------------------------------------------------------
262
263 UsbController instproc usbCmdReadHex {command width size data} {
264 my usbCmd $command
265
266 set code [catch {[my usbHandle] readHex $width $size} result]
267 switch -- $code {
268 0 {
269 set $data $result
270 }
271 1 {
272# puts $result
273 my usbConnect
274 }
275 5 {
276# puts Busy
277 }
278 }
279 }
280
281# -------------------------------------------------------------------------
282
283 Class CfgDisplay -parameter {
284 {master}
285 {controller}
286 }
287
288# -------------------------------------------------------------------------
289
290 CfgDisplay instproc init {} {
291
292 my setup
293
294 next
295 }
296
297# -------------------------------------------------------------------------
298
299 CfgDisplay instproc destroy {} {
300 next
301 }
302
303# -------------------------------------------------------------------------
304
305 CfgDisplay instproc start {} {
306 variable adcCodes
307 variable cfgThrs
308
309 foreach {ch id} [array get adcCodes] {
310 my set delay($ch) 32
311 my set decay($ch) 1000
312 }
313
314 foreach {i value} [array get cfgThrs] {
315 my set thrs($i) $value
316 }
317
318 trace add variable [myvar decay] write [myproc decay_update]
319 trace add variable [myvar delay] write [myproc delay_update]
320 trace add variable [myvar thrs] write [myproc thrs_update]
321
322 my delay_update
323 my thrs_update
324 }
325
326# -------------------------------------------------------------------------
327
328 CfgDisplay instproc setup {} {
329 variable adcCodes
330 variable cfgCodes
331 my instvar number master
332 my instvar config
333
334 set thrs [frame ${master}.thrs]
335 set bins [frame ${master}.bins]
336 set clip [frame ${master}.clip]
337
338 set config(thrs) [labelframe ${thrs}.frame -borderwidth 1 -relief sunken -text {Thresholds}]
339
340 set column 0
341 foreach {input} [list "ADC" "noise thrs" "e/p thrs"] {
342 label ${config(thrs)}.label_${column} -text "${input}"
343 grid ${config(thrs)}.label_${column} -row 0 -column ${column} -sticky ew -padx 5 -pady 7
344 incr column
345 }
346
347 foreach {ch id} [array get adcCodes {[1-2]}] {
348 label ${config(thrs)}.chan_${ch} -text "${id} "
349 grid ${config(thrs)}.chan_${ch} -row ${ch} -column 0 -sticky ew -padx 5 -pady 7
350 foreach {num} [list 0 1] {
351 set column [expr {$num + 1}]
352 set value $cfgCodes(${ch}_${num})
353 spinbox ${config(thrs)}.thrs_${value} -from 0 -to 4095 \
354 -increment 10 -width 10 -textvariable [myvar thrs($value)] \
355 -validate all -vcmd {::mca::validate 4095 4 %P}
356 grid ${config(thrs)}.thrs_${value} -row ${ch} -column ${column} -sticky w -padx 5 -pady 7
357 }
358 }
359
360 grid $config(thrs) -row 0 -column 0 -sticky news -padx 10
361
362 set config(bins) [labelframe ${bins}.frame -borderwidth 1 -relief sunken -text {Thresholds}]
363
364 set column 0
365 foreach {input} [list "ADC" "thrs 1" "thrs 2" "thrs 3" "thrs 4"] {
366 label ${config(bins)}.label_${column} -text "${input}"
367 grid ${config(bins)}.label_${column} -row 0 -column ${column} -sticky ew -padx 5 -pady 7
368 incr column
369 }
370
371 foreach {ch id} [array get adcCodes {[3-6]}] {
372 label ${config(bins)}.chan_${ch} -text "${id} "
373 grid ${config(bins)}.chan_${ch} -row ${ch} -column 0 -sticky ew -padx 5 -pady 7
374 foreach {num} [list 0 1 2 3] {
375 set column [expr {$num + 1}]
376 set value $cfgCodes(${ch}_${num})
377 spinbox ${config(bins)}.thrs_${value} -from 0 -to 4095 \
378 -increment 10 -width 10 -textvariable [myvar thrs($value)] \
379 -validate all -vcmd {::mca::validate 4095 4 %P}
380 grid ${config(bins)}.thrs_${value} -row ${ch} -column ${column} -sticky w -padx 5 -pady 7
381 }
382 }
383
384 grid $config(bins) -row 0 -column 0 -sticky news -padx 10
385
386 set config(clip) [labelframe ${clip}.frame -borderwidth 1 -relief sunken -text {Signal clipping}]
387
388 set column 0
389 foreach {input} [list "ADC" "delay" "decay"] {
390 label ${config(clip)}.label_${column} -text "${input}"
391 grid ${config(clip)}.label_${column} -row 0 -column ${column} -sticky ew -padx 5 -pady 7
392 incr column
393 }
394
395 foreach {ch id} [array get adcCodes] {
396 label ${config(clip)}.chan_${ch} -text "${id} "
397 grid ${config(clip)}.chan_${ch} -row ${ch} -column 0 -sticky ew -padx 5 -pady 7
398 spinbox ${config(clip)}.delay_${ch} -from 0 -to 62 \
399 -increment 2 -width 10 -textvariable [myvar delay($ch)] \
400 -validate all -vcmd {::mca::validate 63 5 %P}
401 grid ${config(clip)}.delay_${ch} -row ${ch} -column 1 -sticky w -padx 5 -pady 7
402 spinbox ${config(clip)}.decay_${ch} -from 0 -to 65535 \
403 -increment 10 -width 10 -textvariable [myvar decay($ch)] \
404 -validate all -vcmd {::mca::validate 65535 5 %P}
405 grid ${config(clip)}.decay_${ch} -row ${ch} -column 2 -sticky w -padx 5 -pady 7
406 }
407
408 grid $config(clip) -row 0 -column 0 -sticky news -padx 10
409
410 grid ${thrs} -row 0 -column 2 -sticky news
411 grid ${bins} -row 0 -column 1 -sticky news
412 grid ${clip} -row 0 -column 0 -sticky news
413
414 grid columnconfigure ${master} 0 -weight 1
415 grid columnconfigure ${master} 1 -weight 1
416 grid columnconfigure ${master} 2 -weight 1
417 grid rowconfigure ${master} 0 -weight 1
418
419 grid rowconfigure ${thrs} 0 -weight 0
420 grid rowconfigure ${bins} 0 -weight 0
421 grid rowconfigure ${clip} 0 -weight 0
422 }
423
424# -------------------------------------------------------------------------
425
426 CfgDisplay instproc decay_update args {
427 my instvar controller decay delay
428
429 set command {}
430 for {set i 1} {$i <= 6} {incr i} {
431 set a $delay($i).0
432 set b $decay($i).0
433 set value [expr int(exp(-${a}/${b})*1024*20)]
434 append command [format {000200%02x0004%04x} [expr {30 + 2 * (${i} - 1)}] $value]
435 }
436
437 $controller usbCmd $command
438 }
439
440# -------------------------------------------------------------------------
441
442 CfgDisplay instproc delay_update args {
443 my instvar controller delay
444
445 set command {}
446 for {set i 1} {$i <= 6} {incr i} {
447 append command [format {000200%02x0004%04x} [expr {31 + 2 * (${i} - 1)}] $delay($i)]
448 }
449
450 $controller usbCmd $command
451
452 my decay_update
453 }
454
455# -------------------------------------------------------------------------
456
457 CfgDisplay instproc thrs_update args {
458 my instvar controller thrs
459
460 set command {}
461 for {set i 0} {$i <= 19} {incr i} {
462 append command [format {000200%02x0004%04x} [expr {10 + ${i}}] $thrs($i)]
463 }
464
465 $controller usbCmd $command
466 }
467
468# -------------------------------------------------------------------------
469
470 Class MuxDisplay -parameter {
471 {master}
472 {controller}
473 }
474
475# -------------------------------------------------------------------------
476
477 MuxDisplay instproc init {} {
478
479 my setup
480
481 next
482 }
483
484# -------------------------------------------------------------------------
485
486 MuxDisplay instproc destroy {} {
487 next
488 }
489
490# -------------------------------------------------------------------------
491
492 MuxDisplay instproc start {} {
493 variable adcCodes
494 my instvar config chan_val
495
496 set chan_val(1) 0
497 set chan_val(2) 0
498 set chan_val(3) 0
499 set chan_val(4) 0
500 set chan_val(5) 0
501 set chan_val(6) 0
502
503 trace add variable [myvar chan_val] write [myproc chan_val_update]
504 trace add variable [myvar polar] write [myproc polar_update]
505
506 $config(1).chan_0_1 select
507 $config(2).chan_0_2 select
508 $config(3).chan_0_3 select
509 $config(4).chan_0_4 select
510 $config(5).chan_0_5 select
511 $config(6).chan_2_1 select
512
513 foreach {ch dummy} [array get adcCodes] {
514 $config(inv).polar_${ch} deselect
515 }
516 }
517
518# -------------------------------------------------------------------------
519
520 MuxDisplay instproc setup {} {
521 variable oscCodes
522 variable adcCodes
523 variable inpCodes
524 my instvar master
525 my instvar config
526
527 set size [array size inpCodes]
528 set oscList [array get oscCodes]
529 set adcList [array get adcCodes]
530 set inpList [array get inpCodes]
531
532 set mux [frame ${master}.mux]
533 set key [frame ${master}.key]
534 set inv [frame ${master}.inv]
535
536 foreach {osc title} $oscList {
537 set config($osc) [labelframe ${mux}.$osc -borderwidth 1 -relief sunken -text $title]
538 set column 1
539 foreach {code input} $inpList {
540 label $config($osc).input_${input} -text " ${input}"
541 grid $config($osc).input_${input} -row 0 -column ${column} -sticky w
542 incr column
543 }
544 foreach {ch id} $adcList {
545 label $config($osc).chan_${ch} -text "${id} "
546 grid $config($osc).chan_${ch} -row ${ch} -column 0 -sticky ew
547 foreach {code input} $inpList {
548 set column [expr {$code + 1}]
549 set value [expr {$size * ($ch - 1) + $code}]
550 radiobutton $config($osc).chan_${code}_${ch} -variable [myvar chan_val($osc)] -value ${value}
551 grid $config($osc).chan_${code}_${ch} -row ${ch} -column ${column} -sticky w
552 }
553 }
554 set column [expr {($osc - 1) % 6}]
555 set row [expr {($osc - 1) / 6}]
556 grid $config($osc) -row ${row} -column ${column} -sticky news -padx 10
557 }
558
559 set config(key) [labelframe ${key}.frame -borderwidth 1 -relief sunken -text {legend}]
560
561 label $config(key).r -text "r - raw signal"
562 grid $config(key).r -row 0 -column 0 -sticky news
563
564 label $config(key).f -text "c - filtered and clipped signal"
565 grid $config(key).f -row 0 -column 1 -sticky news
566
567 label $config(key).d -text "a - amplitude"
568 grid $config(key).d -row 0 -column 2 -sticky news
569
570 label $config(key).c -text "f - amplitude flag"
571 grid $config(key).c -row 0 -column 3 -sticky news
572
573 grid $config(key) -row 0 -column 0 -sticky news -padx 10
574
575
576 set config(inv) [labelframe ${inv}.frame -borderwidth 1 -relief sunken -text {polarity inversion}]
577 label $config(inv).chan_label -text "channel "
578 grid $config(inv).chan_label -row 0 -column 0 -sticky e
579 label $config(inv).polar_label -text "polarity"
580 grid $config(inv).polar_label -row 1 -column 0 -sticky e
581 foreach {ch dummy} $adcList {
582 label $config(inv).chan_${ch} -text "${ch} "
583 grid $config(inv).chan_${ch} -row 0 -column ${ch} -sticky ew
584 checkbutton $config(inv).polar_${ch} -variable [myvar polar($ch)]
585 grid $config(inv).polar_${ch} -row 1 -column ${ch} -sticky w
586 }
587 grid $config(inv) -row 0 -column 0 -sticky news -padx 10
588
589 grid ${key} -row 0 -column 0 -sticky news
590 grid ${mux} -row 1 -column 0 -sticky news
591 grid ${inv} -row 2 -column 0 -sticky news
592
593 grid columnconfigure ${master} 0 -weight 1
594 grid rowconfigure ${master} 0 -weight 1
595 grid rowconfigure ${master} 1 -weight 1
596 grid rowconfigure ${master} 2 -weight 1
597
598 grid columnconfigure ${inv} 0 -weight 1
599
600 grid columnconfigure ${key} 0 -weight 1
601 grid columnconfigure $config(key) 0 -weight 1
602 grid columnconfigure $config(key) 1 -weight 1
603 grid columnconfigure $config(key) 2 -weight 1
604 grid columnconfigure $config(key) 3 -weight 1
605
606
607 grid columnconfigure ${mux} 0 -weight 1
608 grid columnconfigure ${mux} 1 -weight 1
609 grid columnconfigure ${mux} 2 -weight 1
610 grid columnconfigure ${mux} 3 -weight 1
611 grid columnconfigure ${mux} 4 -weight 1
612 grid columnconfigure ${mux} 5 -weight 1
613 }
614
615# ------------------------------------------------------------------------
616
617 MuxDisplay instproc chan_val_update args {
618 my instvar controller chan_val
619
620 set byte1 [format {%02x%02x} $chan_val(2) $chan_val(1)]
621 set byte2 [format {%02x%02x} $chan_val(4) $chan_val(3)]
622 set byte3 [format {%02x%02x} $chan_val(6) $chan_val(5)]
623
624 $controller usbCmd 000200020004${byte1}000200030004${byte2}000200040004${byte3}
625 }
626
627# -------------------------------------------------------------------------
628
629 MuxDisplay instproc polar_update args {
630 my instvar controller polar
631
632 set value {0b}
633 for {set i 6} {$i >= 1} {incr i -1} {
634 append value $polar($i)
635 }
636
637 set value [format {%04x} $value]
638
639 $controller usbCmd 000200010004${value}
640 }
641
642# -------------------------------------------------------------------------
643
644 Class HstDisplay -parameter {
645 {number}
646 {master}
647 {controller}
648 }
649
650# -------------------------------------------------------------------------
651
652 HstDisplay instproc init {} {
653
654 my set data {}
655
656 vector create [myvar xvec](64)
657 vector create [myvar yvec](64)
658
659 # fill one vector for the x axis with 64 points
660 [myvar xvec] seq -0.5 63.5
661
662 my setup
663
664 next
665 }
666
667# -------------------------------------------------------------------------
668
669 HstDisplay instproc destroy {} {
670 next
671 }
672
673# -------------------------------------------------------------------------
674
675 HstDisplay instproc start {} {
676 my instvar config
677
678 trace add variable [myvar data] write [myproc data_update]
679
680 trace add variable [myvar axis] write [myproc axis_update]
681
682 ${config}.axis_check select
683
684 my set yvec_bak 0.0
685 my set yvec_old 0.0
686 }
687
688# -------------------------------------------------------------------------
689
690 HstDisplay instproc setup {} {
691 my instvar number master
692 my instvar xvec yvec graph
693 my instvar config thrs thrs_val base base_typ base_val
694 my instvar cntr_h cntr_m cntr_s
695
696 # create a graph widget and show a grid
697 set graph [graph ${master}.graph -height 250 -leftmargin 80]
698 $graph crosshairs configure -hide no -linewidth 1 -color darkblue -dashes {2 2}
699 $graph grid configure -hide no
700 $graph legend configure -hide yes
701 $graph axis configure x -min 0 -max 64
702
703 set config [frame ${master}.config -width 170]
704
705 checkbutton ${config}.axis_check -text {log scale} -variable [myvar axis]
706
707 frame ${config}.spc1 -width 170 -height 30
708
709 frame ${config}.chan_frame -borderwidth 0 -width 170
710 legendLabel ${config}.chan_frame 0 axisy {Bin entries}
711 legendLabel ${config}.chan_frame 1 axisx {Bin number}
712
713 frame ${config}.spc2 -width 170 -height 30
714
715 button ${config}.start -text Start \
716 -bg yellow -activebackground yellow -command [myproc cntr_start]
717 button ${config}.reset -text Reset \
718 -bg red -activebackground red -command [myproc cntr_reset]
719
720 frame ${config}.spc3 -width 170 -height 30
721
722 button ${config}.register -text Register \
723 -bg lightblue -activebackground lightblue -command [myproc register]
724
725 grid ${config}.axis_check -sticky w
726 grid ${config}.spc1
727 grid ${config}.chan_frame -sticky ew -padx 5
728 grid ${config}.spc2
729 grid ${config}.start -sticky ew -pady 3 -padx 5
730 grid ${config}.reset -sticky ew -pady 3 -padx 5
731 grid ${config}.spc3
732 grid ${config}.register -sticky ew -pady 3 -padx 5
733
734 grid ${graph} -row 0 -column 0 -sticky news
735 grid ${config} -row 0 -column 1
736
737 grid rowconfigure ${master} 0 -weight 1
738 grid columnconfigure ${master} 0 -weight 1
739 grid columnconfigure ${master} 1 -weight 0 -minsize 80
740
741 grid columnconfigure ${config}.chan_frame 1 -weight 1
742
743 # enable zooming
744 Blt_ZoomStack $graph
745
746 my crosshairs $graph
747
748 #bind .graph <Motion> {%W crosshairs configure -position @%x,%y}
749
750 # create one element with data for the x and y axis, no dots
751 $graph element create Spectrum1 -color blue -linewidth 2 -symbol none -smooth step -xdata [myvar xvec] -ydata [myvar yvec]
752 }
753
754# -------------------------------------------------------------------------
755
756 HstDisplay instproc coor_update {W x y} {
757 my instvar config graph
758
759 $W crosshairs configure -position @${x},${y}
760
761 set index [$W axis invtransform x $x]
762 set index [::tcl::mathfunc::round $index]
763 catch {
764 ${config}.chan_frame.axisy_value configure -text [[myvar yvec] index $index]
765 ${config}.chan_frame.axisx_value configure -text ${index}.0
766 }
767 }
768# -------------------------------------------------------------------------
769
770 HstDisplay instproc crosshairs {graph} {
771 set method [myproc coor_update]
772 bind $graph <Motion> [list [self] coor_update %W %x %y]
773 bind $graph <Leave> {
774 %W crosshairs off
775 }
776 bind $graph <Enter> {
777 %W crosshairs on
778 }
779 }
780
781# -------------------------------------------------------------------------
782
783 HstDisplay instproc axis_update args {
784 my instvar axis graph
785 if {$axis} {
786 $graph axis configure y -min 1 -max 1E10 -logscale yes
787 } else {
788 $graph axis configure y -min {} -max {} -logscale no
789 }
790 }
791
792# -------------------------------------------------------------------------
793
794 HstDisplay instproc cntr_reset {} {
795 my instvar controller number
796
797 my cntr_stop
798
799 set value [format %04x [expr {1 << (5 + ${number})}]]
800 $controller usbCmd 000200000004${value}0002000000040000
801
802 my acquire
803 }
804
805# -------------------------------------------------------------------------
806
807 HstDisplay instproc cntr_start {} {
808 my instvar controller config number auto
809
810 set val_addr [format %02x [expr {6 + ${number}}]]
811
812 ${config}.start configure -text Stop -command [myproc cntr_stop]
813# ${config}.reset configure -state disabled
814
815 $controller usbCmd 000200${val_addr}00040001
816
817 set auto 1
818
819 after 100 [myproc acquire_loop]
820 }
821
822# -------------------------------------------------------------------------
823
824 HstDisplay instproc cntr_stop {} {
825 my instvar controller config number auto
826
827 set val_addr [format %02x [expr {6 + ${number}}]]
828
829 ${config}.start configure -text Start -command [myproc cntr_start]
830
831 $controller usbCmd 000200${val_addr}00040000
832
833 set auto 0
834
835 my acquire
836 }
837
838# -------------------------------------------------------------------------
839
840 HstDisplay instproc data_update args {
841 my instvar data
842 usb::convertBlt $data 4 [myvar yvec]
843 }
844
845# -------------------------------------------------------------------------
846
847 HstDisplay instproc acquire_loop {} {
848 my instvar cntr_val auto
849
850 my acquire
851
852 if {$auto} {
853 after 1000 [myproc acquire_loop]
854 }
855 }
856
857# -------------------------------------------------------------------------
858
859 HstDisplay instproc acquire {} {
860 my instvar controller config number
861
862 set size 64
863
864 set prefix [format {%x} [expr {$number + 2}]]
865
866 set value [format {%08x} [expr {$size * 2}]]
867
868 set command 0001${prefix}000000200000001[string range $value 0 3]0003[string range $value 4 7]00050000
869
870 $controller usbCmdReadRaw $command [expr {$size * 4}] [myvar data]
871 }
872
873# -------------------------------------------------------------------------
874
875 HstDisplay instproc save_data {data} {
876 my instvar number
877
878 set types {
879 {{Data Files} {.dat} }
880 {{All Files} * }
881 }
882
883 set stamp [clock format [clock seconds] -format %Y%m%d_%H%M%S]
884 set fname spectrum_[expr {$number + 1}]_${stamp}.dat
885
886 set fname [tk_getSaveFile -filetypes $types -initialfile $fname]
887 if {[string equal $fname {}]} {
888 return
889 }
890
891 set x [catch {
892 set fid [open $fname w+]
893 puts $fid $data
894 close $fid
895 }]
896
897 if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } {
898 tk_messageBox -icon error \
899 -message "An error occurred while writing to \"$fname\""
900 } else {
901 tk_messageBox -icon info \
902 -message "File \"$fname\" written successfully"
903 }
904 }
905
906# -------------------------------------------------------------------------
907
908 HstDisplay instproc register {} {
909 my save_data [join [[myvar yvec] range 0 63] \n]
910 }
911
912# -------------------------------------------------------------------------
913
914 Class OscDisplay -parameter {
915 {master}
916 {controller}
917 }
918
919# -------------------------------------------------------------------------
920
921 OscDisplay instproc init {} {
922 my instvar sequence data xvec yvec
923
924 set data {}
925
926 set sequence 0
927
928# set xvec [vector create #auto(262144)]
929# set xvec [vector create #auto(10000)]
930 set xvec [vector create #auto(60000)]
931
932 for {set i 1} {$i <= 9} {incr i} {
933# dict set yvec $i [vector create #auto(262144)]
934# dict set yvec $i [vector create #auto(10000)]
935 dict set yvec $i [vector create #auto(60000)]
936 }
937
938 # fill one vector for the x axis
939# $xvec seq 0 262143
940# $xvec seq 0 10000
941 $xvec seq 0 60000
942
943 my setup
944
945 next
946 }
947
948# -------------------------------------------------------------------------
949
950 OscDisplay instproc destroy {} {
951 next
952 }
953
954# -------------------------------------------------------------------------
955
956 OscDisplay instproc start {} {
957 my instvar config
958 my instvar recs_val directory
959
960 set directory $::env(HOME)
961 set recs_val 100
962
963 trace add variable [myvar chan] write [myproc chan_update]
964
965 trace add variable [myvar data] write [myproc data_update]
966
967 trace add variable [myvar auto] write [myproc auto_update]
968
969 trace add variable [myvar thrs] write [myproc thrs_update 0]
970 trace add variable [myvar thrs_val] write [myproc thrs_update 0]
971
972 trace add variable [myvar recs_val] write [myproc recs_val_update]
973
974 trace add variable [myvar last] write [myproc last_update]
975
976 for {set i 1} {$i <= 6} {incr i} {
977 ${config}.chan_frame.chan${i}_check select
978 ${config}.chan_frame.chan${i}_value configure -text 0.0
979 }
980 ${config}.chan_frame.axisx_value configure -text 0.0
981
982 ${config}.thrs_check select
983 ${config}.thrs_field set 30
984 }
985
986# -------------------------------------------------------------------------
987
988 OscDisplay instproc setup {} {
989 my instvar master
990 my instvar xvec yvec graph
991 my instvar config
992
993 # create a graph widget and show a grid
994 set graph [graph ${master}.graph -height 250 -leftmargin 80]
995 $graph crosshairs configure -hide no -linewidth 1 -color darkblue -dashes {2 2}
996 $graph grid configure -hide no
997 $graph legend configure -hide yes
998 $graph axis configure x -min 0 -max 60000
999 $graph axis configure y -min 0 -max 4100
1000
1001# scale ${master}.last -orient horizontal -from 1 -to 27 -tickinterval 0 -showvalue no -variable [myvar last]
1002
1003 set config [frame ${master}.config -width 170]
1004
1005 frame ${config}.chan_frame -width 170
1006 legendButton ${config}.chan_frame 0 chan1 {Channel 1} [myvar chan(1)] turquoise2
1007 legendButton ${config}.chan_frame 1 chan2 {Channel 2} [myvar chan(2)] SpringGreen2
1008 legendButton ${config}.chan_frame 2 chan3 {Channel 3} [myvar chan(3)] orchid2
1009 legendButton ${config}.chan_frame 3 chan4 {Channel 4} [myvar chan(4)] orange2
1010 legendButton ${config}.chan_frame 4 chan5 {Channel 5} [myvar chan(5)] blue1 white
1011 legendButton ${config}.chan_frame 5 chan6 {Channel 6} [myvar chan(6)] gray65 white
1012 legendLabel ${config}.chan_frame 6 axisx {Time axis}
1013
1014 frame ${config}.spc1 -width 170 -height 30
1015
1016 checkbutton ${config}.auto_check -text {auto update} -variable [myvar auto]
1017
1018 frame ${config}.spc2 -width 170 -height 30
1019
1020 checkbutton ${config}.thrs_check -text threshold -variable [myvar thrs]
1021 spinbox ${config}.thrs_field -from 1 -to 4095 \
1022 -increment 5 -width 10 -textvariable [myvar thrs_val] \
1023 -validate all -vcmd {::mca::validate 4095 4 %P}
1024
1025 frame ${config}.spc3 -width 170 -height 30
1026
1027 button ${config}.acquire -text Acquire \
1028 -bg green -activebackground green -command [myproc acquire_start]
1029 button ${config}.register -text Register \
1030 -bg lightblue -activebackground lightblue -command [myproc register]
1031
1032 frame ${config}.spc4 -width 170 -height 30
1033
1034 label ${config}.recs -text {number of records}
1035 spinbox ${config}.recs_field -from 0 -to 10000 \
1036 -increment 10 -width 10 -textvariable [myvar recs_val] \
1037 -validate all -vcmd {::mca::validate 10000 5 %P}
1038
1039 frame ${config}.spc5 -width 170 -height 10
1040
1041 button ${config}.sequence -text {Start Recording} -command [myproc sequence_start] \
1042 -bg yellow -activebackground yellow
1043
1044 frame ${config}.spc6 -width 170 -height 30
1045
1046 button ${config}.recover -text {Read file} \
1047 -bg lightblue -activebackground lightblue -command [myproc recover]
1048
1049 grid ${config}.chan_frame -sticky ew
1050 grid ${config}.spc1
1051 grid ${config}.auto_check -sticky w
1052 grid ${config}.spc2
1053 grid ${config}.thrs_check -sticky w
1054 grid ${config}.thrs_field -sticky ew -pady 1 -padx 5
1055 grid ${config}.spc3
1056 grid ${config}.acquire -sticky ew -pady 3 -padx 5
1057 grid ${config}.register -sticky ew -pady 3 -padx 5
1058 grid ${config}.spc4
1059 grid ${config}.recs -sticky w -pady 1 -padx 3
1060 grid ${config}.recs_field -sticky ew -pady 1 -padx 5
1061 grid ${config}.spc5
1062 grid ${config}.sequence -sticky ew -pady 3 -padx 5
1063 grid ${config}.spc6
1064 grid ${config}.recover -sticky ew -pady 3 -padx 5
1065
1066 grid ${graph} -row 0 -column 0 -sticky news
1067 grid ${config} -row 0 -column 1
1068
1069# grid ${master}.last -row 1 -column 0 -columnspan 2 -sticky ew
1070
1071 grid rowconfigure ${master} 0 -weight 1
1072 grid columnconfigure ${master} 0 -weight 1
1073 grid columnconfigure ${master} 1 -weight 0 -minsize 120
1074
1075 grid columnconfigure ${config}.chan_frame 2 -weight 1
1076
1077 # enable zooming
1078 Blt_ZoomStack $graph
1079
1080 my crosshairs $graph
1081
1082 # create one element with data for the x and y axis, no dots
1083 $graph pen create pen1 -color turquoise3 -linewidth 2 -symbol none
1084 $graph pen create pen2 -color SpringGreen3 -linewidth 2 -symbol none
1085 $graph pen create pen3 -color orchid3 -linewidth 2 -symbol none
1086 $graph pen create pen4 -color orange3 -linewidth 2 -symbol none
1087 $graph pen create pen5 -color blue2 -linewidth 2 -symbol none
1088 $graph pen create pen6 -color gray55 -linewidth 2 -symbol none
1089
1090 $graph element create Spectrum1 -pen pen1 -xdata $xvec -ydata [dict get $yvec 1]
1091 $graph element create Spectrum2 -pen pen2 -xdata $xvec -ydata [dict get $yvec 2]
1092 $graph element create Spectrum3 -pen pen3 -xdata $xvec -ydata [dict get $yvec 3]
1093 $graph element create Spectrum4 -pen pen4 -xdata $xvec -ydata [dict get $yvec 4]
1094 $graph element create Spectrum5 -pen pen5 -xdata $xvec -ydata [dict get $yvec 5]
1095 $graph element create Spectrum6 -pen pen6 -xdata $xvec -ydata [dict get $yvec 6]
1096 }
1097
1098# -------------------------------------------------------------------------
1099
1100 OscDisplay instproc coor_update {W x y} {
1101 my instvar xvec yvec graph
1102 my instvar config
1103
1104 $W crosshairs configure -position @${x},${y}
1105
1106 set index [$W axis invtransform x $x]
1107 set index [::tcl::mathfunc::round $index]
1108 catch {
1109 ${config}.chan_frame.chan1_value configure -text [[dict get $yvec 1] index $index]
1110 ${config}.chan_frame.chan2_value configure -text [[dict get $yvec 2] index $index]
1111 ${config}.chan_frame.chan3_value configure -text [[dict get $yvec 3] index $index]
1112 ${config}.chan_frame.chan4_value configure -text [[dict get $yvec 4] index $index]
1113 ${config}.chan_frame.chan5_value configure -text [[dict get $yvec 5] index $index]
1114 ${config}.chan_frame.chan6_value configure -text [[dict get $yvec 6] index $index]
1115 ${config}.chan_frame.axisx_value configure -text ${index}.0
1116 }
1117 }
1118# -------------------------------------------------------------------------
1119
1120 OscDisplay instproc crosshairs {graph} {
1121 set method [myproc coor_update]
1122 bind $graph <Motion> [list [self] coor_update %W %x %y]
1123 bind $graph <Leave> {
1124 %W crosshairs off
1125 }
1126 bind $graph <Enter> {
1127 %W crosshairs on
1128 }
1129 }
1130
1131# -------------------------------------------------------------------------
1132
1133 OscDisplay instproc chan_update {name key op} {
1134 my instvar config graph chan
1135
1136 if {$chan(${key})} {
1137 $graph pen configure pen${key} -linewidth 2
1138 } else {
1139 $graph pen configure pen${key} -linewidth 0
1140 }
1141 }
1142
1143# -------------------------------------------------------------------------
1144
1145 OscDisplay instproc recs_val_update args {
1146 my instvar recs_val
1147 if {[string equal $recs_val {}]} {
1148 set recs_val 0
1149 }
1150 }
1151
1152# -------------------------------------------------------------------------
1153
1154 OscDisplay instproc last_update args {
1155 my instvar graph last
1156
1157 set first [expr {$last - 1}]
1158
1159 $graph axis configure x -min ${first}0000 -max ${last}0000
1160 }
1161
1162# -------------------------------------------------------------------------
1163
1164 OscDisplay instproc thrs_update {reset args} {
1165 my instvar controller config thrs thrs_val
1166
1167 if {[string equal $thrs_val {}]} {
1168 set thrs_val 0
1169 }
1170
1171 if {$thrs} {
1172 ${config}.thrs_field configure -state normal
1173 set value [format {%03x} $thrs_val]
1174 } else {
1175 ${config}.thrs_field configure -state disabled
1176 set value 000
1177 }
1178
1179 set command {}
1180 if {$reset} {
1181 append command 0002000500041${value}
1182 }
1183 append command 0002000500040${value}
1184
1185 $controller usbCmd $command
1186 }
1187
1188# -------------------------------------------------------------------------
1189
1190 OscDisplay instproc data_update args {
1191 my instvar data yvec
1192 my instvar graph chan waiting sequence auto
1193
1194 usb::convertOsc $data $yvec
1195
1196 foreach {key value} [array get chan] {
1197 $graph pen configure pen${key} -dashes 0
1198 }
1199
1200 set waiting 0
1201
1202 if {$sequence} {
1203 my sequence_register
1204 } elseif {$auto} {
1205 after 1000 [myproc acquire_start]
1206 }
1207 }
1208
1209# -------------------------------------------------------------------------
1210
1211 OscDisplay instproc acquire_start {} {
1212 my instvar graph chan controller waiting
1213
1214 foreach {key value} [array get chan] {
1215 $graph pen configure pen${key} -dashes dot
1216 }
1217
1218 # restart
1219 my thrs_update 1
1220
1221 set waiting 1
1222
1223 after 200 [myproc acquire_loop]
1224 }
1225
1226# -------------------------------------------------------------------------
1227
1228 OscDisplay instproc acquire_loop {} {
1229 my instvar controller waiting
1230
1231# set size 262144
1232# set size 10000
1233 set size 60000
1234
1235 set value [format {%08x} [expr {$size * 4}]]
1236
1237 set command 00011000000200000001[string range $value 0 3]0003[string range $value 4 7]00050000
1238
1239 $controller usbCmdReadRaw $command [expr {$size * 8}] [myvar data]
1240
1241 if {$waiting} {
1242 after 200 [myproc acquire_loop]
1243 }
1244 }
1245
1246# -------------------------------------------------------------------------
1247
1248 OscDisplay instproc auto_update args {
1249 my instvar config auto
1250
1251 if {$auto} {
1252 ${config}.recs_field configure -state disabled
1253 ${config}.sequence configure -state disabled
1254 ${config}.acquire configure -state disabled
1255 ${config}.register configure -state disabled
1256 ${config}.recover configure -state disabled
1257
1258 my acquire_start
1259 } else {
1260 ${config}.recs_field configure -state normal
1261 ${config}.sequence configure -state active
1262 ${config}.acquire configure -state active
1263 ${config}.register configure -state active
1264 ${config}.recover configure -state active
1265 }
1266 }
1267
1268# -------------------------------------------------------------------------
1269
1270 OscDisplay instproc save_data {fname} {
1271 my instvar data
1272
1273 set fid [open $fname w+]
1274 fconfigure $fid -translation binary -encoding binary
1275
1276# puts -nonewline $fid [binary format "H*iH*" "1f8b0800" [clock seconds] "0003"]
1277# puts -nonewline $fid [zlib deflate $data]
1278 puts -nonewline $fid $data
1279# puts -nonewline $fid [binary format i [zlib crc32 $data]]
1280# puts -nonewline $fid [binary format i [string length $data]]
1281
1282 close $fid
1283 }
1284
1285# -------------------------------------------------------------------------
1286
1287 OscDisplay instproc open_data {} {
1288 set types {
1289 {{Data Files} {.dat} }
1290 {{All Files} * }
1291 }
1292
1293 set fname [tk_getOpenFile -filetypes $types]
1294 if {[string equal $fname {}]} {
1295 return
1296 }
1297
1298 set x [catch {
1299 set fid [open $fname r+]
1300 fconfigure $fid -translation binary -encoding binary
1301# set size [file size $fname]
1302# seek $fid 10
1303# my set data [zlib inflate [read $fid [expr {$size - 18}]]]
1304 my set data [read $fid]
1305 close $fid
1306 }]
1307
1308 if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } {
1309 tk_messageBox -icon error \
1310 -message "An error occurred while reading \"$fname\""
1311 } else {
1312 tk_messageBox -icon info \
1313 -message "File \"$fname\" read successfully"
1314 }
1315 }
1316
1317# -------------------------------------------------------------------------
1318
1319 OscDisplay instproc register {} {
1320 set types {
1321 {{Data Files} {.dat} }
1322 {{All Files} * }
1323 }
1324
1325 set stamp [clock format [clock seconds] -format {%Y%m%d_%H%M%S}]
1326 set fname oscillogram_${stamp}.dat
1327
1328 set fname [tk_getSaveFile -filetypes $types -initialfile $fname]
1329 if {[string equal $fname {}]} {
1330 return
1331 }
1332
1333 if {[catch {my save_data $fname} result]} {
1334 tk_messageBox -icon error \
1335 -message "An error occurred while writing to \"$fname\""
1336 } else {
1337 tk_messageBox -icon info \
1338 -message "File \"$fname\" written successfully"
1339 }
1340 }
1341
1342# -------------------------------------------------------------------------
1343
1344 OscDisplay instproc recover {} {
1345 my open_data
1346 }
1347
1348# -------------------------------------------------------------------------
1349
1350 OscDisplay instproc sequence_start {} {
1351 my instvar config recs_val recs_bak directory counter sequence
1352
1353 set counter 1
1354 if {$counter > $recs_val} {
1355 return
1356 }
1357
1358 set directory [tk_chooseDirectory -initialdir $directory -title {Choose a directory}]
1359
1360 if {[string equal $directory {}]} {
1361 return
1362 }
1363
1364 ${config}.recs_field configure -state disabled
1365 ${config}.sequence configure -text {Stop Recording} -command [myproc sequence_stop]
1366 ${config}.acquire configure -state disabled
1367 ${config}.register configure -state disabled
1368 ${config}.recover configure -state disabled
1369
1370 set recs_bak $recs_val
1371
1372 set sequence 1
1373
1374 my acquire_start
1375 }
1376
1377# -------------------------------------------------------------------------
1378
1379 OscDisplay instproc sequence_register {} {
1380 my instvar config recs_val recs_bak directory counter
1381
1382 set fname [file join $directory oscillogram_$counter.dat]
1383
1384 my incr counter
1385
1386 if {[catch {my save_data $fname} result]} {
1387 tk_messageBox -icon error \
1388 -message "An error occurred while writing to \"$fname\""
1389 } elseif {$counter <= $recs_bak} {
1390 set recs_val [expr {$recs_bak - $counter}]
1391 my acquire_start
1392 return
1393 }
1394
1395 my sequence_stop
1396 }
1397
1398# -------------------------------------------------------------------------
1399
1400 OscDisplay instproc sequence_stop {} {
1401 my instvar config recs_val recs_bak sequence
1402
1403 set sequence 0
1404
1405 set recs_val $recs_bak
1406
1407 ${config}.recs_field configure -state normal
1408 ${config}.sequence configure -text {Start Recording} -command [myproc sequence_start]
1409 ${config}.acquire configure -state active
1410 ${config}.register configure -state active
1411 ${config}.recover configure -state active
1412 }
1413
1414# -------------------------------------------------------------------------
1415
1416 namespace export MuxDisplay
1417 namespace export HstDisplay
1418 namespace export CfgDisplay
1419 namespace export OscDisplay
1420}
1421
1422set notebook [::blt::tabnotebook .notebook -borderwidth 1 -selectforeground black -side bottom]
1423
1424grid ${notebook} -row 0 -column 0 -sticky news -pady 5
1425
1426grid rowconfigure . 0 -weight 1
1427grid columnconfigure . 0 -weight 1
1428
1429::mca::UsbController usb
1430
1431set window [frame ${notebook}.mux]
1432$notebook insert end -text "Interconnect" -window $window -fill both
1433::mca::MuxDisplay mux -master $window -controller usb
1434
1435set window [frame ${notebook}.cfg]
1436$notebook insert end -text "Configuration" -window $window -fill both
1437::mca::CfgDisplay cfg -master $window -controller usb
1438
1439set window [frame ${notebook}.hst]
1440$notebook insert end -text "Histogram" -window $window -fill both
1441::mca::HstDisplay hst -number 0 -master $window -controller usb
1442
1443set window [frame ${notebook}.ept]
1444$notebook insert end -text "Oscilloscope" -window $window -fill both
1445::mca::OscDisplay osc -master $window -controller usb
1446
1447update
1448
1449cfg start
1450
1451mux start
1452
1453hst start
1454
1455osc start
Note: See TracBrowser for help on using the repository browser.