diff --git a/address_table/generic/etl_test_fw.xml b/address_table/generic/etl_test_fw.xml index 29d2f853d6cec549e73c61ae5d24ef506cf6b287..ae3fdf40b3cd8b1e32c792b5edd515ca3284b3d6 100644 --- a/address_table/generic/etl_test_fw.xml +++ b/address_table/generic/etl_test_fw.xml @@ -2,7 +2,19 @@ <node id="TOP"> <node id="LOOPBACK" module="file://modules/LOOPBACK.xml" address="0x0000" /> <node id="FW_INFO" module="file://modules/FW_INFO.xml" address="0x1000" /> - <node id="READOUT_BOARD_0" module="file://modules/READOUT_BOARD.xml" address="0x2000"/> + + <node id="READOUT_BOARD_0" fwinfo="type=array" module="file://modules/READOUT_BOARD.xml" address="0x2000"/> + <node id="READOUT_BOARD_1" fwinfo="type=array" module="file://modules/READOUT_BOARD.xml" address="0x3000"/> + <node id="READOUT_BOARD_2" fwinfo="type=array" module="file://modules/READOUT_BOARD.xml" address="0x4000"/> + <node id="READOUT_BOARD_3" fwinfo="type=array" module="file://modules/READOUT_BOARD.xml" address="0x5000"/> + <node id="READOUT_BOARD_4" fwinfo="type=array" module="file://modules/READOUT_BOARD.xml" address="0x6000"/> + <node id="SYSTEM" module="file://modules/SYSTEM.xml" address="0xB000" /> - <node id="DAQ_RB0" module="file://modules/DAQ.xml" address="0x120000" /> + + <node id="DAQ_RB0" fwinfo="type=array" module="file://modules/DAQ.xml" address="0x0100000" /> + <node id="DAQ_RB1" fwinfo="type=array" module="file://modules/DAQ.xml" address="0x0200000" /> + <node id="DAQ_RB2" fwinfo="type=array" module="file://modules/DAQ.xml" address="0x0400000" /> + <node id="DAQ_RB3" fwinfo="type=array" module="file://modules/DAQ.xml" address="0x0800000" /> + <node id="DAQ_RB4" fwinfo="type=array" module="file://modules/DAQ.xml" address="0x1000000" /> + </node> diff --git a/address_table/generic/modules/DAQ.xml b/address_table/generic/modules/DAQ.xml index eef446ffcd1f41a80e4ce85d53cef1bbfb196a5f..c09adf32be0ff1e28d5906b0d22ef9ed97736c23 100644 --- a/address_table/generic/modules/DAQ.xml +++ b/address_table/generic/modules/DAQ.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <node id="DAQ_FIFO" fwinfo="endpoint; width=16"> - <node id="FIFO" address="0x0" mode="non-incremental" size="32768" permission="r"/> + <node id="FIFO" address="0x0" mode="non-incremental" size="16384" permission="r"/> </node> diff --git a/address_table/generic/modules/LPGBT_DOWNLINK.xml b/address_table/generic/modules/LPGBT_DOWNLINK.xml index fadf1d22d835a711dc22366447536228580c90ec..f449e8b5f2cd34c5fc7c24bbbad100dcee1b90e8 100644 --- a/address_table/generic/modules/LPGBT_DOWNLINK.xml +++ b/address_table/generic/modules/LPGBT_DOWNLINK.xml @@ -2,12 +2,5 @@ <node id="DOWNLINK"> <node id="RESET" address="0x0" mask="0x00000001" permission="w" description="Reset this Downlink LpGBT Encoder"/> <node id="READY" address="0x1" mask="0x00000001" permission="r" description="LPGBT Downlink Ready"/> - <node id="ALIGN_0" address="0x2" mask="0x00000007" permission="rw" description="Downlink bitslip alignment for Group 0"/> - <node id="ALIGN_1" address="0x2" mask="0x00000070" permission="rw" description="Downlink bitslip alignment for Group 1"/> - <node id="ALIGN_2" address="0x2" mask="0x00000700" permission="rw" description="Downlink bitslip alignment for Group 2"/> - <node id="ALIGN_3" address="0x2" mask="0x00007000" permission="rw" description="Downlink bitslip alignment for Group 3"/> - <node id="DL_SRC" address="0x3" mask="0x0000000f" permission="rw" description="0=etroc, 1=upcnt, 2=prbs, 3=sw fast command"/> - <node id="FAST_CMD_IDLE" address="0x4" mask="0x0000ff00" permission="rw" description="Data to send on fast_cmd" parameters="default=0xF0"/> - <node id="FAST_CMD_DATA" address="0x4" mask="0x00ff0000" permission="rw" description="Data to send on fast_cmd"/> - <node id="FAST_CMD_PULSE" address="0x5" mask="0x00000001" permission="w" description="Write 1 to pulse fast_cmd"/> + <node id="DL_SRC" address="0x3" mask="0x0000000f" permission="rw" description="0=etroc, 1=upcnt, 2=prbs, 3=txfifo"/> </node> diff --git a/address_table/generic/modules/LPGBT_UPLINK.xml b/address_table/generic/modules/LPGBT_UPLINK.xml index bc3591b1eb8cf9921d75bdee36f3c61b15260506..3bc710ec83ece20c678c6a03cd9c5f86b8f145e8 100644 --- a/address_table/generic/modules/LPGBT_UPLINK.xml +++ b/address_table/generic/modules/LPGBT_UPLINK.xml @@ -3,32 +3,4 @@ <node id="RESET" address="0x0" mask="0x00000001" permission="w" description="Reset this Uplink"/> <node id="READY" address="0x1" mask="0x00000001" permission="r" description="LPGBT Uplink Ready"/> <node id="FEC_ERR_CNT" address="0x1" mask="0xFFFF0000" permission="r" description="Data Corrected Count"/> - <node id="ALIGN_0" address="0x2" mask="0x00000007" permission="rw" description=""/> - <node id="ALIGN_1" address="0x2" mask="0x00000070" permission="rw" description=""/> - <node id="ALIGN_2" address="0x2" mask="0x00000700" permission="rw" description=""/> - <node id="ALIGN_3" address="0x2" mask="0x00007000" permission="rw" description=""/> - <node id="ALIGN_4" address="0x2" mask="0x00070000" permission="rw" description=""/> - <node id="ALIGN_5" address="0x2" mask="0x00700000" permission="rw" description=""/> - <node id="ALIGN_6" address="0x2" mask="0x07000000" permission="rw" description=""/> - <node id="ALIGN_7" address="0x2" mask="0x70000000" permission="rw" description=""/> - <node id="ALIGN_8" address="0x3" mask="0x00000007" permission="rw" description=""/> - <node id="ALIGN_9" address="0x3" mask="0x00000070" permission="rw" description=""/> - <node id="ALIGN_10" address="0x3" mask="0x00000700" permission="rw" description=""/> - <node id="ALIGN_11" address="0x3" mask="0x00007000" permission="rw" description=""/> - <node id="ALIGN_12" address="0x3" mask="0x00070000" permission="rw" description=""/> - <node id="ALIGN_13" address="0x3" mask="0x00700000" permission="rw" description=""/> - <node id="ALIGN_14" address="0x3" mask="0x07000000" permission="rw" description=""/> - <node id="ALIGN_15" address="0x3" mask="0x70000000" permission="rw" description=""/> - <node id="ALIGN_16" address="0x4" mask="0x00000007" permission="rw" description=""/> - <node id="ALIGN_17" address="0x4" mask="0x00000070" permission="rw" description=""/> - <node id="ALIGN_18" address="0x4" mask="0x00000700" permission="rw" description=""/> - <node id="ALIGN_19" address="0x4" mask="0x00007000" permission="rw" description=""/> - <node id="ALIGN_20" address="0x4" mask="0x00070000" permission="rw" description=""/> - <node id="ALIGN_21" address="0x4" mask="0x00700000" permission="rw" description=""/> - <node id="ALIGN_22" address="0x4" mask="0x07000000" permission="rw" description=""/> - <node id="ALIGN_23" address="0x4" mask="0x70000000" permission="rw" description=""/> - <node id="ALIGN_24" address="0x5" mask="0x00000007" permission="rw" description=""/> - <node id="ALIGN_25" address="0x5" mask="0x00000070" permission="rw" description=""/> - <node id="ALIGN_26" address="0x5" mask="0x00000700" permission="rw" description=""/> - <node id="ALIGN_27" address="0x5" mask="0x00007000" permission="rw" description=""/> </node> diff --git a/address_table/generic/modules/READOUT_BOARD.xml b/address_table/generic/modules/READOUT_BOARD.xml index 1f2a309723a023ea948d57d8489ef270178fbca1..3138f3e5f29545d3747c0f04bd4609a48268b834 100644 --- a/address_table/generic/modules/READOUT_BOARD.xml +++ b/address_table/generic/modules/READOUT_BOARD.xml @@ -4,23 +4,22 @@ <!-- LPGBT-FPGA --> <node id="LPGBT" address="0x0"> - <node id="DAQ" address="0x00"> - <node id="UPLINK" address="0x00" module="file://LPGBT_UPLINK.xml"/> - <node id="DOWNLINK" address="0x10" module="file://LPGBT_DOWNLINK.xml"/> - </node> - <node id="FEC_ERR_RESET" address="0x1f" mask="0x1" permission="w" description="Write 1 to reset FEC error counter"/> + <node id="UPLINK_0" fwinfo="type=array" address="0x00" module="file://LPGBT_UPLINK.xml"/> + <node id="UPLINK_1" fwinfo="type=array" address="0x10" module="file://LPGBT_UPLINK.xml"/> - <node id="TRIGGER" address="0x20"> - <node id="UPLINK" address="0x00" module="file://LPGBT_UPLINK.xml"/> - </node> + <node id="DOWNLINK" address="0x20" module="file://LPGBT_DOWNLINK.xml"/> - <node id="PATTERN_CHECKER" address="0x30" module="file://PATTERN_CHECKER.xml"/> + <node id="FEC_ERR_RESET" address="0x1f" mask="0x40" permission="w" description="Write 1 to reset FEC error counter"/> + + <node id="PATTERN_CHECKER" address="0x41" module="file://PATTERN_CHECKER.xml"/> </node> <node id="BITSLIP_AUTO_EN" address="0x107" mask="0x1" permission="rw" description="1 to enable automatic bitslipping alignment" parameters="default=0x1"/> + <node id="ELINK_WIDTH" address="0x107" mask="0xe" permission="rw" description="2 = 320 Mbps, 3 = 640 Mbps, 4 = 1280 Mbps" parameters="default=0x2"/> + <node id="ETROC_BITSLIP" address="0x104" mask="0xffffffff" permission="w" description="1 to bitslip an ETROC" /> <node id="RESET_ETROC_RX" address="0x105" mask="0xffffffff" permission="w" description="1 to reset the ETROC rx module" /> <node id="ZERO_SUPRESS" address="0x106" mask="0xffffffff" permission="rw" description="1 to zero suppress fillers out from the ETROC RX" parameters="default=0xfffffff" /> @@ -37,9 +36,14 @@ <node id="FIFO_ELINK_SEL0" address="0x300" mask="0x1f" permission="rw" description="Choose which e-link the readout fifo connects to (0-27)"/> <node id="FIFO_LPGBT_SEL0" address="0x300" mask="0x100" permission="rw" description="Choose which lpgbt the readout fifo connects to (0-1)"/> + <node id="TX_FIFO_RESET" address="0x30e" mask="0x1" permission="w" description="Reset the tx FIFO"/> + <node id="TX_FIFO_WR_EN" address="0x30e" mask="0x2" permission="w" description="TX Fifo Write enable"/> + <node id="TX_FIFO_RD_EN" address="0x30f" mask="0x2" permission="rw" description="TX Fifo Read enable"/> + <node id="TX_FIFO_DATA" address="0x310" mask="0xffffffff" permission="rw" description="TX Fifo Data"/> + <node id="FIFO_RESET" address="0x311" mask="0x1" permission="w" description="Reset the daq FIFO"/> - <node id="RX_FIFO_LOST_WORD_CNT" address="0x312" mask="0x0000ffff" permission="r" description="# of words lost to a full FIFO"/> + <node id="RX_FIFO_LOST_WORD_CNT" address="0x312" mask="0xffffffff" permission="r" description="# of words lost to a full FIFO"/> <node id="RX_FIFO_FULL" address="0x313" mask="0x00000001" permission="r" description="RX FIFO is full"/> <node id="RX_FIFO_OCCUPANCY" address="0x314" mask="0xffffffff" permission="r" description="RX FIFO occupancy"/> @@ -50,12 +54,24 @@ <node id="ETROC_DISABLE" address="0x423" mask="0x0fffffff" permission="rw" description="Write a 1 to disable this ETROC from readout"/> <node id="ETROC_DISABLE_SLAVE" address="0x424" mask="0x0fffffff" permission="rw" description="Write a 1 to disable this ETROC from readout"/> - <node id="LINK_RESET_PULSE" address="0x501" mask="0x00000001" permission="w" description="Write 1 to pulse Link reset"/> - - <node id="PACKET_RX_RATE" address="0x504" mask="0xffffffff" permission="r" description="Measured rate of generated received packets in Hz" /> - <node id="PACKET_CNT" address="0x505" mask="0xffff" permission="r" description="Count of packets received (muxed across elinks)" /> - <node id="ERROR_CNT" address="0x505" mask="0xffff0000" permission="r" description="Count of packet errors (muxed across elinks)" /> + <node id="LINK_RESET_PULSE" address="0x501" mask="0x00000001" permission="w" description="Write 1 to pulse Link reset"/> + <node id="WS_STOP_PULSE" address="0x501" mask="0x00000002" permission="w" description="Write 1 to pulse Waveform Stop"/> + <node id="WS_START_PULSE" address="0x501" mask="0x00000004" permission="w" description="Write 1 to pulse Waveform Start"/> + <node id="QINJ_PULSE" address="0x501" mask="0x00000008" permission="w" description="Write 1 to pulse Charge Injection"/> + <node id="STP_PULSE" address="0x501" mask="0x00000010" permission="w" description="Write 1 to pulse STP"/> + <node id="ECR_PULSE" address="0x501" mask="0x00000020" permission="w" description="Write 1 to pulse ECR"/> + <node id="BC0_PULSE" address="0x501" mask="0x00000040" permission="w" description="Write 1 to pulse BC0"/> + <node id="L1A_PULSE" address="0x501" mask="0x00000080" permission="w" description="Write 1 to pulse L1A"/> + <node id="L1A_QINJ_PULSE" address="0x501" mask="0x00000100" permission="w" description="Write 1 to pulse Charge Injection followed by L1A"/> + <node id="L1A_INJ_DLY" address="0x502" mask="0x0000ffff" permission="rw" description="Number of clock cycles (40MHz) after which the L1A should be generated for a QINJ+L1A"/> + + <node id="PACKET_RX_RATE" address="0x504" mask="0xffffffff" permission="r" description="Measured rate of generated received packets in Hz" /> + <node id="PACKET_CNT" address="0x505" mask="0x0000ffff" permission="r" description="Count of packets received (muxed across elinks)" /> + <node id="ERROR_CNT" address="0x505" mask="0xffff0000" permission="r" description="Count of packet errors (muxed across elinks)" /> + <node id="DATA_CNT" address="0x506" mask="0xffff0000" permission="r" description="Count of packet data frames (muxed across elinks)"/> + <node id="FILLER_RATE" address="0x507" mask="0x00ffffff" permission="r" description="Rate of packet filler frames (muxed across elinks)"/> <node id="PACKET_CNT_RESET" address="0x506" mask="0x00000001" permission="w" description="Write 1 to reset packet counters"/> - <node id="ERR_CNT_RESET" address="0x506" mask="0x00000002" permission="w" description="Write 1 to reset error counters"/> + <node id="ERR_CNT_RESET" address="0x506" mask="0x00000002" permission="w" description="Write 1 to reset error counters"/> + <node id="DATA_CNT_RESET" address="0x506" mask="0x00000004" permission="w" description="Write 1 to reset data counters"/> </node> diff --git a/address_table/generic/modules/SYSTEM.xml b/address_table/generic/modules/SYSTEM.xml index f5fee943e02f38502c7c840f598050fe97976189..7b2051c32d6d2aa57d23cc462f521b29c4b7840b 100644 --- a/address_table/generic/modules/SYSTEM.xml +++ b/address_table/generic/modules/SYSTEM.xml @@ -9,11 +9,14 @@ <node id="SFP0_TX_DIS" address="0x40" mask="0x000001" permission="rw" description="Controls SFP0 Disable" parameters="default=0x0"/> <node id="SFP1_TX_DIS" address="0x40" mask="0x000002" permission="rw" description="Controls SFP1 Disable" parameters="default=0x0"/> - <node id="L1A_PULSE" address="0x500" mask="0x00000001" permission="w" description="Write 1 to pulse L1A"/> - <node id="LINK_RESET_PULSE" address="0x501" mask="0x00000001" permission="w" description="Write 1 to pulse Link reset"/> - <node id="L1A_RATE" address="0x502" mask="0xffffffff" permission="rw" description="Rate of generated triggers f_trig =(2^32-1) * clk_period * rate" parameters="default=0x00000000"/> - <node id="L1A_RATE_CNT" address="0x503" mask="0xffffffff" permission="r" description="Measured rate of generated triggers in Hz" /> - <node id="EN_EXT_TRIGGER" address="0x507" mask="0x1" permission="rw" description="1 to enable the external SMA trigger" /> + <node id="L1A_PULSE" address="0x500" mask="0x00000001" permission="w" description="Write 1 to pulse L1A"/> + <node id="QINJ_PULSE" address="0x500" mask="0x00001000" permission="w" description="Write 1 to pulse QINJ"/> + <node id="L1A_DELAY" address="0x500" mask="0x00000ff8" permission="rw" description="Number of clock cycles to delay the L1A after a QINJ" parameters="default=0x190"/> + <node id="QINJ_MAKES_L1A" address="0x500" mask="0x00000004" permission="rw" description="1 for QINJ to make L1As" parameters="default=0x1"/> + <node id="QINJ_DEADTIME" address="0x500" mask="0xffff0000" permission="rw" description="Minimum deadtime between charge injections" parameters="default=0x000000ff"/> + <node id="QINJ_RATE" address="0x501" mask="0xffffffff" permission="rw" description="Rate of generated qinj f_trig =(2^32-1) * clk_period * rate" parameters="default=0x00000000"/> + <node id="L1A_RATE" address="0x502" mask="0xffffffff" permission="rw" description="Rate of generated triggers f_trig =(2^32-1) * clk_period * rate" parameters="default=0x00000000"/> + <node id="L1A_RATE_CNT" address="0x503" mask="0xffffffff" permission="r" description="Measured rate of generated triggers in Hz" /> + <node id="EN_EXT_TRIGGER" address="0x507" mask="0x00000001" permission="rw" description="1 to enable the external SMA trigger" /> </node> - diff --git a/tamalero/KCU.py b/tamalero/KCU.py index 7e35c842f1eb52d6229ffe0790cb69e580bb6ae8..02167187d2c3b7197763d3ec78b58a5252132be3 100644 --- a/tamalero/KCU.py +++ b/tamalero/KCU.py @@ -48,7 +48,10 @@ class KCU: self.dispatch() def read_node(self, id): - reg = self.hw.getNode(id) + try: + reg = self.hw.getNode(id) + except: + raise Exception(f"Failed finding node {id} in read_node") ret = reg.read() if self.auto_dispatch: self.dispatch() @@ -65,6 +68,15 @@ class KCU: reg = self.hw.getNode(id) self.action_reg(reg) + def print_regs(self): + + for id in self.hw.getNodes(): + reg = self.hw.getNode(id) + # if (reg.getModule() == ""): + if (reg.getMode() != uhal.BlockReadWriteMode.HIERARCHICAL): + print(self.format_reg(reg.getAddress(), reg.getPath()[4:], -1, + self.format_permission(reg.getPermission()))) + def get_firmware_version(self, verbose=False, string=True): nodes = ("FW_INFO.HOG_INFO.GLOBAL_DATE", @@ -119,20 +131,22 @@ class KCU: self.print_reg(self.hw.getNode(id), use_color=True, threshold=1, invert=True) self.check_clock_frequencies() - - locked = self.read_node(f"READOUT_BOARD_0.ETROC_LOCKED").value() - locked_slave = self.read_node(f"READOUT_BOARD_0.ETROC_LOCKED_SLAVE").value() - - for l in range(28): - if (locked >> l) & 1: - print(green(f'Master elink {l} is locked.')) - for l in range(28): - if (locked_slave >> l) & 1: - print(green(f'Slave elink {l} is locked.')) - - if locked | locked_slave == 0: - print(red('Warning: No elink is locked.')) - + + for rb in self.readout_boards: + print('Checking Readout Board {rb.rb}') + locked = self.read_node(f"READOUT_BOARD_{rb.rb}.ETROC_LOCKED").value() + locked_slave = self.read_node(f"READOUT_BOARD_{rb.rb}.ETROC_LOCKED_SLAVE").value() + + for l in range(28): + if (locked >> l) & 1: + print(green(f'Master elink {l} is locked.')) + for l in range(28): + if (locked_slave >> l) & 1: + print(green(f'Slave elink {l} is locked.')) + + if locked | locked_slave == 0: + print(red('Warning: No elink is locked.')) + print() def print_reg(self, reg, threshold=1, maxval=0xFFFFFFFF, use_color=False, invert=False): from tamalero.colors import green, red, dummy diff --git a/tamalero/LPGBT.py b/tamalero/LPGBT.py index 992e96ce0a2e451c7a4bf82662c5cb17f7b1841f..4025b191285479af82cdbedb1b2fa0a30d382ad3 100644 --- a/tamalero/LPGBT.py +++ b/tamalero/LPGBT.py @@ -199,20 +199,20 @@ class LPGBT(RegParser): if self.trigger: if verbose: print ("Checking trigger link status") - print ("Uplink ready:", self.kcu.read_node("READOUT_BOARD_%i.LPGBT.TRIGGER.UPLINK.READY"%self.rb).value()==1 ) - print ("FEC count:", self.kcu.read_node("READOUT_BOARD_%i.LPGBT.TRIGGER.UPLINK.FEC_ERR_CNT"%self.rb).value()) + print ("Uplink ready:", self.kcu.read_node("READOUT_BOARD_%i.LPGBT.UPLINK_1.READY"%self.rb).value()==1 ) + print ("FEC count:", self.kcu.read_node("READOUT_BOARD_%i.LPGBT.UPLINK_1.FEC_ERR_CNT"%self.rb).value()) return ( - (self.kcu.read_node("READOUT_BOARD_%i.LPGBT.TRIGGER.UPLINK.FEC_ERR_CNT"%self.rb).value() == 0) & - (self.kcu.read_node("READOUT_BOARD_%i.LPGBT.TRIGGER.UPLINK.READY"%self.rb).value() == 1) + (self.kcu.read_node("READOUT_BOARD_%i.LPGBT.UPLINK_1.FEC_ERR_CNT"%self.rb).value() == 0) & + (self.kcu.read_node("READOUT_BOARD_%i.LPGBT.UPLINK_1.READY"%self.rb).value() == 1) ) else: if verbose: print ("Checking DAQ link status") - print ("Uplink ready:", self.kcu.read_node("READOUT_BOARD_%i.LPGBT.DAQ.UPLINK.READY"%self.rb).value()==1 ) - print ("FEC count:", self.kcu.read_node("READOUT_BOARD_%i.LPGBT.DAQ.UPLINK.FEC_ERR_CNT"%self.rb).value()) + print ("Uplink ready:", self.kcu.read_node("READOUT_BOARD_%i.LPGBT.UPLINK_0.READY"%self.rb).value()==1 ) + print ("FEC count:", self.kcu.read_node("READOUT_BOARD_%i.LPGBT.UPLINK_0.FEC_ERR_CNT"%self.rb).value()) return ( - (self.kcu.read_node("READOUT_BOARD_%i.LPGBT.DAQ.UPLINK.FEC_ERR_CNT"%self.rb).value() == 0) & - (self.kcu.read_node("READOUT_BOARD_%i.LPGBT.DAQ.UPLINK.READY"%self.rb).value() == 1) + (self.kcu.read_node("READOUT_BOARD_%i.LPGBT.UPLINK_0.FEC_ERR_CNT"%self.rb).value() == 0) & + (self.kcu.read_node("READOUT_BOARD_%i.LPGBT.UPLINK_0.READY"%self.rb).value() == 1) ) def get_version(self): @@ -277,7 +277,7 @@ class LPGBT(RegParser): # needed for the mgt to lock if (not self.kcu.read_node( - "READOUT_BOARD_%d.LPGBT.DAQ.UPLINK.READY" % self.rb)): + "READOUT_BOARD_%d.LPGBT.UPLINK_0.READY" % self.rb)): print(" > Performing LpGBT Magic...") id = "LPGBT.RW.TESTING.ULECDATASOURCE" self.wr_reg(id, 6) @@ -319,7 +319,7 @@ class LPGBT(RegParser): def align_DAQ(self): for i in range(28): - id = "READOUT_BOARD_%d.LPGBT.DAQ.UPLINK.ALIGN_%d" % (self.rb, i) + id = "READOUT_BOARD_%d.LPGBT.UPLINK_0.ALIGN_%d" % (self.rb, i) self.kcu.write_node(id, 2) def wr_adr(self, adr, data): @@ -467,18 +467,18 @@ class LPGBT(RegParser): if self.trigger: if not quiet: print ("Setting uplink alignment for trigger link %i to %i"%(link, val)) - id = "READOUT_BOARD_%d.LPGBT.TRIGGER.UPLINK.ALIGN_%d" % (self.rb, link) + id = "READOUT_BOARD_%d.LPGBT.UPLINK_1.ALIGN_%d" % (self.rb, link) else: if not quiet: print ("Setting uplink alignment for DAQ link %i to %i"%(link, val)) - id = "READOUT_BOARD_%d.LPGBT.DAQ.UPLINK.ALIGN_%d" % (self.rb, link) + id = "READOUT_BOARD_%d.LPGBT.UPLINK_0.ALIGN_%d" % (self.rb, link) self.kcu.write_node(id, val) def get_uplink_alignment(self, link): if self.trigger: - return self.kcu.read_node("READOUT_BOARD_%d.LPGBT.TRIGGER.UPLINK.ALIGN_%d"%(self.rb, link)).value() + return self.kcu.read_node("READOUT_BOARD_%d.LPGBT.UPLINK_1.ALIGN_%d"%(self.rb, link)).value() else: - return self.kcu.read_node("READOUT_BOARD_%d.LPGBT.DAQ.UPLINK.ALIGN_%d"%(self.rb, link)).value() + return self.kcu.read_node("READOUT_BOARD_%d.LPGBT.UPLINK_0.ALIGN_%d"%(self.rb, link)).value() def set_uplink_invert(self, link, invert=True): self.wr_reg("LPGBT.RWF.EPORTRX.EPRX_CHN_CONTROL.EPRX%dINVERT" % link, invert) @@ -1070,7 +1070,7 @@ class LPGBT(RegParser): self.wr_reg("LPGBT.RW.TESTING.DPDATAPATTERN%d"%i, 0xff&(pattern >> (i*8))) def set_downlink_data_src(self, source): - id = "READOUT_BOARD_%d.LPGBT.DAQ.DOWNLINK.DL_SRC" % self.rb + id = "READOUT_BOARD_%d.LPGBT.DOWNLINK.DL_SRC" % self.rb if (source == "etroc"): self.kcu.write_node(id, 0) if (source == "upcnt"): diff --git a/tamalero/ReadoutBoard.py b/tamalero/ReadoutBoard.py index 19b175f05a4a1c3e491e15b5e558deda24395ed8..5cd1be254c3a88bf075078239ef671ea04acfafe 100644 --- a/tamalero/ReadoutBoard.py +++ b/tamalero/ReadoutBoard.py @@ -197,11 +197,11 @@ class ReadoutBoard: def status(self): nodes = list(map (lambda x : "READOUT_BOARD_%s.LPGBT." % self.rb + x, - ("DAQ.DOWNLINK.READY", - "DAQ.UPLINK.READY", - "DAQ.UPLINK.FEC_ERR_CNT", - "TRIGGER.UPLINK.READY", - "TRIGGER.UPLINK.FEC_ERR_CNT",))) + ("DOWNLINK.READY", + "UPLINK_0.READY", + "UPLINK_0.FEC_ERR_CNT", + "UPLINK_1.READY", + "UPLINK_1.FEC_ERR_CNT",))) for node in nodes: val = self.kcu.read_node(node) err = 0 @@ -247,11 +247,11 @@ class ReadoutBoard: def get_FEC_error_count(self, quiet=False): if not quiet: print("{:<8}{:<8}{:<50}{:<8}".format("Address", "Perm.", "Name", "Value")) - self.kcu.print_reg(self.kcu.hw.getNode("READOUT_BOARD_%s.LPGBT.DAQ.UPLINK.FEC_ERR_CNT" % self.rb), use_color=True, invert=True) - self.kcu.print_reg(self.kcu.hw.getNode("READOUT_BOARD_%s.LPGBT.TRIGGER.UPLINK.FEC_ERR_CNT" % self.rb), use_color=True, invert=True) + self.kcu.print_reg(self.kcu.hw.getNode("READOUT_BOARD_%s.LPGBT.UPLINK_0.FEC_ERR_CNT" % self.rb), use_color=True, invert=True) + self.kcu.print_reg(self.kcu.hw.getNode("READOUT_BOARD_%s.LPGBT.UPLINK_1.FEC_ERR_CNT" % self.rb), use_color=True, invert=True) return { - 'DAQ': self.kcu.read_node("READOUT_BOARD_%s.LPGBT.DAQ.UPLINK.FEC_ERR_CNT" % self.rb).value(), - 'TRIGGER': self.kcu.read_node("READOUT_BOARD_%s.LPGBT.TRIGGER.UPLINK.FEC_ERR_CNT" % self.rb).value() + 'DAQ': self.kcu.read_node("READOUT_BOARD_%s.LPGBT.UPLINK_0.FEC_ERR_CNT" % self.rb).value(), + 'TRIGGER': self.kcu.read_node("READOUT_BOARD_%s.LPGBT.UPLINK_1.FEC_ERR_CNT" % self.rb).value() } def reset_FEC_error_count(self, quiet=False): diff --git a/tamalero/__init__.py b/tamalero/__init__.py index 3aaa979c6f9a1bc2e5638e723042ddd95b313f93..7540101940c476c300d226fe44a17a315ea0cd31 100644 --- a/tamalero/__init__.py +++ b/tamalero/__init__.py @@ -1,2 +1,2 @@ __version__ = "0.1.0" -__fw_version__ = "2.1.11" +__fw_version__ = "3.0.7" diff --git a/test_ETROC.py b/test_ETROC.py index c784fecc4ad6587b63ea60ba0039f2fae4fe4838..d23cc9febd3f505f2e0b29a2423e0bc3e269338a 100644 --- a/test_ETROC.py +++ b/test_ETROC.py @@ -116,7 +116,6 @@ def vth_scan_internal(ETROC2, row=0, col=0, dac_min=0, dac_max=500, dac_step=1): run_results = np.array(results) return [dac_axis, run_results] - # initiate ETROC2 = software_ETROC2() # currently using Software ETROC2 (fake) print("ETROC2 emulator instantiated, base configuration successful") @@ -571,6 +570,7 @@ if __name__ == '__main__': else: fifo.select_elink(2) rb_0.kcu.write_node("READOUT_BOARD_0.ERR_CNT_RESET", 1) + rb_0.kcu.write_node("READOUT_BOARD_0.DATA_CNT_RESET", 1) print("\n - Running simple threshold scan on single pixel") vth = [] count = [] @@ -585,6 +585,7 @@ if __name__ == '__main__': count.append(rb_0.kcu.read_node("READOUT_BOARD_0.DATA_CNT").value()) print(i, rb_0.kcu.read_node("READOUT_BOARD_0.DATA_CNT").value()) rb_0.kcu.write_node("READOUT_BOARD_0.ERR_CNT_RESET", 1) + rb_0.kcu.write_node("READOUT_BOARD_0.DATA_CNT_RESET", 1) vth_a = np.array(vth) count_a = np.array(count) @@ -602,6 +603,7 @@ if __name__ == '__main__': count.append(rb_0.kcu.read_node("READOUT_BOARD_0.DATA_CNT").value()) print(i, rb_0.kcu.read_node("READOUT_BOARD_0.DATA_CNT").value()) rb_0.kcu.write_node("READOUT_BOARD_0.ERR_CNT_RESET", 1) + rb_0.kcu.write_node("READOUT_BOARD_0.DATA_CNT_RESET", 1) print(vth) print(count) @@ -702,6 +704,7 @@ if __name__ == '__main__': # reset the counter rb_0.kcu.write_node("READOUT_BOARD_0.ERR_CNT_RESET", 1) + rb_0.kcu.write_node("READOUT_BOARD_0.DATA_CNT_RESET", 1) # turn off data readout for all pixels etroc.wr_reg("disDataReadout", 1, broadcast=True) @@ -724,6 +727,7 @@ if __name__ == '__main__': hits = rb_0.kcu.read_node("READOUT_BOARD_0.DATA_CNT").value() print(f"Found {hits} hits when sitting mid-slope and sending 5000 L1As") rb_0.kcu.write_node("READOUT_BOARD_0.ERR_CNT_RESET", 1) + rb_0.kcu.write_node("READOUT_BOARD_0.DATA_CNT_RESET", 1) # set threshold to threshold print(f"Using found threshold at {dac[res==0][0]}, using value {dac[res==0][2]} for DAC.") @@ -737,6 +741,7 @@ if __name__ == '__main__': counts = [] for i in range(500, 510, 1): rb_0.kcu.write_node("READOUT_BOARD_0.ERR_CNT_RESET", 1) + rb_0.kcu.write_node("READOUT_BOARD_0.DATA_CNT_RESET", 1) fifo.send_QInj(5000, delay=i) hits = rb_0.kcu.read_node("READOUT_BOARD_0.DATA_CNT").value() print(i, hits) @@ -805,6 +810,7 @@ if __name__ == '__main__': # reset the counter rb_0.kcu.write_node("READOUT_BOARD_0.ERR_CNT_RESET", 1) + rb_0.kcu.write_node("READOUT_BOARD_0.DATA_CNT_RESET", 1) # turn off data readout for all pixels etroc.wr_reg("disDataReadout", 1, broadcast=True) diff --git a/test_tamalero.py b/test_tamalero.py index 636312e382389074126cfd509843330b5ac7fe01..b09b75ae8ab86ac6f6ecfca0e0ad22193df6acc3 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -75,7 +75,7 @@ def create_app(rb, modules=[]): module = modules[int(payload['module'])] etroc = module.ETROCs[int(payload['etroc'])] - fifo = FIFO(rb=rb_0) + fifo = FIFO(rb=rb) vth_scan_data = vth_scan( etroc, @@ -137,6 +137,8 @@ if __name__ == '__main__': argParser.add_argument('--strict', action='store_true', default=False, help="Enforce strict limits on ADC reads for SCA and LPGBT") argParser.add_argument('--server', action='store_true', default=False, help="Start server") argParser.add_argument('--port', action='store', default=5000, type=int, help="Port to use for server") + argParser.add_argument('--rb', action='store', default=0, type=int, help="Specify Readout Board") + argParser.add_argument('--multi_board', action = 'store_true') args = argParser.parse_args() @@ -150,8 +152,28 @@ if __name__ == '__main__': print ("Using KCU at address: %s"%args.kcu) kcu = None - rb_0 = None - + rb = None + + if args.multi_board: + temp = get_kcu(args.kcu, control_hub=args.control_hub, host=args.host, verbose=args.verbose) + if temp == 0: + sys.exit(1) + for i in range(3): + try: + print(f'Checking ReadoutBoard {i}') + rb = ReadoutBoard(i, trigger=(not args.force_no_trigger), kcu=temp, config=args.configuration) + print(f'Checking data loopback') + temp.write_node("LOOPBACK.LOOPBACK", data) + if (data != temp.read_node("LOOPBACK.LOOPBACK")): + print(f"No communications with KCU105 for board {i}") + else: + print(f'Successfully connected to ReadoutBoard {i}') + rb.get_trigger() + rb.read_temp() + except: + print(f'Connecting to ReadoutBoard {i} failed') + + temp.status() # write to the loopback node of the KCU105 to check ethernet communication kcu = get_kcu(args.kcu, control_hub=args.control_hub, host=args.host, verbose=args.verbose) if (kcu == 0): @@ -159,21 +181,25 @@ if __name__ == '__main__': # this would cause the RB init to fail. sys.exit(1) + print(f'Utilizing ReadoutBoard {args.rb}') + rb = ReadoutBoard(args.rb, trigger=(not args.force_no_trigger), kcu=kcu, config=args.configuration) + + # IDEA Loop over boards for configuration? + print(kcu.readout_boards) - rb_0 = ReadoutBoard(0, trigger=(not args.force_no_trigger), kcu=kcu, config=args.configuration) data = 0xabcd1234 kcu.write_node("LOOPBACK.LOOPBACK", data) if (data != kcu.read_node("LOOPBACK.LOOPBACK")): print("No communications with KCU105... quitting") sys.exit(1) - is_configured = rb_0.DAQ_LPGBT.is_configured() + is_configured = rb.DAQ_LPGBT.is_configured() header(configured=is_configured) if args.recal_lpgbt: - rb_0.DAQ_LPGBT.calibrate_adc(recalibrate=True) - if rb_0.trigger: - rb_0.TRIG_LPGBT.calibrate_adc(recalibrate=True) + rb.DAQ_LPGBT.calibrate_adc(recalibrate=True) + if rb.trigger: + rb.TRIG_LPGBT.calibrate_adc(recalibrate=True) if not args.devel: check_repo_status(kcu_version=kcu.get_firmware_version(verbose=True)) @@ -186,27 +212,27 @@ if __name__ == '__main__': print("Power up init sequence for: DAQ") - #rb_0.DAQ_LPGBT.power_up_init() + #rb.DAQ_LPGBT.power_up_init() - rb_0.VTRX.get_version() + rb.VTRX.get_version() if (verbose): print ("VTRX status at power up:") - _ = rb_0.VTRX.status() - print (rb_0.VTRX.ver) + _ = rb.VTRX.status() + print (rb.VTRX.ver) - rb_0.get_trigger() + rb.get_trigger() - if rb_0.trigger: + if rb.trigger: #print("Configuring Trigger lpGBT") print (" > Power up init sequence for: Trigger") - rb_0.TRIG_LPGBT.power_up_init() + rb.TRIG_LPGBT.power_up_init() print("Done Configuring Trigger lpGBT") else: - rb_0.VTRX.get_version() + rb.VTRX.get_version() - if not hasattr(rb_0, "TRIG_LPGBT"): - rb_0.get_trigger() + if not hasattr(rb, "TRIG_LPGBT"): + rb.get_trigger() if args.power_up or args.reconfigure: @@ -220,13 +246,13 @@ if __name__ == '__main__': else: alignment = False - #if rb_0.trigger: - # rb_0.TRIG_LPGBT.power_up_init() + #if rb.trigger: + # rb.TRIG_LPGBT.power_up_init() print("Configuring readout board") - rb_0.configure(alignment=alignment, data_mode=data_mode, etroc=args.etroc, verbose=args.verbose) + rb.configure(alignment=alignment, data_mode=data_mode, etroc=args.etroc, verbose=args.verbose) - res = rb_0.DAQ_LPGBT.get_board_id() - res['trigger'] = 'yes' if rb_0.trigger else 'no' + res = rb.DAQ_LPGBT.get_board_id() + res['trigger'] = 'yes' if rb.trigger else 'no' if (verbose): make_version_header(res) @@ -234,25 +260,25 @@ if __name__ == '__main__': if args.power_up or args.reconfigure: # FIXME this is taken out because it sometimes sends the RB into the Nirvana. # Daniel will fix it when he has time. - rb_0.reset_problematic_links( + rb.reset_problematic_links( max_retries=10, allow_bad_links=args.allow_bad_links) if verbose: - rb_0.status() + rb.status() if (verbose): kcu.status() - rb_0.VTRX.get_version() + rb.VTRX.get_version() if (verbose): - _ = rb_0.VTRX.status() + _ = rb.VTRX.status() if args.power_up or args.reconfigure: print("Link inversions") - rb_0.DAQ_LPGBT.invert_links() - if rb_0.trigger: - rb_0.TRIG_LPGBT.invert_links(trigger=rb_0.trigger) + rb.DAQ_LPGBT.invert_links() + if rb.trigger: + rb.TRIG_LPGBT.invert_links(trigger=rb.trigger) #------------------------------------------------------------------------------- # Module Status @@ -262,7 +288,7 @@ if __name__ == '__main__': if args.configuration == 'emulator' or args.configuration == 'modulev0': print("Configuring ETROCs") for i in range(res['n_module']): - modules.append(Module(rb_0, i+1)) + modules.append(Module(rb, i+1)) print() print("Querying module status") @@ -280,7 +306,7 @@ if __name__ == '__main__': monitoring_threads.append(module_mon(modules[i])) if args.server: - app = create_app(rb_0, modules=modules) + app = create_app(rb, modules=modules) app.run(port=args.port, threaded=False) #------------------------------------------------------------------------------- @@ -289,13 +315,13 @@ if __name__ == '__main__': if args.adcs: print("\n\nReading GBT-SCA ADC values:") - rb_0.SCA.read_adcs(check=True, strict_limits=args.strict) + rb.SCA.read_adcs(check=True, strict_limits=args.strict) print("\n\nReading DAQ lpGBT ADC values:") - rb_0.DAQ_LPGBT.read_adcs(check=True, strict_limits=args.strict) + rb.DAQ_LPGBT.read_adcs(check=True, strict_limits=args.strict) # High level reading of temperatures - temp = rb_0.read_temp(verbose=True) + temp = rb.read_temp(verbose=True) #------------------------------------------------------------------------------- # I2C Test @@ -304,7 +330,7 @@ if __name__ == '__main__': if args.i2c_temp: for i in range(100): - print ( rb_0.DAQ_LPGBT.read_temp_i2c() ) + print ( rb.DAQ_LPGBT.read_temp_i2c() ) time.sleep(1) #------------------------------------------------------------------------------- @@ -316,24 +342,24 @@ if __name__ == '__main__': print("Writing and Reading I2C_ctrl register:") for n in range(10): wr = random.randint(0, 100) - rb_0.SCA.I2C_write_ctrl(channel=3, data=wr) - rd = rb_0.SCA.I2C_read_ctrl(channel=3) + rb.SCA.I2C_write_ctrl(channel=3, data=wr) + rd = rb.SCA.I2C_read_ctrl(channel=3) print("write: {} \t read: {}".format(wr, rd)) print("Testing multi-byte read:") - multi_out = rb_0.SCA.I2C_read_multi(channel=3, servant = 0x48, nbytes=2) + multi_out = rb.SCA.I2C_read_multi(channel=3, servant = 0x48, nbytes=2) print("servant: 0x48, channel: 3, nbytes: 2, output = {}".format(multi_out)) print("Testing multi-byte write:") write_value = [0x2, 25, (27&240)] print("servant: 0x48, channel: 3, nbytes: 2, data:{}".format(write_value)) - rb_0.SCA.I2C_write_multi(write_value, channel=3, servant=0x48) - read_value = rb_0.SCA.I2C_read_multi(channel=3, servant=0x48, nbytes = 2, reg=0x2) + rb.SCA.I2C_write_multi(write_value, channel=3, servant=0x48) + read_value = rb.SCA.I2C_read_multi(channel=3, servant=0x48, nbytes = 2, reg=0x2) if read_value == write_value[1:]: print ("write/read successful!") - print("read value = {}".format(rb_0.SCA.I2C_read_multi(channel=3, servant=0x48, nbytes = 2, reg=0x2))) + print("read value = {}".format(rb.SCA.I2C_read_multi(channel=3, servant=0x48, nbytes = 2, reg=0x2))) #------------------------------------------------------------------------------- # Pattern Checkers @@ -341,39 +367,39 @@ if __name__ == '__main__': if args.reset_pattern_checker: print ("\nResetting the pattern checker.") - rb_0.DAQ_LPGBT.set_uplink_group_data_source("normal") - rb_0.DAQ_LPGBT.set_downlink_data_src(args.reset_pattern_checker) + rb.DAQ_LPGBT.set_uplink_group_data_source("normal") + rb.DAQ_LPGBT.set_downlink_data_src(args.reset_pattern_checker) time.sleep(0.1) - rb_0.DAQ_LPGBT.reset_pattern_checkers() + rb.DAQ_LPGBT.reset_pattern_checkers() time.sleep(0.1) if args.run_pattern_checker: print ("\nReading the pattern checker counter. Waiting 1 sec.") time.sleep(1) - rb_0.DAQ_LPGBT.read_pattern_checkers() + rb.DAQ_LPGBT.read_pattern_checkers() #------------------------------------------------------------------------------- # Eyescan #------------------------------------------------------------------------------- if args.eyescan: - rb_0.DAQ_LPGBT.eyescan() + rb.DAQ_LPGBT.eyescan() all_tests_passed = True # FIXME this should be properly defined if all_tests_passed: - rb_0.DAQ_LPGBT.set_configured() + rb.DAQ_LPGBT.set_configured() #------------------------------------------------------------------------------- # Success LEDs #------------------------------------------------------------------------------- - if rb_0.DAQ_LPGBT.ver == 1: - rb_0.DAQ_LPGBT.set_gpio("LED_1", 1) # Set LED1 after tamalero finishes succesfully + if rb.DAQ_LPGBT.ver == 1: + rb.DAQ_LPGBT.set_gpio("LED_1", 1) # Set LED1 after tamalero finishes succesfully t_end = time.time() + 10 if args.power_up: print("RB configured successfully. Rhett is happy " + emojize(":dog_face:")) while time.time() < t_end: - rb_0.DAQ_LPGBT.set_gpio("LED_RHETT", 1) # Let Rhett LED blink for 10s + rb.DAQ_LPGBT.set_gpio("LED_RHETT", 1) # Let Rhett LED blink for 10s time.sleep(0.5) - rb_0.DAQ_LPGBT.set_gpio("LED_RHETT", 0) + rb.DAQ_LPGBT.set_gpio("LED_RHETT", 0) time.sleep(0.5) - rb_0.DAQ_LPGBT.set_gpio("LED_RHETT", 1) + rb.DAQ_LPGBT.set_gpio("LED_RHETT", 1)