Przeglądaj źródła

Added new KAPTURE 2 Timings

Matze 6 lat temu
rodzic
commit
4a1c19db63

+ 81 - 39
KCG/base/backend/board/board_config.py

@@ -49,40 +49,55 @@ class BoardConfiguration(QtGui.QWidget):
         """
         Set default values
         """
-        self._config ={
-            'board_version' : 4,
-            'fpga_delay_max': 15,
-            'fpga_delay': 0,
-            'fpga_delay_factor': 150,
+        self._config = {
+            'board_version' : 5,
+
+            'adc_number': 4,
+
+            'bunches_per_turn': 184,
 
             'chip_delay_max': 31,
             'chip_delay' : [4,4,4,4],
             'chip_delay_factor': 3,
 
-            'th_delay_max': 15,
-            'th_delay': 4,
-            'th_delay_factor': 150,
-
-            'adc_number': 4,
-            'adc_delay_max': 15,
-            'adc_delay' : [4,4,4,4],
-            'adc_delay_factor': 150,
-
+            
+            'delay_330_max': 2**10-1,
+            'delay_330_factor': 330,
+            'delay_330_th':   3,
+            'delay_330_adc':  3,
+            'delay_330_fpga': 3,
+
+            #-Kapture 2 only--------------------
+            'delay_25_max' : 2**5-1,
+            'delay_25_factor': 25,
+            'delay_25_th':   1,
+            'delay_25_adc':  1,
+            'delay_25_fpga': 1,
+
+            'clk_div': 6,
+            'clk_div_th':   6,
+            'clk_div_adc':  6,
+            'clk_div_fpga': 6,
+            'clk_div_cascade': 6,
+
+            #-Kapture 1 only-------------------
             'th_to_adc_cycles': 7,
-            'adc_1_delay_individual': -1,
-
-            'bunches_per_turn': 184,
+            #'adc_1_delay_individual': -1,
+            #----------------------------------            
+            
             'turns_observe': 1000,
             'turns_skip': 0,
             'acquisition_count': 10,
             'turns_wait_time': 15,
+            
             'trigger_skip': 0,
             'trigger_timeout': 12,
             'trigger_method': 1,
             'use_trigger': False,
+
             'build_spectrograms': False,
             'pilot_bunch': True,
-            'header': True,# if kcg_config.save_header is True else False
+            'header': True if kcg_config.save_header is True else False,
 
             #Kapture 2
             'adc_offset': [0,0,0,0],
@@ -235,16 +250,34 @@ class BoardConfiguration(QtGui.QWidget):
         Set observers that are always used
         """
         self.observe_write(self._update_header, 'header')
-        self.observe_write(self._set_fpga_delay, 'fpga_delay')
-        self.observe_write(self._set_chip_delay, 'chip_delay')
-        self.observe_write(self._set_th_delay, 'th_delay')
-        self.observe_write(self._set_adc_delay, 'adc_delay')
+        
         self.observe_write(lambda x: pci.write(self.identifier, hex(x), '0x9020'), 'turns_observe')
         self.observe_write(lambda x: pci.write(self.identifier, hex(x), '0x9028'), 'turns_skip')
         if self._config['board_version'] > 4: # everything for KAPTURE 2
             self.observe_write(lambda x: pci.write(self.identifier, hex(x-2), '0x90E0'), 'bunches_per_turn')
-            self.observe_write(self._set_adc_gain, 'adc_gain')
+            self.observe_write(self._set_adc_gain,   'adc_gain')
             self.observe_write(self._set_adc_offset, 'adc_offset')
+            #Setup Long delay 330ps. Value needs to be shifted to the left because first bit is used vor halfstep
+            #Normaly keep adc and th on the same!
+            self.observe_write(lambda x: pci.write(self.identifier, hex(x<<1), '0x9090'), 'delay_330_adc')
+            self.observe_write(lambda x: pci.write(self.identifier, hex(x<<1), '0x90B0'), 'delay_330_th')
+            self.observe_write(lambda x: pci.write(self.identifier, hex(x<<1), '0x90C0'), 'delay_330_fpga')
+            #Setup short Delay 25ps
+            #Normaly keep adc and th on the same!
+            self.observe_write(lambda x: pci.write(self.identifier, hex(x<<1), '0x9094'), 'delay_330_adc')
+            self.observe_write(lambda x: pci.write(self.identifier, hex(x<<1), '0x90B4'), 'delay_330_th')
+            #Setup Clock Div
+            self.observe_write(self._set_clk_div_all , 'clk_div') #one to set it all - normaly they should be all the same
+            self.observe_write(lambda x: pci.write(self.identifier, hex(x<<1), '0x9098'), 'clk_div_adc')
+            self.observe_write(lambda x: pci.write(self.identifier, hex(x<<1), '0x90B8'), 'clk_div_th')
+            self.observe_write(lambda x: pci.write(self.identifier, hex(x<<1), '0x90C8'), 'clk_div_fpga')
+            self.observe_write(lambda x: pci.write(self.identifier, hex(x<<1), '0x90D8'), 'clk_div_cascade')
+
+        else:
+            self.observe_write(self._set_fpga_delay, 'delay_330_fpga')
+            self.observe_write(self._set_chip_delay, 'chip_delay')
+            self.observe_write(self._set_th_delay,   'delay_330_th')
+            self.observe_write(self._set_adc_delay,  'delay_330_adc')
 
     def notify_all_observers(self, write=False):
         """
@@ -266,7 +299,6 @@ class BoardConfiguration(QtGui.QWidget):
         :param value: the value to set the configuration for key to
         :param entry: if key is array to select the array index.
         """
-        print("update",key, value)
         if entry is not None:
             self._config[key][entry] = value
         else:    
@@ -379,7 +411,10 @@ class BoardConfiguration(QtGui.QWidget):
             observers = self._observers_write.get(str(key), None)
             if observers is not None:
                 for callback in observers:
-                    callback(value)
+                    try:
+                        callback(value)
+                    except Exception as e:
+                        log.error('Observer Callback error: {}'.format(e))
                     time.sleep(0.025)
 
     def _notify_observers(self, key, value, write=True):
@@ -417,16 +452,21 @@ class BoardConfiguration(QtGui.QWidget):
 
         return val
 
+    def _set_clk_div_all(self, value):
+        self.update('clk_div_adc', value)
+        self.update('clk_div_th', value)
+        self.update('clk_div_fpga', value)
+        self.update('clk_div_cascade', value)
 
     def _set_fpga_delay(self, value):
         """
         observer function to set the fpga_delays on the board
         :param value: the value to set the delays to
         """
-        time_factor = self.make_uint(value, self.get('fpga_delay_max'), 'FPGA_Delay')
+        time_factor = self.make_uint(value, self.get('delay_330_max'), 'FPGA_Delay')
         reg_value = "0x000501" + '{0:01x}'.format(time_factor) + "0"
         pci.write(self.identifier, reg_value, '0x9060')
-        logging.vinfo("Set FPGA clock delay %i * %i --> %i picoseconds" % (time_factor, self.get('fpga_delay_factor'), time_factor*self.get('fpga_delay_factor')))
+        logging.vinfo("Set FPGA clock delay %i * %i --> %i picoseconds" % (time_factor, self.get('delay_330_factor'), time_factor*self.get('delay_330_factor')))
         #self.update('fpga_delay', value)
 
     def _set_chip_delay(self, values):
@@ -467,32 +507,34 @@ class BoardConfiguration(QtGui.QWidget):
         Set the track and hold delay on the board
         :param value: the value to set the delay to
         """
-        time_factor = self.make_uint(value, self.get('th_delay_max'), 'TH_Delay')
+        time_factor = self.make_uint(value, self.get('delay_330_max'), 'TH_Delay')
         reg_value = "0x000501" + '{0:01x}'.format(time_factor) + "3"
         pci.write(self.identifier, reg_value, '0x9060')
-        logging.vinfo("Set T/H Signal delay %i * %i --> %i picoseconds" % (time_factor, self.get('th_delay_factor'), time_factor*self.get('th_delay_factor')))
-        value = []
-        for i in range(self._config['adc_number']):
-            value.append(time_factor)
-        self.update('adc_delay', value)
+        logging.vinfo("Set T/H Signal delay %i * %i --> %i picoseconds" % (time_factor, self.get('delay_330_factor'), time_factor*self.get('delay_330_factor')))
+       
+        self.update('delay_330_adc', time_factor)
 
-    def _set_adc_delay(self, values):
+    def _set_adc_delay(self, value):
         """
         Set the adc delay for the given adc on the board
         :param value: the value to set the delay to
         """
         def write_delay(value, channel):
             '''write the delays to the board'''
-            value = self.make_uint(value, self.get('adc_delay_max'), 'ADC Delay')
+            value = self.make_uint(value, self.get('delay_330_max'), 'ADC Delay')
             cmd = '00501' + '%01x' % value + str(channel+4)
             pci.write(self.identifier, cmd, reg='0x9060')
             time.sleep(0.005)
 
-        #print("set adc_delay", values)
+        delay = value + self.get('th_to_adc_cycles')
+
+        if delay > self.get('delay_330_max'):
+            delay -= self.get('delay_330_max') + 1
+
         if self._config['adc_number'] == 4:
-            for (adc, val) in enumerate(values):
-                write_delay(val, adc)
-                s = "Setting ADC_%i delay %i * %i --> %i picoseconds" % ((adc+1), val, self.get('adc_delay_factor'), val*self.get('adc_delay_factor'))
+            for adc in range(self._config['adc_number']):
+                write_delay(delay, adc)
+                s = "Setting ADC_%i delay %i * %i --> %i picoseconds" % ((adc+1), delay, self.get('adc_delay_factor'), delay*self.get('adc_delay_factor'))
                 logging.vinfo(s)
 
         else:

+ 1 - 0
KCG/base/backend/board/communication.py

@@ -209,6 +209,7 @@ class PCIdummy(object):
                         "0x9030" : 5, 
                         "0x9020" : 0x64,
                         "0x9028" : 0x2,
+                        "0x9040" : '0x400',
                         "0x9110" : 0x0,
                         "0x9110" : '2342',
                         }

+ 1 - 1
KCG/base/backend/board/sequences/sequences_5.json

@@ -120,7 +120,7 @@
                 ""
             ],
             [
-                "0x4400000B", "0x9060",
+                "0x4400800B", "0x9060",
                 "",
                 ""
             ],

