123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878 |
- """
- Configuration for each board
- """
- import os
- import sys
- if sys.version_info[:3] < (3,0):
- import ConfigParser as configparser
- else:
- import configparser
- import numpy as np
- import logging
- from PyQt4 import QtGui, QtCore
- from time import sleep
- from .communication import *
- from .... import config as kcg_config
- class BoardConfiguration(QtGui.QWidget):
- """
- The Main configuration class for boards.
- """
- callback_signal = QtCore.pyqtSignal(str, list)
-
- def __init__(self, identifier, config_file=None):
- from . import sequences
- super(BoardConfiguration, self).__init__()
- self.callback_signal.connect(self._notify_observers_receiver)
- self.identifier = identifier
- self._config = {}
- self._observers = {}
- self._observers_for_all = []
- self._observers_write = {}
- self._set_defaults()
- self._get_board_version()
- if self._config['board_version'] > 10:
- logging.critical('Unknown Board Version - gui not working! - restart with active board')
- print('Unknown Board Version - gui not working! - restart with active board')
- else:
- logging.info('Detected Board Version: {}'.format(self._config["board_version"]))
- print('Detected Board Version: {}'.format(self._config["board_version"]))
- self._sequences = sequences.read_sequence(self._config["board_version"])
- self.set_default_observers()
- if self.is_KAPTURE2():
- self.update('bunches_per_turn', kcg_config.bunches_per_turn)
- else:
- self._config['delay_330_factor'] = 150
- self._config['delay_330_max'] = 15
- self._config['chip_delay'] = [3,3,3,3]
- if config_file:
- self.load_config(config_file)
- #self.notify_all_observers(True)
- def _set_defaults(self):
- """
- Set default values
- """
- self._config = {
- 'board_version' : 7,
- 'lastDataSet': None,
- 'adc_number': 8,
- 'samplingrate': 1,
- 'bunches_per_turn': 184,
- 'header_byte_size': 32,
- 'chip_delay_max': 31,
- 'chip_delay' : [0,0,0,0,0,0,0,0],
- 'bunch_shift' : [2,2,2,2,2,2,2,2], #Offset by +2 to encode -2 to +2 range
- 'chip_delay_factor': 3,
-
- 'delay_330_max': 20, #technical 522 #be aware: changing this makes the Delay Calibration invalid!
- 'delay_330_factor': 330,
- 'delay_330_th': 0,
- 'delay_330_adc': 1,
- 'delay_330_fpga': 1,
- #-Kapture 2 only--------------------
- 'delay_25_max' : 23, #be aware: changing this makes the Delay Calibration invalid!
- 'delay_25_factor': 25,
- 'delay_25_th': 0,
- 'delay_25_adc': 10,
- 'delay_25_fpga': 0,
- #-Second FMC------------------
- 'delay_330_th_2': 0,
- 'delay_330_adc_2': 1,
- #'delay_330_fpga_2': 0,
- 'delay_25_th_2': 4,
- 'delay_25_adc_2': 10,
- #'delay_25_fpga_2': 0,
- 'default_25_th_2': 4,
- 'delay_cascade_max': 20,
- 'delay_cascade_factor': 330,
- 'delay_cascade': 0,
- 'delay_cascade_25': 14,
- #-Clock Division--------------
- 'clk_div': 6,
- 'clk_div_th': 6,
- 'clk_div_adc': 6,
- 'clk_div_fpga': 6,
- 'clk_div_cascade': 24,
- #-Kapture 1 only-------------------
- 'th_to_adc_cycles': 7,
- #'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,
- #Kapture 2
- 'adc_offset': [0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000],
- 'adc_gain': [0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000]
- }
- def _get_board_version(self):
- try:
- self._config["board_version"] = int(pci.read(self.identifier, reg='0x9030')[0])
- if self._config["board_version"] == 6:
- self._config["board_version"] = 5
- elif self._config["board_version"] == 7:
- self._config["adc_number"] = 8
- except Exception as e:
- self._config["board_version"] = 0xDEAD
- def is_KAPTURE2(self):
- return self._config["board_version"] >4
- ##########################################################################
- # .d8888b.
- # d88P Y88b
- # Y88b.
- # "Y888b. .d88b. .d88888888 888 .d88b. 88888b. .d8888b .d88b.
- # "Y88b.d8P Y8bd88" 888888 888d8P Y8b888 "88bd88P" d8P Y8b
- # "88888888888888 888888 88888888888888 888888 88888888
- # Y88b d88PY8b. Y88b 888Y88b 888Y8b. 888 888Y88b. Y8b.
- # "Y8888P" "Y8888 "Y88888 "Y88888 "Y8888 888 888 "Y8888P "Y8888
- # 888
- # 888
- # 888
- #
- def get_sequence_list(self):
- if self._sequences =={}:
- return "No Sequences"
- return self._sequences["sequence_names"]
- def get_init_order(self):
- if self._sequences =={}:
- return "No Sequences"
- return self._sequences["initialization_sequence_order"]
- def get_sequence_comment(self, sequence_name):
- if self._sequences =={}:
- return "No Sequences"
- return self._sequences[sequence_name]["Comment"]
- def get_sequence_status(self, sequence_name):
- if self._sequences =={}:
- return "No Sequences"
- return self._sequences[sequence_name]["status_val"]
- def run_sequence(self, name, progressbar=None):
- if self._sequences == {}:
- return False
- from . import sequences
- return sequences.run_sequence(self.identifier, self._sequences[name]["sequence"], progressbar)
- ##########################################################################
- ##########################################################################
- def load_config(self, filename):
- """
- Load a config from a file
- :param filename: the configuration file
- :return:
- """
- if filename:
- config = configparser.RawConfigParser()
- if not config.read(str(filename)):
- return False
- for key in list(self._config.keys()):
- try:
- if type(self._config[key]) == int:
- self._config[key] = config.getint('Config', key)
- elif type(self._config[key]) == bool:
- self._config[key] = config.getboolean('Config', key)
- logging.vinfo("Read '%s' for '%s' from '%s'"%(str(self._config[key]), key, str(filename)))
- except configparser.NoOptionError as e:
- pass
- except configparser.NoSectionError as e:
- pass
- return True
- else:
- return False
- def save_config(self, filename):
- """
- Save the current configuration to a file
- :param filename: the file to write to
- """
- if filename:
- # with open(filename, 'w') as f:
- try:
- f = open(filename, 'w')
- cp = configparser.RawConfigParser()
- cp.add_section('Config')
- for key in list(self._config.keys()):
- cp.set('Config', key, self._config[key])
- f.write('#\n'
- '# KCG (KAPTURE Control Gui) Configuration file\n'
- '#\n'
- '# (c) Karlsruhe Institute of Technology, 2015\n'
- '# All rights reserved.\n'
- '#\n'
- '# Applicable Gui Version(s): 1.0 - 1.0.2\n'
- '#\n'
- '# Saved at: ' + time.asctime() + '\n'
- '#\n\n')
- cp.write(f)
- except (IOError, TypeError):
- return False
- return True
- else:
- return False
- def get(self, key):
- """
- Get the configuration value for key
- :param key: the key to get the value for
- :return: the value of the configuration for key
- """
- if not key in self._config:
- raise NoSuchKeyError(key+" is not registered in BoardConfiguration for board "+str(self.identifier))
- return self._config.get(key, None)
- def dump(self):
- """
- Dump all configuration values
- :return: all configuration values as list
- """
- s = ""
- for key in list(self._config.keys()):
- s += key + ": " + str(self.get(key)) + ", "
- return s[:-1]
- ##########################################################################
- # .d88888b. 888
- # d88P" "Y88b888
- # 888 888888
- # 888 88888888b. .d8888b .d88b. 888d888888 888 .d88b. 888d888.d8888b
- # 888 888888 "88b88K d8P Y8b888P" 888 888d8P Y8b888P" 88K
- # 888 888888 888"Y8888b.88888888888 Y88 88P88888888888 "Y8888b.
- # Y88b. .d88P888 d88P X88Y8b. 888 Y8bd8P Y8b. 888 X88
- # "Y88888P" 88888P" 88888P' "Y8888 888 Y88P "Y8888 888 88888P'
-
- def set_default_observers(self):
- """
- Set observers that are always used
- """
- #def obsprint(x,y):
- # print(x, y)
- #self.observe_all(obsprint)
- self.observe_write(self._update_header, 'header')
- self.observe_write(self._update_pilot_bunch, 'pilot_bunch')
-
- 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_offset, 'adc_offset')
- #Attention: the th delays are inverted! Means: due to the internal setup by increasing the value the sampling
- #would be earlier. This is not intuitive therefore the gui inverts the value by using the delay_max as offset.
- #Setup Long delay 330ps. Value needs to be shifted to the left because first bit is used to set halfstep
- self.observe_write(lambda x: pci.write(self.identifier, hex((x+5)<<1), '0x9090'), 'delay_330_adc')
- self.observe_write(lambda x: pci.write(self.identifier, hex((self._config['delay_330_max']-x+5)<<1), '0x90B0'), 'delay_330_th')
- self.observe_write(lambda x: pci.write(self.identifier, hex((x+5)<<1), '0x90C0'), 'delay_330_fpga')
- self.observe_write(lambda x: pci.write(self.identifier, hex((x+5)<<1), '0x90D0'), 'delay_cascade')
-
- #Setup short Delay 25ps.
- self.observe_write(lambda x: pci.write(self.identifier, hex(x), '0x9094'), 'delay_25_adc')
- self.observe_write(lambda x: pci.write(self.identifier, hex(self._config['delay_25_max']-x), '0x90B4'), 'delay_25_th')
- #self.observe_write(lambda x: pci.write(self.identifier, hex(x), '0x90C4'), 'delay_25_fpga')
- #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), '0x9098'), 'clk_div_adc')
- self.observe_write(lambda x: pci.write(self.identifier, hex(x), '0x90B8'), 'clk_div_th')
- self.observe_write(lambda x: pci.write(self.identifier, hex(x), '0x90C8'), 'clk_div_fpga')
- self.observe_write(lambda x: pci.write(self.identifier, hex(x), '0x90D8'), 'clk_div_cascade')
- self.observe_write(self._set_chip_delay, 'chip_delay')
- self.observe_write(self._set_samplingrate, 'samplingrate')
- self.observe_write(self._set_bunch_shift, 'bunch_shift')
- if self._config['adc_number'] > 4:
- #Setup Long delay 330ps. Value needs to be shifted to the left because first bit is used vor halfstep
- self.observe_write(lambda x: pci.write(self.identifier, hex((x+5)<<1), '0x90A0'), 'delay_330_adc_2')
- self.observe_write(lambda x: pci.write(self.identifier, hex((self._config['delay_330_max']-x+5)<<1), '0x90A8'), 'delay_330_th_2')
-
- #Setup short Delay 25ps
- self.observe_write(lambda x: pci.write(self.identifier, hex(x), '0x90A4'), 'delay_25_adc_2')
- self.observe_write(lambda x: pci.write(self.identifier, hex(self._config['delay_25_max']-x), '0x90AC'), 'delay_25_th_2')
- 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):
- """
- Notify all observers not only the ones that are affected by a change
- """
- for key, value in list(self._config.items()):
- self._notify_observers(key, value, write)
- # observers = self._observers.get(key, None)
- # if observers:
- # for (who, callback) in observers:
- # callback(self.get(key))
- def update(self, key, value, entry=None, write=True):
- """
- Update the value for key in the configuration
- :param key: the key to update
- :param value: the value to set the configuration for key to
- :param entry: if key is array to select the array index.
- """
- if entry is not None:
- self._config[key][entry] = value
- else:
- self._config[key] = value
- self._notify_observers(key, self._config[key], write)
- def updateSilent(self, key, value, entry=None):
- """
- Update the configuration without notifying observers
- :param key: the key to updae
- :param value: the value to set the configuration of key to
- :param entry: if key is array to select the array index.
- """
- if entry is not None:
- self._config[key][entry] = value
- else:
- self._config[key] = value
- def observe(self, who, callback, key):
- """
- Register an observer. (A callback that is called when the according configuration value changes)
- :param who: who is observing
- :param callback: the callback to call on change of the configuration value
- :param key: the key to observe
- """
- if key not in list(self._config.keys()):
- raise ObserverError(str("Key '%s' is unknown." % key))
- if self._observers.get(key, None) is None:
- self._observers[key] = []
- self._observers[key].append([who, callback])
- def observe_all(self, callback):
- """
- Register a observer that is called when any key changes
- :param callback: the callback to register
- """
- if callback not in self._observers_for_all:
- self._observers_for_all.append(callback)
- else:
- raise ObserverError("Observer already registered")
- def observe_write(self, callback, key):
- """
- Register an observer that writes the value for Key on the Board
- :param callback: the callback to call on change of the configuration value
- :param key: the key to observe
- """
- if key not in list(self._config.keys()):
- raise ObserverError(str("Key '%s' is unknown." % key))
- if self._observers_write.get(key, None) is None:
- self._observers_write[key] = []
- self._observers_write[key].append(callback)
- def unobserve(self, who, key=None):
- """
- Remove an observer
- :param who: the observing entity
- :param key: the key to remove it from
- """
- if key is not None:
- observers = np.array(self._observers.get(key, None))
- if observers is None:
- return
- if who not in observers[:, 0]:
- return
- for i, _obs in enumerate(self._observers[key]):
- if _obs[0] is who:
- del self._observers[key][i]
- if not self._observers[key]:
- del self._observers[key]
- return
- for _key in list(self._observers.keys()):
- for i, _obs in enumerate(self._observers[_key]):
- if _obs[0] is who:
- del self._observers[_key][i]
- if not self._observers[_key]:
- del self._observers[_key]
- def unobserve_all_observer(self, callback):
- """
- Unobserve an observer that observes all keys.
- :param callback: the callback to unobserve
- """
- if callback in self._observers_for_all:
- del self._observers_for_all[self._observers_for_all.index(callback)]
- def _notify_observers_receiver(self, key, args):
- """
- The pyqt signal slot for notifications of observers
- :param key: the key that changed
- :param value: the new value
- """
- observers = self._observers.get(str(key), None)
-
- value = args[0]
- write = args[1]
- if observers is not None:
- for (who, callback) in observers:
- try:
- callback(value)
- except Exception as e:
- log.error('Observer Callback error: {}'.format(e))
- for cb in self._observers_for_all:
- try:
- cb(key, value)
- except:
- pass
- if write:
- observers = self._observers_write.get(str(key), None)
- if observers is not None:
- for callback in observers:
- try:
- #log.debug('write ' + key , args)
- 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):
- """
- Notify observers. This emits a pyqt signal to make it thread save
- :param key: the key that changed
- :param value: the new value
- """
- #print("_notify_observers", key, value, write)
- self.callback_signal.emit(key, [value, write])
- def make_uint(self, value, maximum, name=None):
- """
- Convert a value to an uint
- :param value: the value
- :param maximum: the maximum of the returned value
- :param name: the name of this value
- :return: the converted value
- """
- if value is None:
- raise ValueError(str("%s Value is invalid (None)" % name))
- val = None
- try:
- val = int(value)
- except ValueError:
- raise ValueError(str("%s Value is not a valid number" % name))
- if maximum is not None:
- if val > maximum:
- raise ValueError(str("%s Value is too large (>%i)" % (name, maximum)))
- if val < 0:
- raise ValueError(str("%s Values below 0 are not allowed" % name))
- 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_chip_delay(self, values):
- """
- Set the chip_delays on the board
- :param values: the value to set the delays to
- """
-
- _values = []
- for value in values[:4]:
- _values.append(self.make_uint(value, self.get('chip_delay_max'), 'ADC_Value'))
- #print("ADC1: ", values, _values)
- reg_value = ''
- mask = ''
- # Chip Delays are stored as 'ADC_4 ADC_3 ADC_2 ADC_1' in the register.
- # Therefore, we need to traverse the factors array in reverse order
- for value in _values: #reversed(_values): # not for Kapture 2
- if value is not None:
- reg_value += '{0:02x}'.format(value)
- mask += 'ff'
- else:
- reg_value += '00'
- mask += '00'
- if self._config['adc_number'] > 4:
- pci.write(self.identifier, reg_value, '0x9084', hex_mask=mask)
- else:
- pci.write(self.identifier, reg_value, '0x9080', hex_mask=mask)
-
- s = "Setting ADC Delays:"
- for (adc, value) in enumerate(_values):
- s += ' ADC_%i Fine Delay: %i,' % (adc, value)
- s = s[:-1] # cut away the last dangling ','
- logging.vinfo(s)
-
- if self._config['adc_number'] > 4:
- _values = []
- for value in values[4:]:
- _values.append(self.make_uint(value, self.get('chip_delay_max'), 'ADC_Value'))
- #print("ADC 2", values, _values)
- reg_value = ''
- mask = ''
- # Chip Delays are stored as 'ADC_4 ADC_3 ADC_2 ADC_1' in the register.
- # Therefore, we need to traverse the factors array in reverse order
- for value in _values: #reversed(_values): # not for Kapture 2
- if value is not None:
- reg_value += '{0:02x}'.format(value)
- mask += 'ff'
- else:
- reg_value += '00'
- mask += '00'
- pci.write(self.identifier, reg_value, '0x9080', hex_mask=mask)
-
- s = "Setting ADC Delays:"
- for (adc, value) in enumerate(_values):
- s += ' ADC_%i Fine Delay: %i,' % (adc+4, value)
- s = s[:-1] # cut away the last dangling ','
- logging.vinfo(s)
- def _set_bunch_shift(self, values):
- #print("Setting bunch shifts: ", values)
- #Banks are flipped!
- #0x9320: 5,6,7,8
- #0x9330: 1,2,3,4
- bank1 = values[4:8]
- bank2 = values[0:4]
- adcs = bank1 + bank2
- base_reg = 0x9320
- for i, val in enumerate(adcs):
- reg = hex(base_reg+(i*4))
- set = "0x{0:08x}".format(val)
- logging.vinfo("Setting %s to %s"%(reg,set))
- pci.write(self.identifier, set, reg)
- def _update_header(self, state):
- """
- Set the flag to write Header to files when acquiring.
- :param state: True to enabling header and False to disable
- :return: -
- """
- try:
- control = pci.read(self.identifier, 1, '0x9040')[0]
- control_bits = '{0:032b}'.format(int(control, 16))
- if state:
- control_bits = control_bits[:3] + '1' + control_bits[4:]
- else:
- control_bits = control_bits[:3] + '0' + control_bits[4:]
- dec_val_bits = int(control_bits, 2)
- pci.write(self.identifier, hex(dec_val_bits), '0x9040')
- except BoardError as e:
- reason = str(e) if str(e) != '' else "Unknown"
- logging.error("Error in Board Communication, was unable to write value to board "+reason)
- def _update_pilot_bunch(self, state):
- """
- Set the flag to write Header to files when acquiring.
- :param state: True to enabling header and False to disable
- :return: -
- """
- try:
- control = pci.read(self.identifier, 1, '0x9040')[0]
- control_bits = '{0:032b}'.format(int(control, 16))
- if state:
- control_bits = control_bits[:1] + '1' + control_bits[2:]
- else:
- control_bits = control_bits[:1] + '0' + control_bits[2:]
- dec_val_bits = int(control_bits, 2)
- pci.write(self.identifier, hex(dec_val_bits), '0x9040')
- except BoardError as e:
- reason = str(e) if str(e) != '' else "Unknown"
- logging.error("Error in Board Communication, was unable to write value to board "+reason)
- def _set_adc_gain(self, x):
- self._select_adc(1)
- pci.write(self.identifier, '46{:04x}'.format(int(x[0])), '0x9064')
- pci.write(self.identifier, '56{:04x}'.format(int(x[1])), '0x9064')
- self._select_adc(3)
- pci.write(self.identifier, '46{:04x}'.format(int(x[2])), '0x9064')
- pci.write(self.identifier, '56{:04x}'.format(int(x[3])), '0x9064')
- if len(x) > 4:
- logging.vinfo("Gain update not defined for more than 4 adc")
- def _set_adc_offset(self, x):
- #ADC1
- self._select_adc(1)
- pci.write(self.identifier, '44{:04x}'.format(int(x[0])), '0x9064')
- pci.write(self.identifier, '54{:04x}'.format(int(x[1])), '0x9064')
- self._select_adc(3)
- pci.write(self.identifier, '44{:04x}'.format(int(x[2])), '0x9064')
- pci.write(self.identifier, '54{:04x}'.format(int(x[3])), '0x9064')
- if len(x) > 4:
- logging.vinfo("Offset update not defined for more than 4 adc")
- def _select_adc(self, nr):
- val = 0
- if nr == 0:
- val = 0
- if nr < 3:
- val = 4
- elif nr < 5:
- val = 2
- pci.write(self.identifier, hex(val), '0x9044')
- def _set_samplingrate(self, rate):
- return
- if rate == 1:
- #500 MHz
- self.update('delay_25_adc', 10)
- self.update('delay_330_adc', 1)
- self.update('delay_25_adc_2', 10)
- self.update('delay_330_adc_2', 1)
- elif rate == 2:
- #1 GHz
- self.update('delay_25_adc', 10)
- self.update('delay_330_adc', 0)
- self.update('delay_25_adc_2', 10)
- self.update('delay_330_adc_2', 0)
- def set_startup(self):
- #print('board_config setting startup')
- #self.update('delay_330_th', 0)
- #sleep(0.1)
- #self.update('delay_25_th', 0)
- #sleep(0.1)
- self.update('delay_330_th_2', 0)
- sleep(0.1)
- self.update('delay_25_th_2', 3)
- sleep(0.1)
- self.update('delay_25_th_2', 4)
- sleep(0.1)
- self.update('chip_delay', [0,0,0,0, 0,0,0,0])
- sleep(0.1)
- #Bunch Shifts are offset by +2 to encode -2 to +2 as 0x0 to 0x4 in hardware
- self.update('bunch_shift', [2,2,2,2, 2,2,2,2])
- sleep(0.1)
- self.update('adc_gain', [0,0,0,0, 0,0,0,0])
- sleep(0.1)
- self.update('header', 1)
- sleep(0.1)
- self.update('pilot_bunch', 1)
- logging.vinfo('Startup Config Set')
- def read_from_board(self):
- """
- Read values from board and update them in the configuration (Mainly used for skip init functionality)
- """
- try:
- #settings = ['chip_1_delay','chip_2_delay','chip_3_delay','chip_4_delay']
- # --[ read fine/chip delays ]
- adc_number = self._config["adc_number"]
- val = pci.read(self.identifier, reg='9080')[0]
-
- if adc_number > 4:
- val = val + pci.read(self.identifier, reg='9084')[0]
- tmp = np.zeros(adc_number)
-
- for i in range(adc_number):
- selector = [3,2,1,0,7,6,5,4]
- tmp[selector[i]] = int(val[(adc_number-1-i)*2:(adc_number-i)*2], 16)
- self.update('chip_delay', tmp , write=False)
- # --[ read bunch shifts ] --
- #Banks are flipped!
- #0x9320: 5,6,7,8
- #0x9330: 1,2,3,4
- bunch_shifts = pci.read(self.identifier, reg='9330', amount=4, decimal=True)
- if adc_number > 4:
- bunch_shifts = bunch_shifts + pci.read(self.identifier, reg='9320', amount=4, decimal=True)
- self.update('bunch_shift', bunch_shifts, write=False)
- # --[ read and set th delay ]--
- val = pci.read(self.identifier, reg='90B0')[0]
- self.update('delay_330_th', self._config['delay_330_max'] - ((int(val, 16)>>1)-5), write=False)
- val = pci.read(self.identifier, reg='90B4')[0]
- self.update('delay_25_th', self._config['delay_25_max'] - int(val, 16), write=False)
- val = pci.read(self.identifier, reg='90B8')[0]
- self.update('clk_div_th', int(val, 16), write=False)
- # --[ read and set adc delay ]--
- val = pci.read(self.identifier, reg='9090')[0]
- self.update('delay_330_adc', (int(val, 16)>>1)-5, write=False)
- val = pci.read(self.identifier, reg='9094')[0]
- self.update('delay_25_adc', int(val, 16), write=False)
- val = pci.read(self.identifier, reg='9098')[0]
- self.update('clk_div_adc', int(val, 16), write=False)
- # --[ read and set fpga delay ]--
- val = pci.read(self.identifier, reg='90C0')[0]
- self.update('delay_330_fpga', (int(val, 16)>>1)-5, write=False)
- #val = pci.read(self.identifier, reg='90C4')[0]
- #self.update('delay_25_fpga', int(val, 16), write=False)
- val = pci.read(self.identifier, reg='90C8')[0]
- self.update('clk_div_fpga', int(val, 16), write=False)
-
- # --[ read and set number of turns to acquire ]--
- val = pci.read(self.identifier, reg='9020')[0]
- self.update('turns_observe', int(val, 16), write=False)
- # --[ read and set number of turns to skip ]--
- val = pci.read(self.identifier, reg='9028')[0]
- self.update('turns_skip', int(val, 16), write=False)
-
- # --[ read FMC 2 ] --
- # --[ FMC2 read and set th delay ]--
- val = pci.read(self.identifier, reg='90A8')[0]
- self.update('delay_330_th_2', ((int(val, 16)>>1)-5), write=False)
- val = pci.read(self.identifier, reg='90AC')[0]
- self.update('delay_25_th_2', int(val, 16), write=False)
-
- # --[ FCM 2 read and set adc delay ]--
- val = pci.read(self.identifier, reg='90A0')[0]
- self.update('delay_330_adc_2', ((int(val, 16)>>1)-5), write=False)
- val = pci.read(self.identifier, reg='90A4')[0]
- self.update('delay_25_adc_2', int(val, 16), write=False)
-
-
-
- # --[ read and update header ]--
- control = pci.read(self.identifier, 1, '0x9040')[0]
- control_bits = '{0:032b}'.format(int(control, 16))
- if control_bits[3] == '1':
- self.update('header', True, write=False)
- else:
- self.update('header', False, write=False)
- except IndexError:
- error(0x002, "Could not Read data from Board. Pci returned wrong amount of data.")
- # 888 d8P d8888 8888888b. 88888888888 888 888 8888888b. 8888888888 d888
- # 888 d8P d88888 888 Y88b 888 888 888 888 Y88b 888 d8888
- # 888 d8P d88P888 888 888 888 888 888 888 888 888 888
- # 888d88K d88P 888 888 d88P 888 888 888 888 d88P 8888888 888
- # 8888888b d88P 888 8888888P" 888 888 888 8888888P" 888 888
- # 888 Y88b d88P 888 888 888 888 888 888 T88b 888 888888 888
- # 888 Y88b d8888888888 888 888 Y88b. .d88P 888 T88b 888 888
- # 888 Y88b d88P 888 888 888 "Y88888P" 888 T88b 8888888888 8888888
- #
- #
- #
- 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('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('delay_330_factor'), time_factor*self.get('delay_330_factor')))
- #self.update('fpga_delay', value)
-
- def _set_th_delay(self, value):
- """
- 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('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('delay_330_factor'), time_factor*self.get('delay_330_factor')))
-
- self.update('delay_330_adc', time_factor)
- 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('delay_330_max'), 'ADC Delay')
- cmd = '00501' + '%01x' % value + str(channel+4)
- pci.write(self.identifier, cmd, reg='0x9060')
- time.sleep(0.005)
- 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 in range(self._config['adc_number']):
- write_delay(delay, adc)
- s = "Setting ADC_%i delay %i * %i --> %i picoseconds" % ((adc+1), delay, self.get('delay_330_factor'), delay*self.get('delay_330_factor'))
- logging.vinfo(s)
- else:
- logging.vinfo("adc_delay update not defined for more than 4 adc")
-
|