diff --git a/tamalero/ETROC.py b/tamalero/ETROC.py index 36ffab17b95e1b815d3a3093cc7f217399f42633..a2da9ad4023ce5e3c2d37405d57149fde570e6a5 100644 --- a/tamalero/ETROC.py +++ b/tamalero/ETROC.py @@ -27,6 +27,7 @@ class ETROC(): vref=None, vref_pd=False, vtemp = None, + chip_id = 0, ): self.QINJ_delay = 504 # this is a fixed value for the default settings of ETROC2 self.isfake = False @@ -47,8 +48,17 @@ class ETROC(): else: self.ver = "X-X-X" + self.chip_id = chip_id self.regs = load_yaml(os.path.join(here, '../address_table/ETROC2_example.yaml')) + # NOTE: some ETROCs need to be hard reset, otherwise the I2C target does not come alive. + # This actually solves this issue, so please don't take it out (Chesterton's Fence, anyone?) + for i in range(2): + if self.is_connected(): + break + self.reset(hard=True) + time.sleep(0.1) + if self.is_connected(): if vref_pd: self.power_down_VRef() @@ -311,14 +321,16 @@ class ETROC(): return all_pass def reset(self, hard=False): - if hard: - self.rb.SCA.set_gpio(self.reset_pin, 0) - time.sleep(0.1) - self.rb.SCA.set_gpio(self.reset_pin, 1) - else: - self.wr_reg("asyResetGlobalReadout", 0) - time.sleep(0.1) - self.wr_reg("asyResetGlobalReadout", 1) + if self.breed not in ['software', 'emulator']: + # the emulators are not going to be reset at all + if hard: + self.rb.SCA.set_gpio(self.reset_pin, 0) + time.sleep(0.1) + self.rb.SCA.set_gpio(self.reset_pin, 1) + else: + self.wr_reg("asyResetGlobalReadout", 0) + time.sleep(0.1) + self.wr_reg("asyResetGlobalReadout", 1) if not self.isfake: self.rb.rerun_bitslip() # NOTE this is necessary to get the links to lock again @@ -328,7 +340,7 @@ class ETROC(): self.reset_PLL() self.reset_fast_command() self.reset() - self.default_config() + self.default_config(no_reset=True) self.rb.kcu.write_node("READOUT_BOARD_%s.BITSLIP_AUTO_EN"%self.rb.rb, 0x1) time.sleep(0.1) self.rb.kcu.write_node("READOUT_BOARD_%s.BITSLIP_AUTO_EN"%self.rb.rb, 0x0) @@ -422,7 +434,7 @@ class ETROC(): # === CONTROL FUNCTIONS === # ========================= - def default_config(self): + def default_config(self, no_reset=False): # FIXME should use higher level functions for better readability if self.is_connected(): self.reset() # soft reset of the global readout @@ -436,7 +448,7 @@ class ETROC(): self.invalid_FC_counter = self.get_invalidFCCount() # give some number to the ETROC - self.wr_reg("EFuse_Prog", 1234) # gives a chip ID of 308. + self.wr_reg("EFuse_Prog", (self.chip_id)<<2) # gives the correct chip ID # configuration as per discussion with ETROC2 developers self.wr_reg("onChipL1AConf", 0) # this should be default anyway @@ -464,6 +476,23 @@ class ETROC(): self.wr_reg("lowerCalTrig", 0, broadcast=True) self.reset() # soft reset of the global readout, 2nd reset needed for some ETROCs + # + # FIXME this is where the module_reset should happen if links are not locked?? + if not no_reset: + elink_status = self.get_elink_status() + #print(elink_status) + stat = True + for elinks in elink_status: + #print(elink_status[elinks]) + for elink in elink_status[elinks]: + if elink == False: + stat &= False + + if not stat: + print("elinks not locked, resetting PLL and FC modules") + self.reset_modules() + + #print(self.get_elink_status()) def is_good(self): good = True diff --git a/tamalero/Module.py b/tamalero/Module.py index 3a96cc5f2ffdcfb237dc9647021cea5e8eaba3c8..bf8a74d542d411b507028c3527783920024ec13e 100644 --- a/tamalero/Module.py +++ b/tamalero/Module.py @@ -7,7 +7,7 @@ from tamalero.Monitoring import Lock from time import sleep class Module: - def __init__(self, rb, i=1, strict=False, enable_power_board=False): + def __init__(self, rb, i=1, strict=False, enable_power_board=False, moduleid=0): # don't like that this also needs a RB # think about a better solution self.config = rb.configuration['modules'][i] @@ -17,6 +17,7 @@ class Module: #self.regs_em = ['disScrambler', 'singlePort', 'mergeTriggerData', 'triggerGranularity'] self.i = i self.rb = rb + self.id = moduleid if enable_power_board: self.enable_power_board() @@ -50,6 +51,7 @@ class Module: vref = self.config['vref'][j], vref_pd = self.config['disable_vref_gen'][j], vtemp = self.config['vtemp'][j], + chip_id = (self.id << 2) | j # this gives every ETROC a unique ID, based on module ID and ETROC number on the module )) #def configure(self): diff --git a/tamalero/SCA.py b/tamalero/SCA.py index 0fdcc3b28141b5513855133fa1d247b54441340a..fda4cecf4e386e77922200381e1bb0432086d294 100644 --- a/tamalero/SCA.py +++ b/tamalero/SCA.py @@ -582,7 +582,16 @@ class SCA: def I2C_read(self, reg=0x0, master=3, slave_addr=0x48, nbytes=1, adr_nbytes=2, freq=2): # wrapper function to have similar interface as lpGBT I2C_read if nbytes > 1 or adr_nbytes>1: - return self.I2C_read_multi(channel=master, servant=slave_addr, reg=reg, nbytes=nbytes, adr_nbytes=adr_nbytes, freq=freq) + start_time = time.time() + while True: + try: + return self.I2C_read_multi(channel=master, servant=slave_addr, reg=reg, nbytes=nbytes, adr_nbytes=adr_nbytes, freq=freq) + except: + if (time.time() - start_time) < 2: + pass + else: + #print("I2C_read in SCA timed out.") # not printing this. SCA will time out e.g. if we're trying to see if a module/ETROC is connected on an empty slot! + raise RuntimeError("SCA timed out") else: return self.I2C_read_single_byte(channel=master, servant=slave_addr, reg=reg, freq=freq) diff --git a/test_ETROC.py b/test_ETROC.py index f424c82d0f62c9e18f876356a34aadfde387f397..de31c5a0009f78f2191590096b043ca398eb2361 100644 --- a/test_ETROC.py +++ b/test_ETROC.py @@ -241,6 +241,8 @@ if __name__ == '__main__': sys.exit(1) fifo = FIFO(rb=rb_0) + fifo.send_l1a(1) + fifo.reset() is_configured = rb_0.DAQ_LPGBT.is_configured() if not is_configured: @@ -254,7 +256,8 @@ if __name__ == '__main__': connected_modules = [] for i in [1,2,3]: # FIXME we might want to hard reset all ETROCs at this point? - m_tmp = Module(rb=rb_0, i=i, enable_power_board=args.enable_power_board) + moduleid = int(args.moduleid) if i==int(args.module) else (i+200) # NOTE: at some point we should also include the RB number, e.g. (rb << 4) | (module) + m_tmp = Module(rb=rb_0, i=i, enable_power_board=args.enable_power_board, moduleid = moduleid) modules.append(m_tmp) if m_tmp.ETROCs[0].is_connected(): # NOTE assume that module is connected if first ETROC is connected connected_modules.append(i) @@ -265,6 +268,9 @@ if __name__ == '__main__': e_tmp.default_config() time.sleep(1.1) #e_tmp.default_config() + # + print("Setting ETROCs into workMode 0") + e_tmp.wr_reg("workMode", 0, broadcast=True) time.sleep(0.1) @@ -344,11 +350,30 @@ if __name__ == '__main__': # FIXME the below code is still pretty stupid modules = [] connected_modules = [] + for i in [1,2,3]: - m_tmp = Module(rb=rb_0, i=i, enable_power_board=args.enable_power_board) + # FIXME we might want to hard reset all ETROCs at this point? + moduleid = int(args.moduleid) if i==int(args.module) else (i+200) + m_tmp = Module(rb=rb_0, i=i, enable_power_board=args.enable_power_board, moduleid = moduleid) modules.append(m_tmp) - if m_tmp.ETROCs[0].connected: # NOTE assume that module is connected if first ETROC is connected + if m_tmp.ETROCs[0].is_connected(): # NOTE assume that module is connected if first ETROC is connected connected_modules.append(i) + for e_tmp in m_tmp.ETROCs: + if args.hard_reset: + print(f"Running hard reset and default config on module {i}") + e_tmp.reset(hard=True) + e_tmp.default_config() + time.sleep(1.1) + #e_tmp.default_config() + # + print("Setting ETROCs into workMode 0") + e_tmp.wr_reg("workMode", 0, broadcast=True) + + #for i in [1,2,3]: + # m_tmp = Module(rb=rb_0, i=i, enable_power_board=args.enable_power_board) + # modules.append(m_tmp) + # if m_tmp.ETROCs[0].connected: # NOTE assume that module is connected if first ETROC is connected + # connected_modules.append(i) print(f"Found {len(connected_modules)} connected modules") if int(args.module) > 0: @@ -453,49 +478,50 @@ if __name__ == '__main__': print("\n - Checking elinks") - print("Disabling readout for all elinks but the ETROC under test") - rb_0.disable_etroc_readout(all=True) - rb_0.reset_data_error_count() - #rb_0.enable_etroc_readout() - for lpgbt in etroc.elinks: - if lpgbt == 0: - slave = False - else: - slave = True - for link in etroc.elinks[lpgbt]: - print(f"Enabling elink {link}, slave is {slave}") - rb_0.enable_etroc_readout(link, slave=slave) - #time.sleep(0.5) - #rb_0.reset_data_error_count() - #fifo.select_elink(link, slave) - #fifo.ready() - rb_0.rerun_bitslip() - time.sleep(1.5) - rb_0.reset_data_error_count() - stat = rb_0.get_link_status(link, slave=slave, verbose=False) - if stat: - rb_0.get_link_status(link, slave=slave) - start_time = time.time() - while not stat: - #rb_0.disable_etroc_readout(link, slave=slave) - rb_0.enable_etroc_readout(link, slave=slave) - #time.sleep(0.5) - #time.sleep(0.1) - #rb_0.reset_data_error_count() - #fifo.select_elink(link, slave) - #fifo.ready() - rb_0.rerun_bitslip() - time.sleep(1.5) - rb_0.reset_data_error_count() - stat = rb_0.get_link_status(link, slave=slave, verbose=False - ) - if stat: - rb_0.get_link_status(link, slave=slave) - break - if time.time() - start_time > 2: - print('Link not good, but continuing') - rb_0.get_link_status(link, slave=slave) - break + #print("Disabling readout for all elinks but the ETROC under test") + ## FIXME this is still problematic... + #rb_0.disable_etroc_readout(all=True) + #rb_0.reset_data_error_count() + ##rb_0.enable_etroc_readout() + #for lpgbt in etroc.elinks: + # if lpgbt == 0: + # slave = False + # else: + # slave = True + # for link in etroc.elinks[lpgbt]: + # print(f"Enabling elink {link}, slave is {slave}") + # rb_0.enable_etroc_readout(link, slave=slave) + # #time.sleep(0.5) + # #rb_0.reset_data_error_count() + # #fifo.select_elink(link, slave) + # #fifo.ready() + # rb_0.rerun_bitslip() + # time.sleep(1.5) + # rb_0.reset_data_error_count() + # stat = rb_0.get_link_status(link, slave=slave, verbose=False) + # if stat: + # rb_0.get_link_status(link, slave=slave) + # start_time = time.time() + # while not stat: + # #rb_0.disable_etroc_readout(link, slave=slave) + # rb_0.enable_etroc_readout(link, slave=slave) + # #time.sleep(0.5) + # #time.sleep(0.1) + # #rb_0.reset_data_error_count() + # #fifo.select_elink(link, slave) + # #fifo.ready() + # rb_0.rerun_bitslip() + # time.sleep(1.5) + # rb_0.reset_data_error_count() + # stat = rb_0.get_link_status(link, slave=slave, verbose=False + # ) + # if stat: + # rb_0.get_link_status(link, slave=slave) + # break + # if time.time() - start_time > 2: + # print('Link not good, but continuing') + # rb_0.get_link_status(link, slave=slave) + # break ## Bloc below to be retired ## Keeping it for one more iteration diff --git a/test_tamalero.py b/test_tamalero.py index c1f86755b596dfeeee842942b0da03de5cbd4bcd..e8d321ced28deb5fbf5ff440285d96bdb73f38a2 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -284,6 +284,9 @@ if __name__ == '__main__': # Module Status #------------------------------------------------------------------------------- + rb.enable_etroc_readout() + rb.enable_etroc_readout(slave=True) + modules = [] pb_channel = [] if args.configuration == 'emulator' or args.configuration.count('modulev0'):