+ 21 - 1
KCG/widgets/testing_widget.py

@@ -19,6 +19,7 @@ class TestingWidget(kcgw.KCGWidgets):
         self.id = unique_id
         self.par = parent
         self.board_id = available_boards[0]
+        self.board_config = board.get_board_config(self.board_id)
 
         self.layout = QtGui.QGridLayout()
         self.outerLayout = QtGui.QVBoxLayout()
@@ -28,7 +29,7 @@ class TestingWidget(kcgw.KCGWidgets):
 
         self.label1  = self.createInput(str(bif.bk_get_config(self.board_id, 'bunches_per_turn')))
         self.button1 = self.createButton("Write Harmonic Number", connect=lambda x: bif.bk_update_config(self.board_id, "bunches_per_turn", self.label1.text().toInt()[0]))        
-        board.get_board_config(self.board_id).observe(self.label1, lambda x: self.label1.setText(str(x)), 'bunches_per_turn')
+        self.board_config.observe(self.label1, lambda x: self.label1.setText(str(x)), 'bunches_per_turn')
 
         self.label2 = self.createLabel("reg")
         self.label3 = self.createLabel("value")
@@ -41,6 +42,15 @@ class TestingWidget(kcgw.KCGWidgets):
         self.reg2 = self.createInput("0x9060")
         self.out = self.createLabel("-")
 
