Index: /sandbox/MultiChannelUSB/UserInterface.tcl
===================================================================
--- /sandbox/MultiChannelUSB/UserInterface.tcl	(revision 142)
+++ /sandbox/MultiChannelUSB/UserInterface.tcl	(revision 143)
@@ -16,10 +16,54 @@
     namespace import ::blt::tabnotebook
 
-    proc validate {max value} {
+# -------------------------------------------------------------------------
+
+    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] > 4} {
+        } elseif {[string length $value] > $size} {
             return 0
         } else {
@@ -30,62 +74,161 @@
 # -------------------------------------------------------------------------
 
-    Class Display
-
-# -------------------------------------------------------------------------
-
-    Display instproc usbCmd {command} {
-        global usb_handle
-
-        if {[catch {$usb_handle writeRaw [usb::convert $command]} result]} {
-            puts {Error during write}
-            puts $result
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    Display instproc usbCmdRead {command width size} {
-        global usb_handle
-
+    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 usb_data {}
-        if {[catch {$usb_handle readHex $width $size} result]} {
-            puts {Error during read}
-            puts $result
-            set result {}
-        }
-
-        my set data $result
-    }
-
-# -------------------------------------------------------------------------
-
-    Display instproc usbCmdReadEpt {command size} {
-        global usb_handle
-
+        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 usb_data {}
-        if {[catch {$usb_handle readEpt $size} result]} {
-            puts {Error during read}
-            puts $result
-            set result {}
-        }
-
-        my set data $result
-    }
-
-# -------------------------------------------------------------------------
-
-    Class CfgDisplay -superclass Display -parameter {
+        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}
-    }
-
-# -------------------------------------------------------------------------
-
-    CfgDisplay instproc init {} {
-
-        my reset
+        {controller}
+    }
+
+# -------------------------------------------------------------------------
+
+    SpiDisplay instproc init {} {
 
         my setup
@@ -96,5 +239,5 @@
 # -------------------------------------------------------------------------
 
-    CfgDisplay instproc destroy {} {
+    SpiDisplay instproc destroy {} {
         next
     }
@@ -102,46 +245,28 @@
 # -------------------------------------------------------------------------
 
-    CfgDisplay instproc reset {} {
-    }
-
-# -------------------------------------------------------------------------
-
-    CfgDisplay instproc start {} {
+    SpiDisplay instproc start {} {
         my instvar config
 
         trace add variable [myvar dac1] write [myproc dac1_update]
         trace add variable [myvar dac2] write [myproc dac2_update]
-        trace add variable [myvar polar] write [myproc polar_update]
 
         ${config(1)}.dac1 set 0
         ${config(1)}.dac2 set 0
-
-        ${config(2)}.polar1 select
-        ${config(2)}.polar2 select
-        ${config(2)}.polar3 select
-    }
-
-# -------------------------------------------------------------------------
-
-    CfgDisplay instproc setup {} {
+    }
+
+# -------------------------------------------------------------------------
+
+    SpiDisplay instproc setup {} {
         my instvar number master
         my instvar config
 
         set config(1) [labelframe ${master}.cfg1 -borderwidth 1 -relief sunken -text {DAC}]
-        set config(2) [labelframe ${master}.cfg2 -borderwidth 1 -relief sunken -text {polarity inversion}]
 
         frame ${config(1)}.limits
-        label ${config(1)}.limits.min -text {0.0V}
-        label ${config(1)}.limits.max -text {-3.3V}
-
-        scale ${config(1)}.dac1 -orient vertical -from 0 -to 4095 -tickinterval 500 -variable [myvar dac1]
-        scale ${config(1)}.dac2 -orient vertical -from 0 -to 4095 -tickinterval 0 -variable [myvar dac2]
-
-        checkbutton ${config(2)}.polar1 -text {channel 1} -variable [myvar polar(1)]
-        checkbutton ${config(2)}.polar2 -text {channel 2} -variable [myvar polar(2)]
-        checkbutton ${config(2)}.polar3 -text {channel 3} -variable [myvar polar(3)]
-
-        grid ${config(1)} -sticky ns
-        grid ${config(2)} -sticky ew -pady 7
+        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
@@ -150,63 +275,407 @@
         grid ${config(1)}.dac1 ${config(1)}.dac2 ${config(1)}.limits -sticky ns -pady 7
 
-        grid ${config(2)}.polar1
-        grid ${config(2)}.polar2
-        grid ${config(2)}.polar3
-
+        
+        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 ${config(1)} 0 -weight 1
-        grid rowconfigure ${config(2)} 0 -weight 1
-    }
-
-# -------------------------------------------------------------------------
-
-    CfgDisplay instproc dac1_update args {
-        my instvar dac1
-
-        set value [format {%03x} $dac1]
-        set command 0005012000050030000500[string range $value 0 1]000502[string index $value 2]0
-
-        my usbCmd $command
-    }
-
-# -------------------------------------------------------------------------
-
-    CfgDisplay instproc dac2_update args {
-        my instvar dac2
-
-        set value [format {%03x} $dac2]
-        set command 0005012400050030000500[string range $value 0 1]000502[string index $value 2]0
-
-        my usbCmd $command
-    }
-
-# -------------------------------------------------------------------------
-
-    CfgDisplay instproc polar_update args {
-        my instvar polar
-
-        set value [format {0%x%x%x} $polar(3) $polar(2) $polar(1)]
-
-        my usbCmd 000A${value}
-    }
-
-# -------------------------------------------------------------------------
-
-    Class OscDisplay -superclass Display -parameter {
+        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}
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc init {} {
-        my instvar data xvec yvec
-
-        set xvec [vector #auto]
-        set yvec [vector #auto]
-        # fill one vector for the x axis with 1025 points
-        $xvec seq 0 1024
-
-        my reset
+        {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
@@ -217,5 +686,5 @@
 # -------------------------------------------------------------------------
 
-    OscDisplay instproc destroy {} {
+    HstDisplay instproc destroy {} {
         next
     }
@@ -223,448 +692,135 @@
 # -------------------------------------------------------------------------
 
-    OscDisplay instproc reset {} {
-        my instvar data xvec yvec
-
-        set data {}
-
-        $yvec set {}
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc start {} {
-        my instvar config trig_mux disp_mux
-
-        set trig_mux 2
-        set disp_mux 2
+    HstDisplay instproc start {} {
+        my instvar config
 
         trace add variable [myvar data] write [myproc data_update]
-        trace add variable [myvar auto] write [myproc auto_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_val_update]
-        trace add variable [myvar disp_val] write [myproc disp_val_update]
-        trace add variable [myvar trig_val] write [myproc trig_val_update]
-
-        ${config}.auto_check select
+        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 1278
-        ${config}.disp_uwt2 select
-        ${config}.trig_uwt2 select
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc setup {} {
+        ${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 data xvec yvec
-        my instvar config auto thrs thrs_val disp_val trig_val
+        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 2 -dashes { 1 1 }
+        $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 1024
-        $graph axis configure y -min 0 -max 4100
-
-        set config [frame ${master}.config]
-
-        checkbutton ${config}.auto_check -text {auto update} -variable [myvar auto]
-
-        frame ${config}.spc1 -width 10 -height 10
+        $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 %P}
-
-        frame ${config}.spc2 -width 10 -height 10
-
-        label ${config}.disp -text {display input}
-        radiobutton ${config}.disp_data -text {raw data} -variable [myvar disp_val] -value data
-        radiobutton ${config}.disp_uwt1 -text {filter 1} -variable [myvar disp_val] -value uwt1
-        radiobutton ${config}.disp_uwt2 -text {filter 2} -variable [myvar disp_val] -value uwt2
-        radiobutton ${config}.disp_uwt3 -text {filter 3} -variable [myvar disp_val] -value uwt3
-        radiobutton ${config}.disp_base -text {baseline} -variable [myvar disp_val] -value base
-#        radiobutton ${config}.disp_sum8 -text {sum of 8} -variable [myvar disp_val] -value sum8
-
-        frame ${config}.spc3 -width 10 -height 10
-
-        label ${config}.trig -text {trigger input}
-        radiobutton ${config}.trig_data -text {raw data} -variable [myvar trig_val] -value data
-        radiobutton ${config}.trig_uwt1 -text {filter 1} -variable [myvar trig_val] -value uwt1
-        radiobutton ${config}.trig_uwt2 -text {filter 2} -variable [myvar trig_val] -value uwt2
-        radiobutton ${config}.trig_uwt3 -text {filter 3} -variable [myvar trig_val] -value uwt3
-        radiobutton ${config}.trig_base -text {baseline} -variable [myvar trig_val] -value base
-#        radiobutton ${config}.trig_sum8 -text {sum of 8} -variable [myvar trig_val] -value sum8
-
-        frame ${config}.spc4 -width 10 -height 10
-
-        button ${config}.acquire -text Acquire \
-            -bg green -activebackground green -command [myproc acquire]
-        button ${config}.restart -text Restart \
-            -bg yellow -activebackground yellow -command [myproc restart]
+            -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}.auto_check -sticky w
+        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}.spc2
-        grid ${config}.disp -sticky w -pady 1 -padx 3
-        grid ${config}.disp_data -sticky w
-        grid ${config}.disp_uwt1 -sticky w
-        grid ${config}.disp_uwt2 -sticky w
-        grid ${config}.disp_uwt3 -sticky w
-        grid ${config}.disp_base -sticky w
-#        grid ${config}.disp_sum8 -sticky w
-        grid ${config}.spc3
-        grid ${config}.trig -sticky w -pady 1 -padx 3
-        grid ${config}.trig_data -sticky w
-        grid ${config}.trig_uwt1 -sticky w
-        grid ${config}.trig_uwt2 -sticky w
-        grid ${config}.trig_uwt3 -sticky w
-        grid ${config}.trig_base -sticky w
-#        grid ${config}.disp_sum8 -sticky w
-        grid ${config}.spc4
-        grid ${config}.acquire -sticky ew -pady 3 -padx 5
-        grid ${config}.restart -sticky ew -pady 3 -padx 5
-        grid ${config}.register -sticky ew -pady 3 -padx 5
-
-        grid ${graph} -row 0 -column 0 -sticky news
-        grid ${config} -row 0 -column 1
-
-        grid rowconfigure ${master} 0 -weight 1
-        grid columnconfigure ${master} 0 -weight 1
-        grid columnconfigure ${master} 1 -weight 0 -minsize 80
-
-        # enable zooming
-        Blt_ZoomStack $graph
-
-        #bind .graph <Motion> {%W crosshairs configure -position @%x,%y}
-
-        # create one element with data for the x and y axis, no dots
-        $graph element create Spectrum1 -symbol none -xdata $xvec -ydata $yvec
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc data_update args {
-        my instvar data yvec
-        $yvec set $data
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc auto_update args {
-        my instvar config auto after_handle
-
-        if {$auto} {
-            ${config}.acquire configure -state disabled
-            ${config}.restart configure -state disabled
-            ${config}.register configure -state disabled
-
-            my acquire_restart_loop
-        } else {
-            if {[my exists after_handle]} {
-                after cancel $after_handle
-            }
-            ${config}.acquire configure -state active
-            ${config}.restart configure -state active
-            ${config}.register configure -state active
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc thrs_update args {
-        my instvar config number thrs thrs_val
-
-        set val_addr [format %04x [expr {17 + ${number}}]]
-
-        if {$thrs} {
-            ${config}.thrs_field configure -state normal
-            my thrs_val_update
-        } else {
-            ${config}.thrs_field configure -state disabled
-            my usbCmd ${val_addr}0000
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc thrs_val_update args {
-        my instvar config number thrs_val
-
-        if {[string equal $thrs_val {}]} {
-            set thrs_val 0
-        }
-
-        set val_addr [format %04x [expr {17 + ${number}}]]
-        set value [format %04x $thrs_val]
-
-        my usbCmd ${val_addr}${value}
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc mux {} {
-        my instvar trig_mux disp_mux
-
-        format {00%x%x} $trig_mux $disp_mux
-    }
-
-# ------------------------------------------------------------------------
-
-    OscDisplay instproc disp_val_update args {
-        my instvar number disp_val disp_mux
-
-        set mux_addr [format %04x [expr {20 + ${number}}]]
-
-        switch -- $disp_val {
-            data {
-                set disp_mux 0
-                my usbCmd ${mux_addr}[my mux]
-            }
-            uwt1 {
-                set disp_mux 1
-                my usbCmd ${mux_addr}[my mux]
-            }
-            uwt2 {
-                set disp_mux 2
-                my usbCmd ${mux_addr}[my mux]
-            }
-            uwt3 {
-                set disp_mux 3
-                my usbCmd ${mux_addr}[my mux]
-            }
-            base {
-                set disp_mux 4
-                my usbCmd ${mux_addr}[my mux]
-            }
-        }
-    }
-
-# ------------------------------------------------------------------------
-
-    OscDisplay instproc trig_val_update args {
-        my instvar number trig_val trig_mux
-
-        set mux_addr [format %04x [expr {20 + ${number}}]]
-
-        switch -- $trig_val {
-            data {
-                set trig_mux 0
-                my usbCmd ${mux_addr}[my mux]
-            }
-            uwt1 {
-                set trig_mux 1
-                my usbCmd ${mux_addr}[my mux]
-            }
-            uwt2 {
-                set trig_mux 2
-                my usbCmd ${mux_addr}[my mux]
-            }
-            uwt3 {
-                set trig_mux 3
-                my usbCmd ${mux_addr}[my mux]
-            }
-            base {
-                set trig_mux 4
-                my usbCmd ${mux_addr}[my mux]
-            }
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc save_data {data} {
-        set file [tk_getSaveFile]
-        if {[string equal $file {}]} {
-            return
-        }
-
-        set x [catch {set fid [open $file w+]}]
-        set y [catch {puts $fid $data}]
-        set z [catch {close $fid}]
-
-        if { $x || $y || $z || ![file exists $file] || ![file isfile $file] || ![file readable $file] } {
-            tk_messageBox -icon error \
-                -message "An error occurred while writing to \"$file\""
-        } else {
-            tk_messageBox -icon info \
-                -message "File \"$file\" written successfully"
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc acquire {} {
-        my instvar number
-        my usbCmdRead 0002000${number} 2 1024
-   }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc restart {} {
-        my instvar number
-        my usbCmd 0001000${number}
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc register {} {
-        my save_data [my set data]
-    }
-
-# -------------------------------------------------------------------------
-
-    OscDisplay instproc acquire_restart_loop {} {
-        my instvar number after_handle
-
-        my acquire
-        my restart
-
-        set after_handle [after 1000 [myproc acquire_restart_loop]]
-    }
-
-# -------------------------------------------------------------------------
-
-    Class HstDisplay -superclass Display -parameter {
-        {number}
-        {master}
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc init {} {
-        my instvar data xvec yvec
-
-        set xvec [vector #auto]
-        set yvec [vector #auto]
-        # fill one vector for the x axis with 4097 points
-        $xvec seq 0 4096
-
-        my reset
-
-        my setup
-
-        next
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc destroy {} {
-        next
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc reset {} {
-        my instvar data xvec yvec
-
-        set data {}
-
-        $yvec set {}
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc start {} {
-        my instvar config base_mux peak_mux
-
-        set base_mux 0
-        set peak_mux 1
-
-        trace add variable [myvar axis] write [myproc axis_update]
-        trace add variable [myvar data] write [myproc data_update]
-        trace add variable [myvar auto] write [myproc auto_update]
-        trace add variable [myvar peak] write [myproc peak_update]
-        trace add variable [myvar thrs] write [myproc thrs_update]
-        trace add variable [myvar thrs_val] write [myproc thrs_val_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 deselect
-        ${config}.auto_check select
-        ${config}.peak_check select
-
-        ${config}.thrs_check select
-        ${config}.thrs_field set 1278
-
-        ${config}.base_const select
-        ${config}.base_field set 35
-        ${config}.base_check deselect
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc setup {} {
-        my instvar number master
-        my instvar data xvec yvec graph
-        my instvar config auto thrs thrs_val base base_typ base_val
-
-        # create a graph widget and show a grid
-        set graph [graph ${master}.graph -height 250 -leftmargin 80]
-        $graph crosshairs configure -hide no -linewidth 2 -dashes { 1 1 }
-        $graph grid configure -hide no
-        $graph legend configure -hide yes
-        $graph axis configure x -min 0 -max 4096
-
-        set config [frame ${master}.config]
-
-        checkbutton ${config}.axis_check -text {log scale} -variable [myvar axis]
-
-        frame ${config}.spc1 -width 10 -height 10
-
-        checkbutton ${config}.auto_check -text {auto update} -variable [myvar auto]
-
-        frame ${config}.spc2 -width 10 -height 10
-
-        checkbutton ${config}.peak_check -text {peak detect} -variable [myvar peak]
-
-        frame ${config}.spc3 -width 10 -height 10
-
-        checkbutton ${config}.thrs_check -text threshold -variable [myvar thrs]
-        spinbox ${config}.thrs_field -from 1 -to 4095 \
-            -increment 5 -width 10 -textvariable [myvar thrs_val] \
-            -validate all -vcmd {::mca::validate 4095 %P}
-
-        frame ${config}.spc4 -width 10 -height 10
-
-        checkbutton ${config}.base_check -text baseline -variable [myvar base]
-        radiobutton ${config}.base_auto -text automatic -variable [myvar base_typ] -value auto
-        radiobutton ${config}.base_const -text constant -variable [myvar base_typ] -value const
-        spinbox ${config}.base_field -from 1 -to 4095 \
-            -increment 5 -width 10 -textvariable [myvar base_val] \
-            -validate all -vcmd {::mca::validate 4095 %P}
-
-        frame ${config}.spc5 -width 10 -height 10
-
-        button ${config}.acquire -text Acquire \
-            -bg green -activebackground green -command [myproc acquire]
-        button ${config}.restart -text Restart \
-            -bg yellow -activebackground yellow -command [myproc restart]
-        button ${config}.register -text Register \
-            -bg lightblue -activebackground lightblue -command [myproc register]
-
-        grid ${config}.axis_check -sticky w
-        grid ${config}.spc1
-        grid ${config}.auto_check -sticky w
-        grid ${config}.spc2
-        grid ${config}.peak_check -sticky w
-        grid ${config}.spc3
-        grid ${config}.thrs_check -sticky w
-        grid ${config}.thrs_field -sticky ew -pady 1 -padx 5
-        grid ${config}.spc4
+        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}.spc5
-        grid ${config}.acquire -sticky ew -pady 3 -padx 5
-        grid ${config}.restart -sticky ew -pady 3 -padx 5
+        grid ${config}.spc7
         grid ${config}.register -sticky ew -pady 3 -padx 5
 
@@ -676,11 +832,43 @@
         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 <Motion> {%W crosshairs configure -position @%x,%y}
 
         # create one element with data for the x and y axis, no dots
-        $graph element create Spectrum1 -symbol none -smooth step -xdata $xvec -ydata $yvec
+        $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 <Motion> [list [self] coor_update %W %x %y]
+        bind $graph <Leave> {
+            %W crosshairs off
+        }
+        bind $graph <Enter> {
+            %W crosshairs on
+        }
     }
 
@@ -698,81 +886,22 @@
 # -------------------------------------------------------------------------
 
-    HstDisplay instproc data_update args {
-        my instvar data yvec
-        $yvec set $data
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc auto_update args {
-        my instvar auto after_handle
-        my instvar config
-        if {$auto} {
-            ${config}.acquire configure -state disabled
-            ${config}.register configure -state disabled
-
-            my acquire_loop
-        } else {
-            if {[my exists after_handle]} {
-                after cancel $after_handle
-            }
-            ${config}.acquire configure -state active
-            ${config}.register configure -state active
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc mux {} {
-        my instvar base_mux peak_mux
-
-        format {00%x%x} $base_mux $peak_mux
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc peak_update args {
-        my instvar number peak peak_mux
-
-        set mux_addr [format %04x [expr {23 + ${number}}]]
-
-        if {$peak} {
-            set peak_mux 1
-            my usbCmd ${mux_addr}[my mux]
-        } else {
-            set peak_mux 0
-            my usbCmd ${mux_addr}[my mux]
-        }
-    }
-
-# -------------------------------------------------------------------------
-
     HstDisplay instproc thrs_update args {
-        my instvar config number thrs thrs_val
-
-        set val_addr [format %04x [expr {14 + ${number}}]]
+        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
-            my thrs_val_update
+            set value [format %03x $thrs_val]
         } else {
             ${config}.thrs_field configure -state disabled
-            my usbCmd ${val_addr}0000
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc thrs_val_update args {
-        my instvar config number thrs_val
-
-        if {[string equal $thrs_val {}]} {
-            set thrs_val 0
-        }
-
-        set val_addr [format %04x [expr {14 + ${number}}]]
-        set value [format %04x $thrs_val]
-
-        my usbCmd ${val_addr}${value}
+            set value 000
+        }
+
+        $controller usbCmd 000200${val_addr}00040${value}
     }
 
@@ -780,8 +909,7 @@
 
     HstDisplay instproc base_update args {
-        my instvar config number base base_val base_mux
-
-        set mux_addr [format %04x [expr {23 + ${number}}]]
-        set val_addr [format %04x [expr {11 + ${number}}]]
+        my instvar controller config number base base_typ
+
+        set val_addr [format %02x [expr {7 + 2 * ${number}}]]
 
         if {$base} {
@@ -793,6 +921,5 @@
             ${config}.base_const configure -state disabled
             ${config}.base_field configure -state disabled
-            set base_mux 0
-            my usbCmd ${mux_addr}[my mux]${val_addr}0000
+            $controller usbCmd 000200${val_addr}0004${base_typ}000
         }
     }
@@ -801,22 +928,16 @@
 
     HstDisplay instproc base_typ_update args {
-        my instvar config number base_typ base_val base_mux
-
-        set mux_addr [format %04x [expr {23 + ${number}}]]
-        set val_addr [format %04x [expr {11 + ${number}}]]
-        set value [format %04x $base_val]
+        my instvar config base_typ
 
         switch -- $base_typ {
-            auto {
+            1 {
                 ${config}.base_field configure -state disabled
-                set base_mux 1
-                my usbCmd ${mux_addr}[my mux]
             }
-            const {
+            0 {
                 ${config}.base_field configure -state normal
-                set base_mux 0
-                my usbCmd ${mux_addr}[my mux]${val_addr}${value}
             }
         }
+
+        my base_val_update
     }
 
@@ -824,5 +945,5 @@
 
     HstDisplay instproc base_val_update args {
-        my instvar number base_val
+        my instvar controller number base_typ base_val
 
         if {[string equal $base_val {}]} {
@@ -830,8 +951,193 @@
         }
 
-        set val_addr [format %04x [expr {11 + ${number}}]]
-        set value [format %04x $base_val]
-
-        my usbCmd ${val_addr}${value}
+        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]
+        }
     }
 
@@ -839,33 +1145,62 @@
 
     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
-        my usbCmdRead 0002001${number} 4 4096
-   }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc restart {} {
-        my instvar number
-        my usbCmd 0001001${number}
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc save_data {data} {
-        set file [tk_getSaveFile]
-        if {[string equal $file {}]} {
+
+        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 $file w+]}]
-        set y [catch {puts $fid $data}]
-        set z [catch {close $fid}]
-
-        if { $x || $y || $z || ![file exists $file] || ![file isfile $file] || ![file readable $file] } {
+        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 \"$file\""
+                -message "An error occurred while writing to \"$fname\""
         } else {
             tk_messageBox -icon info \
-                -message "File \"$file\" written successfully"
+                -message "File \"$fname\" written successfully"
         }
     }
@@ -874,39 +1209,27 @@
 
     HstDisplay instproc register {} {
-        my save_data [my set data]
-    }
-
-# -------------------------------------------------------------------------
-
-    HstDisplay instproc acquire_loop {} {
-        my instvar number after_handle
-
-        my acquire
-
-        set after_handle [after 1000 [myproc acquire_loop]]
-    }
-
-# -------------------------------------------------------------------------
-
-    Class EptDisplay -superclass Display -parameter {
-        {number}
+        my save_data [join [[myvar yvec] range 0 4095] \n]
+    }
+
+# -------------------------------------------------------------------------
+
+    Class CntDisplay -parameter {
         {master}
-    }
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc init {} {
-        my instvar data xvec yvec
-
-        set xvec [vector #auto]
-
-        for {set i 0} {$i < 11} {incr i} {
-          set yvec($i) [vector #auto]
-        }
-
-        # fill one vector for the x axis
-        $xvec seq 0 10000
-
-        my reset
+        {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
@@ -917,5 +1240,5 @@
 # -------------------------------------------------------------------------
 
-    EptDisplay instproc destroy {} {
+    CntDisplay instproc destroy {} {
         next
     }
@@ -923,112 +1246,575 @@
 # -------------------------------------------------------------------------
 
-    EptDisplay instproc reset {} {
-        my instvar data xvec yvec
-        my instvar number_val directory
-
-        set data {}
-
-        set directory $::env(HOMEPATH)
-        set number_val 10
-
-        for {set i 0} {$i < 11} {incr i} {
-          $yvec($i) set {}
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc start {} {
+    CntDisplay instproc start {} {
         my instvar config
 
-        trace add variable [myvar recs_val] write [myproc recs_val_update]
         trace add variable [myvar data] write [myproc data_update]
-        trace add variable [myvar last] write [myproc data_update]
-
-    }
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc setup {} {
+
+        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 data xvec yvec graph
-        my instvar config number_val
+        my instvar xvec yvec graph
+        my instvar config
+        my instvar cntr_ms
 
         # create a graph widget and show a grid
-        set display [frame ${master}.display]
-
-        set graph(0) [graph ${display}.graph0 -height 200 -leftmargin 80]
-        $graph(0) crosshairs configure -hide no -linewidth 2 -dashes { 1 1 }
-        $graph(0) grid configure -hide no
-        $graph(0) legend configure -hide yes
-        $graph(0) axis configure x -min 0 -max 10000
-        $graph(0) axis configure y -min 0 -max 4100
-
-        set graph(1) [graph ${display}.graph1 -height 200 -leftmargin 80]
-        $graph(1) crosshairs configure -hide no -linewidth 2 -dashes { 1 1 }
-        $graph(1) grid configure -hide no
-        $graph(1) legend configure -hide yes
-        $graph(1) axis configure x -min 0 -max 10000 -hide yes
-        $graph(1) axis configure y -min 0 -max 4100
-
-        set graph(2) [graph ${display}.graph2 -height 200 -leftmargin 80]
-        $graph(2) crosshairs configure -hide no -linewidth 2 -dashes { 1 1 }
-        $graph(2) grid configure -hide no
-        $graph(2) legend configure -hide yes
-        $graph(2) axis configure x -min 0 -max 10000 -hide yes
-        $graph(2) axis configure y -min 0 -max 4100
-
-        set graph(3) [graph ${display}.graph3 -height 100 -leftmargin 80]
-        $graph(3) crosshairs configure -hide no -linewidth 2 -dashes { 1 1 }
-        $graph(3) grid configure -hide no
-        $graph(3) legend configure -hide yes
-        $graph(3) axis configure x -min 0 -max 10000 -hide yes
-        $graph(3) axis configure y -min 0 -max 25
-
-        scale ${master}.last -orient horizontal -from 1 -to 35 -tickinterval 0 -showvalue no -variable [myvar last]
-
-        set config [frame ${master}.config -width 120]
-
-        label ${config}.recs -text {number of records}
-        spinbox ${config}.recs_field -from 5 -to 100 \
-            -increment 5 -width 10 -textvariable [myvar recs_val] \
-            -validate all -vcmd {::mca::validate 100 %P}
-
-        frame ${config}.spc1 -width 10 -height 10
-
-        button ${config}.sequence -text {Start Recording}  \
-            -bg red -activebackground red -command [myproc sequence]
-
-        frame ${config}.spc2 -width 10 -height 10
-
-        label ${config}.stat -text {}
-
-        frame ${config}.spc3 -width 10 -height 20
-
-        button ${config}.acquire -text Acquire \
-            -bg green -activebackground green -command [myproc acquire]
+        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 <Motion> {%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 <Motion> [list [self] coor_update %W %x %y]
+        bind $graph <Leave> {
+            %W crosshairs off
+        }
+        bind $graph <Enter> {
+            %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}.sequence -sticky ew -pady 3 -padx 5
+        grid ${config}.auto_check -sticky w
         grid ${config}.spc2
-        grid ${config}.stat -sticky w -pady 1 -padx 3
+        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 ${graph(3)} -row 0 -column 0 -sticky news
-        grid ${graph(2)} -row 1 -column 0 -sticky news
-        grid ${graph(1)} -row 2 -column 0 -sticky news
-        grid ${graph(0)} -row 3 -column 0 -sticky news
-
-        grid ${display} -row 0 -column 0 -sticky news
+        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 ${master}.last -row 1 -column 0 -columnspan 2 -sticky ew
 
         grid rowconfigure ${master} 0 -weight 1
@@ -1036,91 +1822,285 @@
         grid columnconfigure ${master} 1 -weight 0 -minsize 120
 
-        grid columnconfigure ${display} 0 -weight 1
-        grid rowconfigure ${display} 0 -weight 1
-        grid rowconfigure ${display} 1 -weight 1
-        grid rowconfigure ${display} 2 -weight 1
-        grid rowconfigure ${display} 3 -weight 1
+        grid columnconfigure ${config}.chan_frame 2 -weight 1
 
         # enable zooming
-        Blt_ZoomStack $graph(0)
-        Blt_ZoomStack $graph(1)
-        Blt_ZoomStack $graph(2)
-        Blt_ZoomStack $graph(3)
-
-        #bind .graph <Motion> {%W crosshairs configure -position @%x,%y}
+        Blt_ZoomStack $graph
+
+        my crosshairs $graph
 
         # create one element with data for the x and y axis, no dots
-        $graph(0) element create Spectrum0 -symbol none -xdata $xvec -ydata $yvec(0)
-        $graph(1) element create Spectrum1 -symbol none -xdata $xvec -ydata $yvec(1)
-        $graph(2) element create Spectrum2 -symbol none -xdata $xvec -ydata $yvec(2)
-        for {set i 3} {$i < 11} {incr i} {
-          $graph(3) element create Spectrum$i -symbol none -xdata $xvec -ydata $yvec($i)
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc recs_val_update args {
+        $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 <Motion> [list [self] coor_update %W %x %y]
+        bind $graph <Leave> {
+            %W crosshairs off
+        }
+        bind $graph <Enter> {
+            %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 number_val 0
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc data_update args {
-        my instvar data xvec yvec graph last
+            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
         
-        $xvec seq ${first}0000 ${last}0000
-        for {set i 0} {$i < 4} {incr i} {
-            $graph($i) axis configure x -min ${first}0000 -max ${last}0000
-        }
-
-        for {set i 0} {$i < 11} {incr i} {
-            $yvec($i) set [lrange [lindex $data $i] ${first}0000 ${last}0000]
-        }
-    }
-
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc save_data {data} {
-        set file [tk_getSaveFile]
-        if {[string equal $file {}]} {
+        $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 $file w+]}]
-        set y [catch {puts $fid $data}]
-        set z [catch {close $fid}]
-
-        if { $x || $y || $z || ![file exists $file] || ![file isfile $file] || ![file readable $file] } {
+        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 writing to \"$file\""
+                -message "An error occurred while reading \"$fname\""
         } else {
             tk_messageBox -icon info \
-                -message "File \"$file\" written successfully"
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc acquire {} {
-        my usbCmdReadEpt 00060000 2097152
-   }
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc register {} {
-        my save_data [my set data]
-    }
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc sequence {} {
-        my instvar config recs_val directory counter
+                -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}]
@@ -1131,258 +2111,90 @@
 
         ${config}.recs_field configure -state disabled
-        ${config}.sequence 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 counter 1
+        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
+        }
         
-        if {$counter <= $recs_val} {
-            ${config}.stat configure -text "record $counter of $recs_val"
-            set after_handle [after 100 [myproc acquire_register_loop]]
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    EptDisplay instproc acquire_register_loop {} {
-        my instvar after_handle
-        my instvar config data recs_val directory counter
-
-        my acquire
-
-        set file [file join $directory ept_$counter.dat.gz]
-
-        set x [catch {set fid [open $file w+]}]
-        fconfigure $fid -translation binary -encoding binary
-
-        set y [catch {
-            puts -nonewline $fid [binary format "H*iH*" "1f8b0800" [clock seconds] "0003"]
-            puts -nonewline $fid [zlib deflate $data]
-            puts -nonewline $fid [binary format i [zlib crc32 $data]]
-            puts -nonewline $fid [binary format i [string length $data]]
-        }]
-
-        set z [catch {close $fid}]
-
-        my incr counter
-
-        if { $x || $y || $z || ![file exists $file] || ![file isfile $file] || ![file readable $file] } {
-            tk_messageBox -icon error -message "An error occurred while writing to \"$file\""
-        } elseif {$counter <= $recs_val} {
-            ${config}.stat configure -text "record $counter of $recs_val"
-            set after_handle [after 100 [myproc acquire_register_loop]]
-            return
-        }
+        my sequence_stop
+    }
+
+# -------------------------------------------------------------------------
+
+    OscDisplay instproc sequence_stop {} {
+        my instvar config recs_val recs_bak sequence
+
+        set sequence 0
         
-        ${config}.stat configure -text {}
+        set recs_val $recs_bak
+
         ${config}.recs_field configure -state normal
-        ${config}.sequence configure -state active
+        ${config}.sequence configure -text {Start Recording} -command [myproc sequence_start]
         ${config}.acquire configure -state active
         ${config}.register configure -state active
-
-    }
-
-# -------------------------------------------------------------------------
-
-    Class MemDisplay -superclass Display -parameter {
-        {number}
-        {master}
-    }
-
-# -------------------------------------------------------------------------
-
-    MemDisplay instproc init {} {
-        my instvar data xvec yvec
-
-        set xvec [vector #auto]
-        set yvec [vector #auto]
-
-        # fill one vector for the x axis
-        $xvec seq 0 10000
-
-        my reset
-
-        my setup
-
-        next
-    }
-
-# -------------------------------------------------------------------------
-
-    MemDisplay instproc destroy {} {
-        next
-    }
-
-# -------------------------------------------------------------------------
-
-    MemDisplay instproc reset {} {
-        my instvar data xvec yvec
-
-        set data {}
-
-        $yvec set {}
-    }
-
-# -------------------------------------------------------------------------
-
-    MemDisplay instproc start {} {
-        my instvar config
-
-        trace add variable [myvar data] write [myproc data_update]
-        trace add variable [myvar last] write [myproc data_update]
-    }
-
-# -------------------------------------------------------------------------
-
-    MemDisplay instproc setup {} {
-        my instvar master
-        my instvar data xvec yvec
-        my instvar config auto thrs thrs_val disp_val trig_val
-
-        # create a graph widget and show a grid
-        set graph [graph ${master}.graph -height 250 -leftmargin 80]
-        $graph crosshairs configure -hide no -linewidth 2 -dashes { 1 1 }
-        $graph grid configure -hide no
-        $graph legend configure -hide yes
-        $graph axis configure x -min 0 -max 10000
-#        $graph axis configure y -min 0 -max 4100
-
-        scale ${master}.last -orient horizontal -from 1 -to 105 -tickinterval 0 -variable [myvar last]
-
-        set config [frame ${master}.config]
-
-        button ${config}.acquire -text Acquire \
-            -bg green -activebackground green -command [myproc acquire]
-        button ${config}.register -text Register \
-            -bg lightblue -activebackground lightblue -command [myproc register]
-
-        grid ${config}.acquire -sticky ew -pady 3 -padx 5
-        grid ${config}.register -sticky ew -pady 3 -padx 5
-
-        grid ${graph} -row 0 -column 0 -sticky news
-        grid ${config} -row 0 -column 1
-
-        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 80
-
-        # enable zooming
-        Blt_ZoomStack $graph
-
-        #bind .graph <Motion> {%W crosshairs configure -position @%x,%y}
-
-        # create one element with data for the x and y axis, no dots
-        $graph element create Spectrum -symbol none -xdata $xvec -ydata $yvec
-    }
-
-# -------------------------------------------------------------------------
-
-    MemDisplay instproc data_update args {
-        my instvar data yvec last
-
-        set first [expr {$last - 1}]
-        $yvec set [lrange $data ${first}0000 ${last}0000]
-    }
-
-# -------------------------------------------------------------------------
-
-    MemDisplay instproc save_data {data} {
-        set file [tk_getSaveFile]
-        if {[string equal $file {}]} {
-            return
-        }
-
-        set x [catch {set fid [open $file w+]}]
-        set y [catch {puts $fid $data}]
-        set z [catch {close $fid}]
-
-        if { $x || $y || $z || ![file exists $file] || ![file isfile $file] || ![file readable $file] } {
-            tk_messageBox -icon error \
-                -message "An error occurred while writing to \"$file\""
-        } else {
-            tk_messageBox -icon info \
-                -message "File \"$file\" written successfully"
-        }
-    }
-
-# -------------------------------------------------------------------------
-
-    MemDisplay instproc acquire {} {
-        my usbCmdRead 00040000 1 524288
-#        my usbCmdRead 00060000 1 1048576
-   }
-
-# -------------------------------------------------------------------------
-
-    MemDisplay instproc register {} {
-        my save_data [my set data]
-    }
-
-# -------------------------------------------------------------------------
-
-    namespace export MemDisplay
-    namespace export EptDisplay
+        ${config}.recover configure -state active
+    }
+
+# -------------------------------------------------------------------------
+
+    namespace export MuxDisplay
     namespace export HstDisplay
+    namespace export CntDisplay
     namespace export OscDisplay
-    namespace export CfgDisplay
 }
 
-set config [frame .config]
 set notebook [::blt::tabnotebook .notebook -borderwidth 1 -selectforeground black -side bottom]
 
-grid ${config} -row 0 -column 0 -sticky ns -padx 3
-grid ${notebook} -row 0 -column 1  -sticky news -pady 5
+grid ${notebook} -row 0 -column 0  -sticky news -pady 5
 
 grid rowconfigure . 0 -weight 1
-grid columnconfigure . 0 -weight 0  -minsize 50
-grid columnconfigure . 1 -weight 1
-
-foreach i {0 1 2} {
-    set channel [expr $i + 1]
-
-    set window [frame ${notebook}.hst_$i]
-    $notebook insert end -text "Histogram $channel" -window $window -fill both
-    ::mca::HstDisplay hst_$i -number $i -master $window
-
-    set window [frame ${notebook}.osc_$i]
-    $notebook insert end -text "Pulse shape $channel" -window $window -fill both
-    ::mca::OscDisplay osc_$i -number $i -master $window
-}
-
-#set window [frame ${notebook}.cfg]
-#$notebook insert end -text "Configuration" -window $window -fill both
-::mca::CfgDisplay cfg -master $config
+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 "EPT" -window $window -fill both
-::mca::EptDisplay ept -master $window
-
-#set window [frame ${notebook}.mem]
-#$notebook insert end -text "Memory test" -window $window -fill both
-#::mca::MemDisplay mem -master $window
-
-set usb_handle {}
-
-while {[catch {usb::connect 0x09FB 0x6001 1 1 0} usb_handle]} {
-    set answer [tk_messageBox -icon error -type retrycancel \
-        -message {Cannot access USB device} -detail $usb_handle]
-    if {[string equal $answer cancel]} break
-}
-
-# cfg reset
-cfg reset
-
-cfg start
-
-foreach i {0 1 2} {
-    hst_$i start
-    osc_$i start
-
-    hst_$i restart
-    osc_$i restart
-}
-
-ept start
-#mem start
+$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