+        def update_delay(which, spinbox):
+            self.board_config.update(which, getattr(self, spinbox).value())
+
+        self.divLabel = self.createLabel("Clock Div")
+        self.divInputTh   = self.createSpinbox(0, 64, start_value=self.board_config.get('clk_div_th'), connect=lambda: update_delay("clk_div_th", "divInputTh"))
+        self.divInputAdc  = self.createSpinbox(0, 64, start_value=self.board_config.get('clk_div_adc'), connect=lambda: update_delay("clk_div_adc", "divInputAdc"))
+        self.divInputFpga = self.createSpinbox(0, 64, start_value=self.board_config.get('clk_div_fpga'), connect=lambda: update_delay("clk_div_fpga", "divInputFpga"))
+        self.divInputCasc = self.createSpinbox(0, 64, start_value=self.board_config.get('clk_div_cascade'), connect=lambda: update_delay("clk_div_cascade", "divInputCasc"))
+
         self.layout.addWidget(self.button1, 0,0)
         self.layout.addWidget(self.label1, 0,1)
 
@@ -54,6 +64,16 @@ class TestingWidget(kcgw.KCGWidgets):
         self.layout.addWidget(self.reg2,3,1)
         self.layout.addWidget(self.out,3,2)
 
+        self.layout.addWidget(self.divLabel,4,0)
+        self.layout.addWidget(self.createLabel("T/H"),5,0)
+        self.layout.addWidget(self.createLabel("ADC"),5,1)
+        self.layout.addWidget(self.createLabel("FPGA"),5,2)
+        self.layout.addWidget(self.createLabel("Cascade"),5,3)
+        self.layout.addWidget(self.divInputTh, 6, 0)
+        self.layout.addWidget(self.divInputAdc, 6, 1)
+        self.layout.addWidget(self.divInputFpga, 6, 2)
+        self.layout.addWidget(self.divInputCasc, 6, 3)
+
         self.setWindowTitle("Testing Widget")
         #self.setMaximumHeight(100)
         #self.resize(150,300)

+ 158 - 126
KCG/widgets/timingWidget.py

@@ -383,6 +383,7 @@ class timingPart(kcgw.KCGWidgets):
         self.outerLayout.addLayout(self.layout)
         self.setLayout(self.outerLayout)
         self.time_scan_enabled = False
+        self.show_advanced = True
 
         # --------[ Create TimeScan part ]----------
         # --------[ Create Elements ]-------------
@@ -390,8 +391,8 @@ class timingPart(kcgw.KCGWidgets):
         self.fine_scan_range_label = self.createLabel(tr("Label", "Fine scan"))
         self.from_label = self.createLabel(tr("Label", "From"))
         self.to_label = self.createLabel(tr("Label", "To"))
-        self.coarse_scan_min_spinbox = self.createSpinbox(0, bif.bk_get_config(board_id, 'th_delay_max'), start_value=0)
-        self.coarse_scan_max_spinbox = self.createSpinbox(0, bif.bk_get_config(board_id, 'th_delay_max'), start_value=bif.bk_get_config(board_id, 'th_delay_max'))
+        self.coarse_scan_min_spinbox = self.createSpinbox(0, bif.bk_get_config(board_id, 'delay_330_max'), start_value=0)
+        self.coarse_scan_max_spinbox = self.createSpinbox(0, bif.bk_get_config(board_id, 'delay_330_max'), start_value=bif.bk_get_config(board_id, 'delay_330_max'))
         self.fine_scan_min_spinbox = self.createSpinbox(0, bif.bk_get_config(board_id, 'chip_delay_max'), start_value=0)
         self.fine_scan_max_spinbox = self.createSpinbox(0, bif.bk_get_config(board_id, 'chip_delay_max'), start_value=bif.bk_get_config(board_id, 'chip_delay_max'))
 
@@ -430,37 +431,52 @@ class timingPart(kcgw.KCGWidgets):
 
         def update_delay(which, spinbox):
             '''update the delays on the board'''
-            board.get_board_config(board_id).update(which, getattr(self, spinbox).value())
+            val = getattr(self, spinbox).value()
+            self.board_config.update(which, val)
+            if not self.show_advanced and "th" in which:
+                key = which[:-2] + "adc"
+                self.board_config.update(key, val)
+
+
+        adc_number = self.board_config.get('adc_number')
             #board.get_board_config(board_id).set_delay(self.coarseInput.value())
         self.thdelayLabel = self.createLabel(tr("Label", "T/H Delay"))
-        self.adc1thdelayLabel = self.createLabel(tr("Label", "2. ADC1 T/H Delay"))
-        self.coarseLabel = self.createLabel(tr("Label", "Coarse Delay"))
-        self.coarseInput = self.createSpinbox(0, 15, connect=lambda: update_delay("th_delay", "coarseInput"))
-        self.adc1CoarseInput = self.createSpinbox(0, 15, connect=lambda: update_delay("adc_1_delay_individual", "adc1CoarseInput"))
-        self.adc1CoarseInput.setEnabled(False)
-        self.adc1CoarseInputSwitch = self.createCheckbox(tr("Label", "Enable second ADC1 T/H Delay"), connect=self.toggleAdc1IndividualDelay)
+        #self.adc1thdelayLabel = self.createLabel(tr("Label", "2. ADC1 T/H Delay"))
+        self.labelCoarseAdcDelay = self.createLabel("ADC")
+        self.labelCoarseFpgaDelay = self.createLabel("FPGA")
+
+        self.coarseLabel = self.createLabel(tr("Label", "330ps Coarse Delay"))
+        self.coarseInputTh   = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_th", "coarseInputTh"))
+        self.coarseInputAdc  = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_adc", "coarseInputAdc"))
+        self.coarseInputFpga = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_fpga", "coarseInputFpga"))
+        #self.coarseInputAdc.setEnabled(False)
+        #self.coarseInputFpga.setEnabled(False)
+
+        if self.board_config.is_KAPTURE2():
+            self.coarse2Label = self.createLabel(tr("Label", "25ps Coarse Delay"))
+            self.coarse2InputTh   = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_th", "coarse2InputTh"))
+            self.coarse2InputAdc  = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_adc", "coarse2InputAdc"))
+            self.coarse2InputFpga = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_fpga", "coarse2InputFpga"))
+            #self.coarse2InputAdc.setEnabled(False)
+            #self.coarse2InputFpga.setEnabled(False)
+            #self.adc1CoarseInput = self.createSpinbox(0, 15, connect=lambda: update_delay("adc_1_delay_individual", "adc1CoarseInput"))
+            #self.adc1CoarseInput.setEnabled(False)
+            self.adc1CoarseInputSwitch = self.createCheckbox(tr("Label", "Enable advanced"), connect=self.toggleAdvanced)
 
         self.fineLabel = self.createLabel(tr("Label", "Fine Delay"))
 
-        self.fineAdc1Input = self.createSpinbox(0, 31, connect=self.on_adc_delay_changed)
-        self.fineAdc2Input = self.createSpinbox(0, 31, connect=self.on_adc_delay_changed)
-        self.fineAdc3Input = self.createSpinbox(0, 31, connect=self.on_adc_delay_changed)
-        self.fineAdc4Input = self.createSpinbox(0, 31, connect=self.on_adc_delay_changed)
+        self.fineAdcInput = []
+        for i in range(adc_number):
+            self.fineAdcInput.append(self.createSpinbox(0, 31, connect=self.on_adc_delay_changed))
 
         self.toggleTimeScanCheckbox = self.createCheckbox(tr("Button", "Time Scan"), tr("Tooltip", "Show time scan part"),
                                                           connect=self.showTimeScan)
         #---------[ End ]---------
 
-        Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id)], [
-            self.coarseInput,
-            self.fineAdc1Input,
-            self.fineAdc2Input,
-            self.fineAdc3Input,
-            self.fineAdc4Input,
-            self.time_scan_button,
-            self.adc1CoarseInputSwitch
-        ])
+        Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id)], self.time_scan_button)
+        Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id)], self.fineAdcInput)
         Elements.addItem('acquire_{}'.format(self.board_id), self.time_scan_button)
+
         def setValueSilent(value, spinbox,adc):
             '''set values silent to not trigger signals'''
             spinbox.blockSignals(True)
@@ -478,92 +494,73 @@ class timingPart(kcgw.KCGWidgets):
                 lambda value=None: setValueSilent(value=value, spinbox=who,adc=adc),
                 what
             )
-        obs(self.fineAdc1Input, 'chip_delay', 0)
-        obs(self.fineAdc2Input, 'chip_delay', 1)
-        obs(self.fineAdc3Input, 'chip_delay', 2)
-        obs(self.fineAdc4Input, 'chip_delay', 3)
-        obs(self.coarseInput, 'th_delay')
-        obs(self.adc1CoarseInput, 'adc_1_delay_individual')
+        for i, item in enumerate(self.fineAdcInput):
+            obs(item, 'chip_delay', i)
+        
+        obs(self.coarseInputTh, 'delay_330_th')
+        obs(self.coarseInputAdc, 'delay_330_adc')
+        obs(self.coarseInputFpga, 'delay_330_fpga')
+
+        if self.board_config.is_KAPTURE2():
+            obs(self.coarse2InputTh, 'delay_25_th')
+            obs(self.coarse2InputAdc, 'delay_25_adc')
+            obs(self.coarse2InputFpga, 'delay_25_fpga')
+
+        #obs(self.adc1CoarseInput, 'adc_1_delay_individual')
 
         # -------[ Create outputs ]---------------
         self.totalLabel = self.createLabel(tr("Label", "Total Delay"))
-        self.totalAdc1Box = self.createInput("", read_only=True)
-        self.totalAdc2Box = self.createInput("", read_only=True)
-        self.totalAdc3Box = self.createInput("", read_only=True)
-        self.totalAdc4Box = self.createInput("", read_only=True)
-
-        def observe_function(x, box):
-            '''method to pass as callable to to the configuration as observer'''
-            box.setText('%i + %i' % (self.board_config.get('th_delay')*
-                                     self.board_config.get('th_delay_factor'),
-                                     x*self.board_config.get('chip_delay_factor')))
-
-        def observe_function_total(x, box, adc):
-            '''method to pass as callable to to the configuration as observer'''
-            box.setText('%i + %i' % (x *
-                                     self.board_config.get('th_delay_factor'),
-                                     self.board_config.get('chip_delay')[int(adc)-1] *
-                                     self.board_config.get('chip_delay_factor')))
-
-        # def adc1_observe_function_total(x, box):
-        #     adc1_individual = board.get_board_config(board_id).get("adc_1_delay_individual")
-        #     if adc1_individual == -1:
-        #         adc1_individual = 0
-        #     box.setText('%i + %i' % ((x+adc1_individual)*
-        #                              board.get_board_config(board_id).get('th_delay_factor'),
-        #                              board.get_board_config(board_id).get('chip_1_delay') *
-        #                              board.get_board_config(board_id).get('chip_delay_factor')))
-
-
-        self.board_config.observe(self.totalAdc1Box,
-                                                 lambda x: observe_function(x[0], self.totalAdc1Box,), 'chip_delay')
-        self.board_config.observe(self.totalAdc1Box,
-                                                 lambda x: observe_function_total(x, self.totalAdc1Box, '1'), 'th_delay')
-        # board.get_board_config(board_id).observe(self.totalAdc1Box, lambda x: adc1_observe_function_total(x, self.totalAdc1Box), 'th_delay')
-        # board.get_board_config(board_id).observe(self.totalAdc1Box, lambda x: adc1_observe_function_total(x, self.totalAdc1Box), 'adc_1_delay_individual')
-        self.board_config.observe(self.totalAdc2Box,
-                                                 lambda x: observe_function(x[1], self.totalAdc2Box), 'chip_delay')
-        self.board_config.observe(self.totalAdc2Box,
-                                                 lambda x: observe_function_total(x, self.totalAdc2Box, '2'), 'th_delay')
-        self.board_config.observe(self.totalAdc3Box,
-                                                 lambda x: observe_function(x[2], self.totalAdc3Box), 'chip_delay')
-        self.board_config.observe(self.totalAdc3Box,
-                                                 lambda x: observe_function_total(x, self.totalAdc3Box, '3'), 'th_delay')
-        self.board_config.observe(self.totalAdc4Box,
-                                                 lambda x: observe_function(x[3], self.totalAdc4Box), 'chip_delay')
-        self.board_config.observe(self.totalAdc4Box,
-                                                 lambda x: observe_function_total(x, self.totalAdc4Box, '4'), 'th_delay')
+        self.totalAdcBox = []
+        for i in range(adc_number):
+            self.totalAdcBox.append(self.createInput("", read_only=True))
 
-       
+
+        self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'chip_delay')
+        self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_330_th')
+        if self.board_config.is_KAPTURE2():
+            self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_25_th')
             
 
         #--------[ Fill Grid ]----------------
         self.layout.addWidget(self.thdelayLabel, 0, 1)
+        self.layout.addWidget(self.labelCoarseAdcDelay, 0, 2)
+        self.layout.addWidget(self.labelCoarseFpgaDelay, 0, 3)
+        self.layout.addWidget(self.adc1CoarseInputSwitch, 0, 4)
+
         self.layout.addWidget(self.coarseLabel, 1, 0)
-        self.layout.addWidget(self.coarseInput, 1, 1)
-        self.layout.addWidget(self.adc1thdelayLabel, 0, 2)
-        self.layout.addWidget(self.adc1CoarseInput, 1, 2)
-        self.layout.addWidget(self.adc1CoarseInputSwitch, 1, 3, 1, 2)
+        self.layout.addWidget(self.coarseInputTh, 1, 1)
+        self.layout.addWidget(self.coarseInputAdc, 1, 2)
+        self.layout.addWidget(self.coarseInputFpga, 1, 3)
+
+        #self.layout.addWidget(self.adc1thdelayLabel, 0, 2)
+        #self.layout.addWidget(self.adc1CoarseInput, 1, 2)
+        #self.layout.addWidget(self.adc1CoarseInputSwitch, 1, 3, 1, 2)
+        
         self.layout.addItem(QtGui.QSpacerItem(10, 15), 2, 1)
+        if self.board_config.is_KAPTURE2():
+            self.layout.addWidget(self.coarse2Label, 3, 0)
+            self.layout.addWidget(self.coarse2InputTh, 3, 1)
+            self.layout.addWidget(self.coarse2InputAdc, 3, 2)
+            self.layout.addWidget(self.coarse2InputFpga, 3, 3)    
+
+        self.layout.addItem(QtGui.QSpacerItem(10, 15), 4, 1)
 
         # Leave some rows free for additional things (empty rows will not be shown)
         for i in range(4):
             self.layout.addWidget(self.createLabel("ADC "+str(i+1)), 5, i+1)
         self.layout.addWidget(self.fineLabel, 6, 0)
-        self.layout.addWidget(self.fineAdc1Input, 6, 1)
-        self.layout.addWidget(self.fineAdc2Input, 6, 2)
-        self.layout.addWidget(self.fineAdc3Input, 6, 3)
-        self.layout.addWidget(self.fineAdc4Input, 6, 4)
+        for i, item in enumerate(self.fineAdcInput):
+            self.layout.addWidget(item, 6, i+1)
+        
         self.layout.addItem(QtGui.QSpacerItem(10, 15), 7, 1)
         line = QtGui.QFrame()
         line.setFrameStyle(QtGui.QFrame.HLine)
         self.layout.addWidget(line, 8, 0, 1, 5)
         self.layout.addItem(QtGui.QSpacerItem(10, 15), 9, 1)
         self.layout.addWidget(self.totalLabel, 10, 0)
-        self.layout.addWidget(self.totalAdc1Box, 10, 1)
-        self.layout.addWidget(self.totalAdc2Box, 10, 2)
-        self.layout.addWidget(self.totalAdc3Box, 10, 3)
-        self.layout.addWidget(self.totalAdc4Box, 10, 4)
+        for i, item in enumerate(self.totalAdcBox):
+            self.layout.addWidget(item, 10, i+1)
+            item.setFocusPolicy(QtCore.Qt.ClickFocus)
         self.layout.addItem(QtGui.QSpacerItem(10, 15), 11, 1)
         
 
@@ -575,16 +572,55 @@ class timingPart(kcgw.KCGWidgets):
         #  -------[ End ]-----------
 
         #  ------[ Exclude Total Delay Boxes from Tab Order ]--------
-        self.totalAdc1Box.setFocusPolicy(QtCore.Qt.ClickFocus)
-        self.totalAdc2Box.setFocusPolicy(QtCore.Qt.ClickFocus)
-        self.totalAdc3Box.setFocusPolicy(QtCore.Qt.ClickFocus)
-        self.totalAdc4Box.setFocusPolicy(QtCore.Qt.ClickFocus)
 
-        self.setTabOrder(self.fineAdc4Input, self.toggleTimeScanCheckbox)
+        #self.setTabOrder(self.fineAdc4Input, self.toggleTimeScanCheckbox)
 
-        self.setValues()
+        #self.setValues()
+        self.board_config.notify_all_observers()
+        self.toggleAdvanced()
         self.setWindowTitle(tr("Heading", "Timing"))
 
+
+    def delay_observer(self, x):
+        for i, item in enumerate(self.totalAdcBox):
+            if self.board_config.is_KAPTURE2():
+                item.setText('%i + %i + %i' % (self.board_config.get('delay_330_th')  * self.board_config.get('delay_330_factor'),
+                                               self.board_config.get('delay_25_th')   * self.board_config.get('delay_25_factor'),
+                                               self.board_config.get('chip_delay')[i] * self.board_config.get('chip_delay_factor')))
+                val = self.board_config.get('delay_25_th')   * self.board_config.get('delay_25_factor')+self.board_config.get('chip_delay')[i] * self.board_config.get('chip_delay_factor')
+            
+                item.setText('%i + %i + %i' % (self.board_config.get('delay_330_th')  * self.board_config.get('delay_330_factor'),
+                                               self.board_config.get('delay_25_th')   * self.board_config.get('delay_25_factor'),
+                                               self.board_config.get('chip_delay')[i] * self.board_config.get('chip_delay_factor')))
+                val = self.board_config.get('delay_25_th')   * self.board_config.get('delay_25_factor')+self.board_config.get('chip_delay')[i] * self.board_config.get('chip_delay_factor')
+
+
+            else:
+                item.setText('%i  + %i' % (self.board_config.get('delay_330_th')  * self.board_config.get('delay_330_factor'),
+                                               self.board_config.get('chip_delay')[i] * self.board_config.get('chip_delay_factor')))
+
+            
+
+    def toggleAdvanced(self):
+        if self.show_advanced:
+            self.labelCoarseAdcDelay.setEnabled(False)
+            self.labelCoarseFpgaDelay.setEnabled(False)
+            self.coarseInputAdc.setEnabled(False)
+            self.coarseInputFpga.setEnabled(False)
+            if self.board_config.is_KAPTURE2():
+                self.coarse2InputAdc.setEnabled(False)
+                self.coarse2InputFpga.setEnabled(False)
+            self.show_advanced = False
+        else:
+            self.labelCoarseAdcDelay.setEnabled(True)
+            self.labelCoarseFpgaDelay.setEnabled(True)
+            self.coarseInputAdc.setEnabled(True)
+            self.coarseInputFpga.setEnabled(True)
+            if self.board_config.is_KAPTURE2():
+                self.coarse2InputAdc.setEnabled(True)
+                self.coarse2InputFpga.setEnabled(True)
+            self.show_advanced = True
+
     def toggleAdc1IndividualDelay(self):
         """
         Toggle to use an individual delay for adc1 or not
@@ -679,39 +715,36 @@ class timingPart(kcgw.KCGWidgets):
         """
         Event handler when this window is closed
         """
-        Elements.emptyGroup('timing_{}'.format(self.board_id))
-        board.get_board_config(self.board_id).unobserve(self.fineAdc1Input, 'chip_delay')
-        board.get_board_config(self.board_id).unobserve(self.fineAdc2Input, 'chip_delay')
-        board.get_board_config(self.board_id).unobserve(self.fineAdc3Input, 'chip_delay')
-        board.get_board_config(self.board_id).unobserve(self.fineAdc4Input, 'chip_delay')
-        board.get_board_config(self.board_id).unobserve(self.coarseInput, 'th_delay')
-        board.get_board_config(self.board_id).unobserve(self.totalAdc1Box, 'chip_delay')
-        board.get_board_config(self.board_id).unobserve(self.totalAdc2Box, 'chip_delay')
-        board.get_board_config(self.board_id).unobserve(self.totalAdc3Box, 'chip_delay')
-        board.get_board_config(self.board_id).unobserve(self.totalAdc4Box, 'chip_delay')
-        board.get_board_config(self.board_id).unobserve(self.totalAdc1Box, 'th_delay')
-        board.get_board_config(self.board_id).unobserve(self.totalAdc2Box, 'th_delay')
-        board.get_board_config(self.board_id).unobserve(self.totalAdc3Box, 'th_delay')
-        board.get_board_config(self.board_id).unobserve(self.totalAdc4Box, 'th_delay')
-        board.get_board_config(self.board_id).unobserve(self.adc1CoarseInput, 'adc_1_delay_individual')
-
         
-            
+        self.board_config.unobserve(self.totalAdcBox[0], 'chip_delay')
+        if self.board_config.is_KAPTURE2():
+            self.board_config.unobserve(self.totalAdcBox[0], 'delay_25_th')
+        self.board_config.unobserve(self.totalAdcBox[0], 'delay_330_th')
 
+        for i, item in enumerate(self.fineAdcInput):
+            self.board_config.unobserve(item, 'chip_delay')
 
-        Elements.removeItem('no_board_{}'.format(self.board_id),
-                            [
-                                self.fineAdc1Input,
-                                self.fineAdc2Input,
-                                self.fineAdc3Input,
-                                self.fineAdc4Input,
-                                self.coarseInput,
-                                self.time_scan_button,
-                                self.adc1CoarseInputSwitch
-                            ])
+
+        self.board_config.unobserve(self.coarseInputTh, 'delay_330_th')
+        self.board_config.unobserve(self.coarseInputAdc, 'delay_330_adc')
+        self.board_config.unobserve(self.coarseInputFpga, 'delay_330_fpga')
+
+        if self.board_config.is_KAPTURE2():
+            self.board_config.unobserve(self.coarse2InputTh, 'delay_25_th')
+            self.board_config.unobserve(self.coarse2InputAdc, 'delay_25_adc')
+            self.board_config.unobserve(self.coarse2InputFpga, 'delay_25_fpga')
+        
+
+        Elements.emptyGroup('timing_{}'.format(self.board_id))
+        Elements.removeItem('no_board_{}'.format(self.board_id), self.time_scan_button)
+        Elements.removeItem('no_board_{}'.format(self.board_id), self.fineAdcInput)
         Elements.removeItem("start_time_scan_{}".format(self.board_id), self.time_scan_button)
         Elements.removeItem(['acquire_{}'.format(self.board_id), "start_time_scan_{}".format(self.board_id)], self.time_scan_button)
 
+        Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id)], self.time_scan_button)
+        Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id)], self.fineAdcInput)
+        Elements.addItem('acquire_{}'.format(self.board_id), self.time_scan_button)
+
 
         super(timingPart, self).closeEvent(event)
 
@@ -720,12 +753,11 @@ class timingPart(kcgw.KCGWidgets):
         Handler that gets called when an adc delay gets changed
         """
         try:
-            #board.get_board_config(self.board_id).set_delay(self.coarseInput.value())
-            board.get_board_config(self.board_id).update('th_delay',self.coarseInput.value())
-            factors = [self.fineAdc1Input.value(), self.fineAdc2Input.value(),
-                       self.fineAdc3Input.value(), self.fineAdc4Input.value()]
-            #board.get_board_config(self.board_id).set_chip_delay([0, 1, 2, 3], factors)
-            board.get_board_config(self.board_id).update('chip_delay', factors)
+            factors = []
+            for item in self.fineAdcInput:
+                factors.extend([item.value()])
+            
+            self.board_config.update('chip_delay', factors)
         except board.BoardError as e:
             logging.error("ADC fine delay failed: {}".format(str(e)))
             bif.bk_status_readout(self.board_id)